Documentation
¶
Overview ¶
Package golog provides a simple, structured logging library for Go applications. It supports JSON output, context-based logging, and field enrichment.
Architecture ¶
Golog uses three main concepts:
- Writers: Implement LogWriter to control where and how logs are formatted (e.g., JSON, human-readable).
- Scopes: LogScope holds fields and context; create scopes with With, WithFields, WithContext, WithError, or WithPairs.
- Enrichers: Implement Enricher to add fields to log entries; register globally with RegisterEnricher.
Features ¶
- Structured JSON or text logging
- Context support for request-scoped fields
- Field enrichment via Enricher
- Multiple log levels (Debug, Info, Error)
- Flushable output
Thread Safety ¶
LogScope is not safe for concurrent use; create a new scope per goroutine or operation. LogWriter implementations (NewDefaultWriter, NewJSONWriter) are thread-safe.
Example ¶
writer := golog.NewJSONWriter(os.Stdout)
golog.SetWriter(writer)
golog.Info("Hello, world!")
golog.With("user_id", 123).Info("User logged in")
golog.WithError(err).Error("Operation failed")
golog.WithContext(ctx).WithFields(map[string]any{"request_id": "abc"}).Info("Request processed")
golog.WithPairs("user_id", 123, "action", "login").Info("User logged in")
golog.SetLevel(golog.LevelDebug)
golog.SetSkipFrames(2)
Index ¶
- Constants
- func Debug(msg string, args ...any)
- func Error(msg string, args ...any) error
- func Flush()
- func GetSkipFrames() int
- func Info(msg string, args ...any)
- func LevelString(level int) string
- func NewDefaultWriter(output io.Writer) *defaultWriter
- func NewJSONWriter(output io.Writer) *jsonWriter
- func ParseLevel(level string) int
- func RegisterEnricher(enricher Enricher)
- func SetLevel(level int)
- func SetSkipFrames(skip int)
- func SetWriter(logger LogWriter)
- type Enricher
- type EnricherFunc
- type LogScope
- func (l *LogScope) Context() context.Context
- func (l *LogScope) Debug(msg string, args ...any)
- func (l *LogScope) Error(msg string, args ...any) error
- func (l *LogScope) Flush()
- func (l *LogScope) Info(msg string, args ...any)
- func (l *LogScope) With(key string, value any) *LogScope
- func (l *LogScope) WithContext(ctx context.Context) *LogScope
- func (l *LogScope) WithError(err error) *LogScope
- func (l *LogScope) WithFields(fields map[string]any) *LogScope
- type LogWriter
Examples ¶
Constants ¶
const ( LevelDebug = iota // 0 - detailed debugging information LevelInfo // 1 - general operational information (default minimum) LevelError // 2 - error conditions )
Log level constants. Lower values are less severe; only messages with level >= the minimum (set via SetLevel) are logged.
const ( // FieldTime is the key for time of log FieldTime = "time" // FieldLevel is the key for level of log FieldLevel = "level" // FieldMessage is the key for message of log FieldMessage = "msg" // FieldCaller is the key for caller of log FieldCaller = "caller" )
Standard JSON log field names used in log output
Variables ¶
This section is empty.
Functions ¶
func Debug ¶
Debug logs a message at the debug level. Args are passed to fmt.Sprintf for message formatting.
func Error ¶
Error logs a message at the error level and returns an error for propagation. Args are passed to fmt.Sprintf for message formatting.
func Flush ¶
func Flush()
Flush ensures all buffered log entries are written. It calls Flush on the global log writer instance.
func GetSkipFrames ¶ added in v1.1.0
func GetSkipFrames() int
GetSkipFrames returns the number of frames to skip when logging.
func Info ¶
Info logs a message at the info level. Args are passed to fmt.Sprintf for message formatting.
func LevelString ¶
LevelString converts an integer level to its string representation. Returns "UNKNOWN" if the level is invalid.
func NewDefaultWriter ¶
NewDefaultWriter creates a new defaultWriter instance with the given io.Writer. The writer is wrapped in a buffer for better performance. Unsupported field types (complex64, complex128, channels, functions) will cause a panic.
Example:
writer := NewDefaultWriter(os.Stdout)
func NewJSONWriter ¶
NewJSONWriter creates a new JSON logger that writes machine-readable logs to the given io.Writer. Each log entry is a single JSON object with keys: time, level, msg, caller, plus any custom fields. Ideal for production environments and log aggregation tools (e.g., ELK, Datadog).
Example output:
{"time":"2024-03-30T12:34:56Z","level":"INFO","msg":"User logged in","caller":"main.go:42","user_id":123}
func ParseLevel ¶
ParseLevel converts a string level name to its integer value. The parsing is case-insensitive (e.g., "debug", "DEBUG", "Debug" all map to LevelDebug). Returns -1 if the level name is invalid.
Example ¶
fmt.Println(ParseLevel("debug"))
fmt.Println(ParseLevel("INFO"))
fmt.Println(ParseLevel("invalid"))
Output: 0 1 -1
func RegisterEnricher ¶
func RegisterEnricher(enricher Enricher)
RegisterEnricher adds a new enricher to the global enrichers list. Enrichers are called in the order they are registered.
func SetLevel ¶
func SetLevel(level int)
SetLevel sets the minimum log level that should be logged. Only messages with severity >= minLevel will be logged. Use LevelDebug, LevelInfo, or LevelError, or ParseLevel for string-based config.
func SetSkipFrames ¶
func SetSkipFrames(skip int)
SetSkipFrames sets the number of frames to skip when logging. This is useful for logging from functions that are called by other functions.
Types ¶
type Enricher ¶
type Enricher interface {
// Enrich adds additional fields to a log entry based on the context.
// Modify the fields map in place; do not replace it.
Enrich(ctx context.Context, level string, msg string, fields map[string]any)
}
Enricher defines the interface for log entry enrichment. Enrichers add additional fields to log entries based on context. The fields map is modified in place; add keys to enrich the log entry.
type EnricherFunc ¶
EnricherFunc is a function type that implements the Enricher interface. Use it to create enrichers without defining a new type:
golog.RegisterEnricher(golog.EnricherFunc(func(ctx context.Context, level, msg string, fields map[string]any) {
fields["trace_id"] = traceIDFromContext(ctx)
}))
Example ¶
// EnricherFunc allows using a function as an Enricher without defining a new type
enricher := EnricherFunc(func(ctx context.Context, level, msg string, fields map[string]any) {
fields["trace_id"] = "abc-123"
})
// Use with RegisterEnricher at startup
_ = enricher
fmt.Println("EnricherFunc registered")
Output: EnricherFunc registered
type LogScope ¶
type LogScope struct {
// contains filtered or unexported fields
}
LogScope represents a logging context with associated fields and enrichers. It supports method chaining (With, WithFields, WithContext, WithError) and is typically used for request handlers or operations where fields should propagate to all log calls. LogScope is not thread-safe; create a new scope per goroutine.
func With ¶
With creates a new LogScope with a single key-value field. LogScope is not thread-safe; create a new scope per goroutine.
func WithContext ¶
WithContext creates a new LogScope with the given context. It is a convenience function for creating a scope with a context.
func WithError ¶
WithError creates a new LogScope with an error field. It is a convenience function for creating a scope with an error.
func WithFields ¶
WithFields creates a new LogScope with multiple fields. It is a convenience function for creating a scope with multiple fields at once.
func WithPairs ¶
WithPairs creates a new LogScope with multiple fields from alternating key-value pairs. Args must be an even number: key1, value1, key2, value2, ... Panics if args has odd length or if any key is not a string.
Example ¶
buf := &bytes.Buffer{}
oldWriter := instance
instance = NewDefaultWriter(buf)
defer func() { instance = oldWriter }()
WithPairs("user_id", 123, "action", "login").Info("User logged in")
instance.Flush()
output := buf.String()
if strings.Contains(output, "User logged in") && strings.Contains(output, "user_id") {
fmt.Println("ok")
}
Output: ok
func (*LogScope) Debug ¶
Debug writes a log entry at the debug level. The message and any additional arguments are formatted using fmt.Sprintf.
func (*LogScope) Error ¶
Error writes a log entry at the error level and returns an error for propagation. The message and any additional arguments are formatted using fmt.Sprintf. If the scope has an error field (via WithError), returns errors.Wrap of that error; otherwise returns a new error with the formatted message.
func (*LogScope) Flush ¶
func (l *LogScope) Flush()
Flush ensures all buffered log entries are written. It calls Flush on the underlying log writer.
func (*LogScope) Info ¶
Info writes a log entry at the info level. The message and any additional arguments are formatted using fmt.Sprintf.
func (*LogScope) With ¶
With adds a key-value field to this LogScope. It returns the LogScope for method chaining.
func (*LogScope) WithContext ¶
WithContext sets the context for this LogScope. It returns the LogScope for method chaining.
type LogWriter ¶
type LogWriter interface {
// Write writes a log entry with the given level, message, and fields
Write(level int, msg string, fields map[string]any)
// Flush ensures all buffered log entries are written
Flush()
}
LogWriter defines the interface for log output writers. Implementations should handle the actual writing of log entries.