Documentation
¶
Overview ¶
Package logkit provides a minimal structured logging interface backed by zerolog. It exposes a Logger interface, optional file rotation via lumberjack, context propagation, and a slog.Handler adapter for use with the standard log/slog package.
Building a logger ¶
New builds a Logger from options. Defaults are InfoLevel and ConsoleOutput. Nil options are ignored. Use WithLevel, WithOutput, WithFileOptions, WithServiceName, and WithExitFunc to configure. New returns ErrEmptyFilename when Output is FileOutput or BothOutput and FileOptions.Filename is empty. Unknown Level values are mapped to InfoLevel.
Output ¶
ConsoleOutput writes to stdout in human-readable format (zerolog console writer). FileOutput uses lumberjack for rotation: set FileOptions with Filename required; MaxSize, MaxBackups, MaxAge use defaults (100 MB, 5 backups, 30 days) when zero. BothOutput writes to stdout and to the file. Child loggers from WithFields or WithError share the root's output and closer; Close on any of them closes the underlying file for all—call Close only on the root logger, typically via defer.
Levels and methods ¶
Logger provides Debug, Info, Warn, Error, and Fatal. Each accepts a message and optional variadic Fields; multiple Fields are merged (later keys override). DebugContext, InfoContext, and similar methods accept context.Context for future use (e.g. trace IDs); the context is not yet used. Fatal writes the event, calls Close, then calls the configured exit function (default os.Exit(1)); deferred functions in the caller are not run. For graceful shutdown use Error and an explicit exit path. Noop returns a logger that discards all output; Fatal on the noop logger does not exit (for tests).
Context ¶
IntoContext stores a logger in the request context; FromContext retrieves it, or Noop() if absent or ctx is nil. IntoContext panics if ctx is nil. Use in middleware to set the request-scoped logger and in handlers to retrieve it.
Field helpers ¶
TraceID, RequestID, UserID, Error, Duration, DurationMs, and Component return Fields with conventional keys (trace_id, request_id, user_id, error, duration, component). Use them for consistent structured logs. Duration formats as a string (e.g. "1.5s"); DurationMs formats as int64 milliseconds for ELK/Loki/ClickHouse. Error returns nil when err is nil (no field added).
slog integration ¶
SlogHandler returns a slog.Handler that forwards log/slog records to a Logger. Use slog.New(SlogHandler(l)) to pass a logkit logger to code that expects slog. WithGroup and WithAttrs are supported.
Conventions ¶
Do not log secrets (passwords, tokens, API keys) or unredacted PII in Fields. Control characters (including \r, \n, NUL, U+2028, U+2029) in messages and in field keys and values are replaced with space to reduce log injection.
Errors ¶
ErrEmptyFilename is the only error returned by New; use errors.Is to detect it.
Thread safety ¶
Logger methods are safe for concurrent use. Close is safe to call from multiple goroutines; only the first call has effect and closes the underlying output for all loggers sharing it.
Testing ¶
Use Noop() when a Logger is required but output should be discarded (e.g. in tests or when logging is disabled). For asserting log calls in unit tests, use the mock package: mock.NewMockLogger(t) returns a MockLogger that implements Logger and records expectations; call EXPECT() to set up and verify calls.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrEmptyFilename is returned by New when Output is FileOutput or BothOutput but FileOptions.Filename is empty. // Use errors.Is(err, logkit.ErrEmptyFilename) to detect it and prompt the caller to set WithFileOptions with a non-empty Filename. ErrEmptyFilename = errors.New("logkit: filename required for file output") )
Functions ¶
func IntoContext ¶
IntoContext stores the logger in ctx so it can be retrieved later with FromContext. Use in middleware to set a request-scoped logger; handlers then call FromContext(ctx) to get it. Panics if ctx is nil. The same ctx should be passed along the request chain.
func SlogHandler ¶
SlogHandler returns a slog.Handler that forwards log/slog records to the given Logger. Use slog.New(SlogHandler(l)) so code that expects slog.Logger or slog.Handler can use a logkit Logger. WithGroup and WithAttrs are supported; group names are prefixed to attribute keys (e.g. group "http", attr "method" → "http.method"). The adapter does not filter by level; Enabled always returns true—level filtering is done by the Logger.
Types ¶
type Fields ¶
Fields is a key-value map attached to a log event. Keys and values are sanitized: control characters (including \r, \n, NUL, U+2028, U+2029) are replaced with space to reduce log injection. Multiple Fields passed to one call are merged; later keys override earlier ones. Shallow-copied when passed to WithFields or log methods; do not mutate the map after passing.
func Component ¶
Component returns Fields with the component key. Use to tag events by handler name, service layer, or module so logs can be filtered by component in centralized logging.
func Duration ¶
Duration returns Fields with the duration key formatted as a string (e.g. "1.5s"). Prefer DurationMs when logs are ingested by structured backends (ELK, Loki, ClickHouse) for querying and aggregation.
func DurationMs ¶
DurationMs returns Fields with the duration key as int64 milliseconds. Use for structured backends (ELK, Loki, ClickHouse) so duration can be queried and aggregated; for human-readable logs use Duration.
func Error ¶
Error returns Fields with the error key for structured error logging. Returns nil if err is nil— in that case no field is added, so callers can pass the result directly to log methods.
func RequestID ¶
RequestID returns Fields with the request_id key. Use the same ID as in HTTP headers (e.g. X-Request-ID) so logs can be correlated with a single request across services.
type FileOptions ¶
type FileOptions struct {
Filename string // Log file path (required for FileOutput or BothOutput).
MaxSize int // Max megabytes per file before rotation; zero uses default (100).
MaxBackups int // Max number of old files to keep; zero uses default (5).
MaxAge int // Max days to keep old files; zero uses default (30).
Compress bool // Whether to gzip rotated files.
}
FileOptions configures file output (lumberjack). Filename is required when Output is FileOutput or BothOutput. Zero MaxSize, MaxBackups, and MaxAge use internal defaults (100 MB, 5 backups, 30 days); set them for explicit rotation.
type Level ¶
type Level int
Level is the minimum level at which log events are emitted. Events below this level are dropped. Pass to WithLevel when building a logger; unknown values are treated as InfoLevel.
type Logger ¶
type Logger interface {
Debug(msg string, fields ...Fields)
Info(msg string, fields ...Fields)
Warn(msg string, fields ...Fields)
Error(msg string, fields ...Fields)
Fatal(msg string, fields ...Fields)
DebugContext(ctx context.Context, msg string, fields ...Fields)
InfoContext(ctx context.Context, msg string, fields ...Fields)
WarnContext(ctx context.Context, msg string, fields ...Fields)
ErrorContext(ctx context.Context, msg string, fields ...Fields)
FatalContext(ctx context.Context, msg string, fields ...Fields)
WithFields(fields Fields) Logger
WithError(err error) Logger
Close() error
}
Logger is the interface for structured logging. Implementations are safe for concurrent use. Close releases underlying output (e.g. file); child loggers from WithFields or WithError share the same output— closing any of them closes it for all. Call Close only once, typically on the root logger via defer.
func FromContext ¶
FromContext returns the logger from ctx (set by IntoContext). Returns Noop() if ctx is nil or if no logger was stored—so callers can always use the result without a nil check.
func New ¶
New builds a Logger from the given options. Defaults are InfoLevel and ConsoleOutput; nil options are ignored. Use WithLevel, WithOutput, WithFileOptions, WithServiceName, and WithExitFunc to configure. When Output is FileOutput or BothOutput, FileOptions.Filename must be set; otherwise New returns ErrEmptyFilename. Unknown Level values are treated as InfoLevel. Call Close on the returned logger when done (e.g. defer) to release file output.
type Option ¶
type Option func(*Options)
Option configures a logger when passed to New. Nil options are ignored; pass WithLevel, WithOutput, etc.
func WithExitFunc ¶
WithExitFunc sets the function called by Fatal after logging and Close. If nil, Fatal calls os.Exit(1). Use in tests to avoid terminating the process, or for graceful shutdown (e.g. run exit in a deferred path after flushing).
func WithFileOptions ¶
func WithFileOptions(fo FileOptions) Option
WithFileOptions sets file output options. Required when Output is FileOutput or BothOutput; Filename must be non-empty or New returns ErrEmptyFilename.
func WithLevel ¶
WithLevel sets the minimum log level. Events below this level are not emitted; unknown values are treated as InfoLevel.
func WithOutput ¶
func WithOutput(output OutputType) Option
WithOutput sets the output destination. For FileOutput or BothOutput, also set FileOptions via WithFileOptions (Filename required).
func WithServiceName ¶
WithServiceName sets the service name; adds a "service" field to every log event. Use for multi-service deployments so logs can be filtered by service in centralized logging.
type Options ¶
type Options struct {
Level Level // Minimum log level.
Output OutputType // Where to write (console, file, or both).
FileOptions FileOptions // Required when Output is FileOutput or BothOutput.
ServiceName string // Added as "service" field to every event when non-empty.
ExitFunc func(int) // Called by Fatal after logging and Close; nil uses os.Exit.
}
Options holds configuration for New. Zero value for Level is treated as InfoLevel; zero Output as ConsoleOutput. When Output is FileOutput or BothOutput, FileOptions.Filename must be set or New returns ErrEmptyFilename.
type OutputType ¶
type OutputType int
OutputType selects where log output is written (console, file, or both).
const ( ConsoleOutput OutputType = iota FileOutput BothOutput )
Output destinations.