nanny

package module
v1.51.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 14, 2024 License: MIT Imports: 14 Imported by: 0

README

nanny

GoDoc

Records a sliding window of slog events with all attribute values for remote inspection through HTTP.

usage

	import "github.com/emicklei/nanny"

	...

	nanny.SetupDefault()
	slog.Debug("debug", "hello", "world")

or by composing the setup yourself:

	r := nanny.NewRecorder()

	// recorder captures debug and forwards to existing handler
	l := slog.New(nanny.NewLogHandler(r, slog.Default().Handler(), slog.LevelDebug)) // or nanny.LevelTrace
	
	// replace the default logger
	slog.SetDefault(l)

	// serve the events
	http.Handle("/nanny", nanny.NewBrowser(rec))

Then after starting your HTTP service, you can access /nanny to see and explore your log events.

event groups

Events can be grouped e.g. by function name or for the processing of a specific HTTP request.

	l := slog.Default().With("trace-id", "some-correlation-value")
	l.Debug("var", "key", "value")

Here trace-id is the default event group marker. You can change the group keys to whatever you want using the RecorderOptions GroupMarkers.

sample record served as JSON

Access the events via /nanny?do=events.

  {
    "t": "2023-11-08T18:15:14.349402+01:00",
    "l": "DEBUG",
    "g" : "some group", 
    "m": "checking...", 
    "a": {
      "bike": {
		"Brand": "Trek",
      	"Model": "Emonda",
      	"Year": "2017"
	  }
    }
field comment
t timestamp
l log level
g group
m message
a attributes

how it works

Your program calls slog.Debug which creates an slog.Record which is sent to the default slog.Handler. If the default handler is a nanny.SlogHandler then the record is first sent to a nanny.Recorder. The nanny.Recorder keeps the last N record copies in memory and adds grouping information to them. Records from the nanny.Recorder are served by the nanny.Browser using an HTTP endpoint.

A nanny.SlogHandler wraps (decorates) another slog.Handler, the fallback handler. Both the nanny.SlogHandler and the fallback handler respond to a certain slog.Level. If the nanny.SlogHandler is enabled for the log level of the record then it is sent to fallback handler. If the fallback handler is enabled for the log level of the record then it is sent to the fallback output. So if the fallback handler is configured for INFO only then the TRACE and DEBUG records are kept by the nanny.Recorder only ; they are not logged to the output of the fallback handler.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var LevelTrace = slog.Level(-8)
View Source
var Version = "v1.51.3"

because of a typo, versions have a gap between 1.15.3 and 1.50.0

Functions

func NewRecorder

func NewRecorder(opts ...RecorderOptions) *recorder

func SetupDefault

func SetupDefault()

SetupDefault wraps the default log handler with a handler that records events. Logging all events on error detection is true. Maxium number of event groups in memory is 100. Installs the browser (page=100) on the default serve mux with path /nanny

func Trace

func Trace(sl *slog.Logger, msg string, args ...any)

func TraceContext

func TraceContext(ctx context.Context, sl *slog.Logger, msg string, args ...any)

Types

type BasicAuthHandler

type BasicAuthHandler struct {
	Handler  http.Handler
	Username string
	Password string
}

BasicAuthHandler is a http.Handler that requires basic authentication. 95% Suggested by Google Duet

func NewBasicAuthHandler

func NewBasicAuthHandler(handler http.Handler, username, password string) *BasicAuthHandler

func (*BasicAuthHandler) ServeHTTP

func (h *BasicAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

type Browser

type Browser struct {
	// contains filtered or unexported fields
}

func NewBrowser

func NewBrowser(rec *recorder, opts ...BrowserOptions) *Browser

func (*Browser) ServeHTTP

func (b *Browser) ServeHTTP(w http.ResponseWriter, r *http.Request)

type BrowserOptions added in v1.15.0

type BrowserOptions struct {
	PageSize  int
	PageTitle string
}

type Event

type Event struct {
	Time    time.Time      `json:"t" `
	Level   slog.Level     `json:"l" `
	Message string         `json:"m" `
	Group   string         `json:"g" ` // group name of events
	Attrs   map[string]any `json:"a" `
	// contains filtered or unexported fields
}

type RecordCondition added in v0.6.0

type RecordCondition struct {
	Name    string
	Enabled bool
	Path    string
	Value   string
	// contains filtered or unexported fields
}

func NewCondition added in v0.6.0

func NewCondition(name string, enabled bool, path string, value string) RecordCondition

func (RecordCondition) Matches added in v0.6.0

func (r RecordCondition) Matches(ev *Event) bool

Matches returns true if the event matches the specification of this condition.

func (RecordCondition) String added in v0.6.0

func (c RecordCondition) String() string

type RecorderOptions added in v1.15.0

type RecorderOptions struct {
	MaxEventsMemoryBytes int64    // zero means no limit
	MaxEventGroups       int      // zero means no limit
	MaxEvents            int      // zero means no limit
	GroupMarkers         []string // one or more attribute names for grouping events
	LogEventGroupOnError bool     // if an Error event is recorded then all leading debug and trace events in the same group are logger first
}

RecorderOptions holds all configuration options for keeping a window of events. The maxima are handled in order of precedence: MaxEventsMemoryBytes->MaxEventGroups->MaxEvents.

type SlogHandler

type SlogHandler struct {
	// contains filtered or unexported fields
}

func NewLogHandler

func NewLogHandler(recorder *recorder, passThroughHandler slog.Handler, level slog.Level) *SlogHandler

func (*SlogHandler) Enabled

func (h *SlogHandler) Enabled(ctx context.Context, level slog.Level) bool

Enabled implements slog.Handler.

func (*SlogHandler) Handle

func (h *SlogHandler) Handle(ctx context.Context, rec slog.Record) error

Handle implements slog.Handler.

func (*SlogHandler) WithAttrs

func (h *SlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs implements slog.Handler.

func (*SlogHandler) WithGroup

func (h *SlogHandler) WithGroup(name string) slog.Handler

WithGroup implements slog.Handler.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL