Documentation
¶
Overview ¶
Package mylog provides structured logging utilities built on log/slog.
For production use, NewLogger creates a configured slog.Logger with text or JSON output, injectable host/PID, and level filtering. For tests, NewTestLogger returns a logger backed by TestHandler which captures structured entries for assertions via FindEntries and RequireEntry.
SlogWriter adapts a slog.Logger to an io.Writer for use with packages that expect traditional writers (e.g., net/http error logs).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewDiscardLogger ¶
NewDiscardLogger returns a logger whose output is discarded. This is useful for tests where log output should be suppressed.
func NewLogger ¶
func NewLogger(cfg LoggerConfig) *slog.Logger
NewLogger creates a configured *slog.Logger. Host and PID default to os.Hostname() and os.Getpid() when not provided via LoggerConfig.
func OrDefault ¶ added in v1.0.0
OrDefault returns lg unless it is nil, in which case the default logger is returned.
func ParseLevel ¶
ParseLevel maps common textual level names to slog.Level. The function is case-insensitive and ignores surrounding whitespace. If an unrecognized value is provided, slog.LevelInfo is returned.
Types ¶
type LoggedEntry ¶
type LoggedEntry struct {
Time time.Time `json:"time"`
Level slog.Level `json:"level"`
Msg string `json:"msg"`
Attrs map[string]any `json:"attrs"`
Source *slog.Source `json:"source"`
PC uintptr `json:"pc"`
}
LoggedEntry represents a captured structured log entry for assertions in tests. It contains the timestamp, level, message, attributes, source location, and performance details.
func FindEntries ¶
func FindEntries(th *TestHandler, pred func(LoggedEntry) bool) []LoggedEntry
FindEntries returns a copy of entries from the TestHandler that satisfy the provided predicate. The handler's internal slice is copied under lock to avoid races.
func RequireEntry ¶
func RequireEntry(t *testing.T, th *TestHandler, pred func(LoggedEntry) bool, timeout time.Duration) LoggedEntry
RequireEntry fails the test if a matching entry isn't observed within the given timeout. When a matching entry is found it is returned. If the timeout elapses, the test is failed and the captured entries are included in the failure message to aid debugging.
type LoggerConfig ¶
type LoggerConfig struct {
Version string
// If Out is nil, stdout is used.
Out io.Writer
Level slog.Level
JSON bool // true => JSON output, false => text
Source bool
// Host overrides os.Hostname() when set. Use this in tests or when
// the hostname should be injected rather than discovered at runtime.
Host string
// PID overrides os.Getpid() when set. Use this in tests or
// containerized environments where the OS PID is not meaningful.
PID int
}
LoggerConfig is a minimal, convenient set of options for creating a new slog.Logger.
Fields:
- Version: application or build version included with each log entry.
- Out: destination writer for log output. If nil, os.Stdout is used.
- Level: minimum logging level.
- JSON: when true, output is JSON; otherwise, human-readable text is used.
- Host: hostname included with each log entry. If empty, os.Hostname() is used.
- PID: process ID included with each log entry. If zero, os.Getpid() is used.
type SlogWriter ¶
type SlogWriter struct {
// CallerDepth controls the stack skip for runtime.Caller when
// attaching caller information. Zero disables caller attribution.
// The default (when created via NewSlogWriter) is 5 which matches
// the typical log.Logger -> Write -> slog pipeline depth.
CallerDepth int
// contains filtered or unexported fields
}
SlogWriter adapts a slog.Logger to an io.Writer. Each line written is logged as a separate entry at the configured level.
func NewSlogWriter ¶ added in v1.2.0
func NewSlogWriter(lg *slog.Logger, level slog.Level) *SlogWriter
NewSlogWriter creates a SlogWriter with sensible defaults.
type TestHandler ¶
type TestHandler struct {
Entries []LoggedEntry
T testingT
// contains filtered or unexported fields
}
TestHandler captures structured entries so tests can assert on logs. It is safe for concurrent use. When created via WithAttrs or WithGroup, the handler shares the root handler's Entries slice so FindEntries and RequireEntry work on the original handler returned by NewTestHandler.
func NewTestHandler ¶
func NewTestHandler(t testingT) *TestHandler
NewTestHandler creates an empty TestHandler. Optionally pass a testing.T to have the handler echo captured entries to the test log (via Logf).
func NewTestLogger ¶
func NewTestLogger(t testingT, level slog.Level) ( *slog.Logger, *TestHandler)
NewTestLogger returns a *slog.Logger that writes to a TestHandler and the handler itself for assertions. The returned logger has a default attribute ("test"="true") to make it easier to identify test logs.
func (*TestHandler) Enabled ¶
Enabled returns true for all levels. Filtering is expected to be handled by the caller or the logger's handler options.
func (*TestHandler) Handle ¶
Handle captures the provided record as a LoggedEntry and appends it to the root handler's Entries slice. If a testingT was provided, a human-readable line is also logged to the test output. When this handler was created via WithAttrs or WithGroup, entries are stored on the root handler so that FindEntries and RequireEntry work on the original handler.
func (*TestHandler) WithAttrs ¶
func (h *TestHandler) WithAttrs(attrs []slog.Attr) slog.Handler
WithAttrs returns a new handler with the provided attributes appended to subsequent log entries. The returned handler shares the parent's Entries slice so FindEntries and RequireEntry work on the original handler.