Documentation
¶
Overview ¶
Package logging provides structured logging for gokit applications using zerolog.
It supports multiple output formats (JSON, console), log level configuration, and component-scoped loggers with structured fields.
Configuration ¶
logging: level: "info" format: "json"
Usage ¶
log := logging.NewDefault("my-service")
log.Info("operation completed", logging.Fields("key", "value"))
// Component-scoped logger derived from a base logger.
dbLog := log.WithComponent("database")
dbLog.Debug("query executed")
Context and filtering ¶
ContextWithTraceID and its siblings carry trace, span, request, user, and correlation IDs on a context; ComponentSpan and RequestSpan derive loggers enriched from that context. BuildDirectives and ParseDirectives convert between a base level plus per-module overrides and the compact directive string used to configure level filtering from the environment.
Index ¶
- Constants
- func BuildDirectives(baseLevel string, moduleLevels map[string]string) string
- func ContextWithCorrelationID(ctx context.Context, id string) context.Context
- func ContextWithRequestID(ctx context.Context, id string) context.Context
- func ContextWithSpanID(ctx context.Context, id string) context.Context
- func ContextWithTraceID(ctx context.Context, id string) context.Context
- func ContextWithUserID(ctx context.Context, id string) context.Context
- func Debug(msg string, fields ...map[string]any)
- func DebugCtx(ctx context.Context, msg string, fields ...map[string]any)
- func DurationFields(op string, d time.Duration) map[string]any
- func Error(msg string, fields ...map[string]any)
- func ErrorCtx(ctx context.Context, msg string, fields ...map[string]any)
- func ErrorFields(op string, err error) map[string]any
- func Fatal(msg string, fields ...map[string]any)
- func FatalCtx(ctx context.Context, msg string, fields ...map[string]any)
- func Fields(kvs ...any) map[string]any
- func GetLoggerZ() zerolog.Logger
- func Info(msg string, fields ...map[string]any)
- func InfoCtx(ctx context.Context, msg string, fields ...map[string]any)
- func MergeWithDuration(fields map[string]any, d time.Duration) map[string]any
- func MergeWithError(fields map[string]any, err error) map[string]any
- func NewSampler(cfg SamplingConfig) zerolog.Sampler
- func ParseDirectives(directives string) (baseLevel string, moduleLevels map[string]string)
- func ServiceFields(service, environment, version string) map[string]any
- func Warn(msg string, fields ...map[string]any)
- func WarnCtx(ctx context.Context, msg string, fields ...map[string]any)
- type ClientComponent
- type ComponentRegistry
- func (r *ComponentRegistry) APIPrefix() string
- func (r *ComponentRegistry) Clients() []ClientComponent
- func (r *ComponentRegistry) Consumers() []ConsumerComponent
- func (r *ComponentRegistry) Handlers() []HandlerComponent
- func (r *ComponentRegistry) Infrastructure() []InfraComponent
- func (r *ComponentRegistry) RegisterClient(name, target, status string)
- func (r *ComponentRegistry) RegisterConsumer(c ConsumerComponent)
- func (r *ComponentRegistry) RegisterHandler(method, path, handler string)
- func (r *ComponentRegistry) RegisterInfrastructure(name, componentType, status, details string)
- func (r *ComponentRegistry) RegisterRepository(name, store, status string)
- func (r *ComponentRegistry) RegisterService(name, status string, dependencies []string)
- func (r *ComponentRegistry) Repositories() []RepositoryComponent
- func (r *ComponentRegistry) Services() []ServiceComponent
- func (r *ComponentRegistry) SetAPIPrefix(prefix string)
- func (r *ComponentRegistry) SetHandlers(handlers []HandlerComponent)
- func (r *ComponentRegistry) StartTime() time.Time
- type Config
- type ConsumerComponent
- type DefaultMasker
- type HandlerComponent
- type InfraComponent
- type Logger
- func ComponentSpan(ctx context.Context, name string) *Logger
- func Default() *Logger
- func New(cfg *Config, serviceName string) *Logger
- func NewDefault(serviceName string) *Logger
- func NewFromEnv(serviceName string) *Logger
- func RequestSpan(ctx context.Context, method, path, requestID string) *Logger
- func WithComponent(name string) *Logger
- func WithContext(ctx context.Context) *Logger
- func (l *Logger) Close() error
- func (l *Logger) ComponentSpan(ctx context.Context, name string) *Logger
- func (l *Logger) Debug(msg string, fields ...map[string]any)
- func (l *Logger) DebugCtx(ctx context.Context, msg string, fields ...map[string]any)
- func (l *Logger) Error(msg string, fields ...map[string]any)
- func (l *Logger) ErrorCtx(ctx context.Context, msg string, fields ...map[string]any)
- func (l *Logger) Fatal(msg string, fields ...map[string]any)
- func (l *Logger) FatalCtx(ctx context.Context, msg string, fields ...map[string]any)
- func (l *Logger) GetLogger() zerolog.Logger
- func (l *Logger) Info(msg string, fields ...map[string]any)
- func (l *Logger) InfoCtx(ctx context.Context, msg string, fields ...map[string]any)
- func (l *Logger) RequestSpan(ctx context.Context, method, path, requestID string) *Logger
- func (l *Logger) Warn(msg string, fields ...map[string]any)
- func (l *Logger) WarnCtx(ctx context.Context, msg string, fields ...map[string]any)
- func (l *Logger) WithComponent(name string) *Logger
- func (l *Logger) WithContext(ctx context.Context) *Logger
- func (l *Logger) WithError(err error) *Logger
- func (l *Logger) WithFields(fields map[string]any) *Logger
- func (l *Logger) WithMasker(m Masker) *Logger
- func (l *Logger) WithOTLP(provider *OTLPProvider) *Logger
- type Masker
- type MaskingConfig
- type ModuleLevelManager
- type OTLPConfig
- type OTLPProvider
- type OTLPProviderConfig
- type Registry
- type RepositoryComponent
- type SamplingConfig
- type ServiceComponent
Examples ¶
Constants ¶
const ( FieldComponent = "component" FieldTraceID = "trace_id" FieldSpanID = "span_id" FieldRequestID = "request_id" FieldCorrelationID = "correlation_id" FieldUserID = "user_id" FieldSessionID = "session_id" FieldOperation = "operation" FieldStatus = "status" FieldError = "error" FieldDuration = "duration_ms" FieldPlatform = "platform" FieldPhase = "phase" FieldContainerID = "container_id" FieldEmail = "email" FieldHTTPMethod = "http.method" FieldHTTPPath = "http.path" // Unified schema fields — consistent across gokit, rskit, and pykit. FieldService = "service" FieldEnvironment = "environment" FieldTimestamp = "timestamp" FieldLevel = "level" FieldMessage = "message" FieldVersion = "version" )
Standard field key constants for structured logging.
const ( FormatPretty = "pretty" BooleanTrue = "true" )
Variables ¶
This section is empty.
Functions ¶
func BuildDirectives ¶
BuildDirectives renders a base level and a set of per-module overrides into a single comma-separated directive string, e.g. "info,sqlx=warn,hyper=error". The base level comes first and module directives follow in sorted order, so the output is deterministic and stable across runs. This mirrors the RUST_LOG / env-filter grammar used by the sibling kits, giving gokit a portable interchange form for per-module log configuration. When there are no module overrides the base level is returned alone.
func ContextWithCorrelationID ¶
ContextWithCorrelationID returns a context carrying the correlation ID, which (*Logger).WithContext folds into the correlation_id field.
func ContextWithRequestID ¶
ContextWithRequestID returns a context carrying the request ID, which (*Logger).WithContext folds into the request_id field.
func ContextWithSpanID ¶
ContextWithSpanID returns a context carrying the span ID, which (*Logger).WithContext folds into the span_id field.
func ContextWithTraceID ¶
ContextWithTraceID returns a context carrying the trace ID, which (*Logger).WithContext folds into the trace_id field.
func ContextWithUserID ¶
ContextWithUserID returns a context carrying the user ID, which (*Logger).WithContext folds into the user_id field.
func DurationFields ¶
DurationFields creates fields for a timed operation.
func ErrorFields ¶
ErrorFields creates fields for an operation that failed.
Example ¶
package main
import (
"fmt"
"github.com/kbukum/gokit/logging"
)
func main() {
f := logging.ErrorFields("save_user", fmt.Errorf("db offline"))
fmt.Println(f["operation"], f["error"])
}
Output: save_user db offline
func Fields ¶
Fields builds a map[string]any from alternating key-value pairs.
logger.Info("done", logger.Fields("op", "save", "id", 42))
Example ¶
package main
import (
"fmt"
"github.com/kbukum/gokit/logging"
)
func main() {
f := logging.Fields("user_id", 42, "tenant", "acme")
fmt.Println(f["user_id"], f["tenant"])
}
Output: 42 acme
func GetLoggerZ ¶
GetLoggerZ returns the underlying zerolog.Logger from the default logger.
func MergeWithDuration ¶
MergeWithDuration adds a duration field to an existing map.
func MergeWithError ¶
MergeWithError adds an error field to an existing map.
func NewSampler ¶
func NewSampler(cfg SamplingConfig) zerolog.Sampler
NewSampler creates a zerolog sampler from SamplingConfig. It uses a BurstSampler that allows an initial burst of messages per period, then falls back to sampling every Nth message thereafter.
func ParseDirectives ¶
ParseDirectives is the inverse of BuildDirectives. It splits a directive string into the base level and the per-module overrides, so a value carried in an environment variable such as LOG_LEVEL="info,sqlx=warn" can be turned back into structured configuration. A bare "module=level" token with no leading base level yields an empty base level and that override; empty tokens are ignored.
func ServiceFields ¶
ServiceFields creates the standard service identification fields for the unified log schema (consistent across gokit, rskit, and pykit).
Types ¶
type ClientComponent ¶
ClientComponent represents an external client (gRPC, HTTP, etc.).
type ComponentRegistry ¶
type ComponentRegistry struct {
// contains filtered or unexported fields
}
ComponentRegistry tracks components during bootstrap for summary display.
func NewComponentRegistry ¶
func NewComponentRegistry() *ComponentRegistry
NewComponentRegistry creates a new component registry.
func (*ComponentRegistry) APIPrefix ¶
func (r *ComponentRegistry) APIPrefix() string
APIPrefix returns the configured API prefix.
func (*ComponentRegistry) Clients ¶
func (r *ComponentRegistry) Clients() []ClientComponent
Clients returns all registered client components.
func (*ComponentRegistry) Consumers ¶
func (r *ComponentRegistry) Consumers() []ConsumerComponent
Consumers returns all registered consumer components.
func (*ComponentRegistry) Handlers ¶
func (r *ComponentRegistry) Handlers() []HandlerComponent
Handlers returns all registered handler components.
func (*ComponentRegistry) Infrastructure ¶
func (r *ComponentRegistry) Infrastructure() []InfraComponent
Infrastructure returns all registered infrastructure components.
func (*ComponentRegistry) RegisterClient ¶
func (r *ComponentRegistry) RegisterClient(name, target, status string)
RegisterClient registers an external client.
func (*ComponentRegistry) RegisterConsumer ¶
func (r *ComponentRegistry) RegisterConsumer(c ConsumerComponent)
RegisterConsumer registers a message consumer.
func (*ComponentRegistry) RegisterHandler ¶
func (r *ComponentRegistry) RegisterHandler(method, path, handler string)
RegisterHandler registers an HTTP handler.
func (*ComponentRegistry) RegisterInfrastructure ¶
func (r *ComponentRegistry) RegisterInfrastructure(name, componentType, status, details string)
RegisterInfrastructure registers an infrastructure component.
func (*ComponentRegistry) RegisterRepository ¶
func (r *ComponentRegistry) RegisterRepository(name, store, status string)
RegisterRepository registers a repository component.
func (*ComponentRegistry) RegisterService ¶
func (r *ComponentRegistry) RegisterService(name, status string, dependencies []string)
RegisterService registers a service component.
func (*ComponentRegistry) Repositories ¶
func (r *ComponentRegistry) Repositories() []RepositoryComponent
Repositories returns all registered repository components.
func (*ComponentRegistry) Services ¶
func (r *ComponentRegistry) Services() []ServiceComponent
Services returns all registered service components.
func (*ComponentRegistry) SetAPIPrefix ¶
func (r *ComponentRegistry) SetAPIPrefix(prefix string)
SetAPIPrefix sets the API prefix (for example "/api/v1") for route grouping.
func (*ComponentRegistry) SetHandlers ¶
func (r *ComponentRegistry) SetHandlers(handlers []HandlerComponent)
SetHandlers replaces the handler list (useful when collecting routes dynamically).
func (*ComponentRegistry) StartTime ¶
func (r *ComponentRegistry) StartTime() time.Time
StartTime returns the registry creation time (bootstrap start).
type Config ¶
type Config struct {
Level string `yaml:"level" mapstructure:"level"`
Format string `yaml:"format" mapstructure:"format"`
Output string `yaml:"output" mapstructure:"output"`
NoColor bool `yaml:"no_color" mapstructure:"no_color"`
Timestamp bool `yaml:"timestamp" mapstructure:"timestamp"`
Caller bool `yaml:"caller" mapstructure:"caller"`
Stacktrace bool `yaml:"stacktrace" mapstructure:"stacktrace"`
MaxSize int `yaml:"max_size" mapstructure:"max_size"` // megabytes
MaxBackups int `yaml:"max_backups" mapstructure:"max_backups"` // number of backups
MaxAge int `yaml:"max_age" mapstructure:"max_age"` // days
Compress bool `yaml:"compress" mapstructure:"compress"`
LocalTime bool `yaml:"local_time" mapstructure:"local_time"`
ServiceName string `yaml:"service_name" mapstructure:"service_name"` // used as tag in log output
Environment string `yaml:"environment" mapstructure:"environment"` // deployment environment (e.g. development, staging, production)
Version string `yaml:"version" mapstructure:"version"` // service version (e.g. 1.0.0)
Masking MaskingConfig `yaml:"masking" mapstructure:"masking"`
Sampling SamplingConfig `yaml:"sampling" mapstructure:"sampling"`
ModuleLevels map[string]string `yaml:"module_levels" mapstructure:"module_levels"` // e.g., {"database": "debug", "kafka": "warn"}
OTLP OTLPConfig `yaml:"otlp" mapstructure:"otlp"`
}
Config contains logging configuration.
func (*Config) ApplyDefaults ¶
func (c *Config) ApplyDefaults()
ApplyDefaults applies default values to logging configuration.
type ConsumerComponent ¶
type ConsumerComponent struct {
Name string
Group string
Topic string
Partitions int
Status string
}
ConsumerComponent represents a message consumer (e.g. Kafka).
type DefaultMasker ¶
type DefaultMasker struct {
// contains filtered or unexported fields
}
DefaultMasker provides field-name and value-pattern based sensitive data masking. It is safe for concurrent use after construction (all fields are read-only).
func NewDefaultMasker ¶
func NewDefaultMasker(cfg MaskingConfig) *DefaultMasker
NewDefaultMasker creates a DefaultMasker from the given MaskingConfig. All regexps are compiled at construction time via regexp.MustCompile.
func (*DefaultMasker) MaskFields ¶
func (m *DefaultMasker) MaskFields(fields map[string]any) map[string]any
MaskFields masks all values in a map, returning a new map. String values are masked directly. Non-string values are converted to a string representation, checked for sensitive patterns, and replaced with the masked string if a pattern matches.
func (*DefaultMasker) MaskValue ¶
func (m *DefaultMasker) MaskValue(key, value string) string
MaskValue masks a single value based on its field key and content. If the key matches a sensitive field name, the full replacement is returned. Otherwise each value pattern is tested and the first match wins.
type HandlerComponent ¶
HandlerComponent represents an HTTP handler/route.
type InfraComponent ¶
type InfraComponent struct {
Name string
Type string // "database", "kafka", "redis", "server"
Status string // "active", "inactive", "error"
Details string
}
InfraComponent represents an infrastructure dependency (database, cache, broker, etc.).
type Logger ¶
type Logger struct {
// contains filtered or unexported fields
}
Logger wraps zerolog.Logger with additional context.
func ComponentSpan ¶
ComponentSpan returns a component-tagged logger from the default logger.
func Default ¶
func Default() *Logger
Default returns the process default logger, constructing it on first use. Prefer injecting an explicit *Logger; use Default only for incidental logging where threading a logger through the call site adds no value.
func NewDefault ¶
NewDefault creates a logger with default configuration.
func NewFromEnv ¶
NewFromEnv creates a logger configured from environment variables.
func RequestSpan ¶
RequestSpan returns a request-enriched logger from the default logger.
func WithComponent ¶
WithComponent returns a component-tagged logger from the default logger.
func WithContext ¶
WithContext returns a context-enriched logger from the default logger.
func (*Logger) ComponentSpan ¶
ComponentSpan returns a logger tagged with the component name and enriched with any identifiers already present in ctx — the gokit equivalent of rskit-logging's component_span.
func (*Logger) Debug ¶
Debug logs a debug message.
For request- or operation-scoped logging that should propagate cancellation and trace correlation to OTLP, prefer DebugCtx.
func (*Logger) Fatal ¶
Fatal logs a fatal message and exits. Prefer FatalCtx when a context is in scope.
func (*Logger) FatalCtx ¶
FatalCtx logs a fatal message and exits, propagating ctx to the OTLP exporter.
func (*Logger) RequestSpan ¶
RequestSpan returns a logger enriched with HTTP request metadata and any identifiers already present in ctx — the gokit equivalent of rskit-logging's request_span.
func (*Logger) WithComponent ¶
WithComponent returns a logger tagged with a component name. If a per-module log level override exists for the component, it is applied.
func (*Logger) WithContext ¶
WithContext returns a logger enriched with trace/span/request IDs from context.
func (*Logger) WithFields ¶
WithFields returns a logger with additional fields.
func (*Logger) WithMasker ¶
WithMasker returns a new Logger with the given Masker applied.
func (*Logger) WithOTLP ¶
func (l *Logger) WithOTLP(provider *OTLPProvider) *Logger
WithOTLP returns a new Logger with the given OTLPProvider attached.
type MaskingConfig ¶
type MaskingConfig struct {
Enabled bool `yaml:"enabled" mapstructure:"enabled"`
FieldNames []string `yaml:"field_names" mapstructure:"field_names"` // Additional field names to mask
ValuePatterns []string `yaml:"value_patterns" mapstructure:"value_patterns"` // Additional regex patterns
Replacement string `yaml:"replacement" mapstructure:"replacement"`
PreserveLast int `yaml:"preserve_last" mapstructure:"preserve_last"` // Preserve last N chars for partial masking
}
MaskingConfig contains configuration for sensitive data masking.
type ModuleLevelManager ¶
type ModuleLevelManager struct {
// contains filtered or unexported fields
}
ModuleLevelManager manages per-module log level overrides. It is safe for concurrent use.
func NewModuleLevelManager ¶
func NewModuleLevelManager(levels map[string]string) *ModuleLevelManager
NewModuleLevelManager creates a manager from a map of module names to level strings. Unrecognized level strings are silently ignored.
func (*ModuleLevelManager) Level ¶
func (m *ModuleLevelManager) Level(module string) (zerolog.Level, bool)
Level returns the override level for a module. The second return value is false if no override exists.
func (*ModuleLevelManager) SetLevel ¶
func (m *ModuleLevelManager) SetLevel(module, level string)
SetLevel dynamically sets a module's log level. An unrecognized level string is silently ignored.
type OTLPConfig ¶
type OTLPConfig struct {
Enabled bool `yaml:"enabled" mapstructure:"enabled"` // Default: false
Endpoint string `yaml:"endpoint" mapstructure:"endpoint"` // e.g., "localhost:4317"
Protocol string `yaml:"protocol" mapstructure:"protocol"` // "grpc" or "http" (default: "grpc")
Insecure bool `yaml:"insecure" mapstructure:"insecure"` // Skip TLS (for dev)
Headers map[string]string `yaml:"headers" mapstructure:"headers"` // Auth headers
}
OTLPConfig configures the OpenTelemetry OTLP log export bridge.
type OTLPProvider ¶
type OTLPProvider struct {
// contains filtered or unexported fields
}
OTLPProvider manages the OpenTelemetry LoggerProvider for OTLP export.
func NewOTLPProvider ¶
func NewOTLPProvider(cfg OTLPProviderConfig) (*OTLPProvider, error)
NewOTLPProvider creates and starts an OTLP log provider.
func (*OTLPProvider) EmitLog ¶
EmitLog sends a log record to the OTLP collector.
ctx is propagated to the OTel exporter so that cancellation, deadlines, and trace correlation flow through to telemetry. Pass context.Background() only for emit sites where no request-scoped context is available (e.g. startup banners, signal handlers).
type OTLPProviderConfig ¶
type OTLPProviderConfig struct {
Exporter OTLPConfig
ServiceName string
Environment string
Version string
}
OTLPProviderConfig configures an OTLP log provider and its service resource attributes.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is an injected collection of component-scoped loggers derived from a base logger. It replaces the previous package-global logger registry: callers construct a Registry via NewRegistry and pass it explicitly, so there is no mutable package-level state shared across unrelated components.
func NewRegistry ¶
NewRegistry creates a Registry backed by base. When base is nil the process default logger is used so the registry is always usable.
type RepositoryComponent ¶
type RepositoryComponent struct {
Name string
Store string // "PostgreSQL", "Redis", etc.
Status string
}
RepositoryComponent represents a data-access repository.
type SamplingConfig ¶
type SamplingConfig struct {
Enabled bool `yaml:"enabled" mapstructure:"enabled"` // Default: false
InitialRate int `yaml:"initial_rate" mapstructure:"initial_rate"` // Log first N per second per level
ThereafterRate int `yaml:"thereafter_rate" mapstructure:"thereafter_rate"` // Then log every Nth
}
SamplingConfig controls rate-based log sampling to reduce volume in high-throughput scenarios.
type ServiceComponent ¶
type ServiceComponent struct {
Name string
Status string // "lazy", "initialized", "active"
Dependencies []string
}
ServiceComponent represents a business-logic service.