Inspired by the go-autumn library, go-autumn-slog offers an implementation of the go-autumn-logging interface. It utilizes the standard Go library for structured logging, log/slog, ensuring seamless integration and compatibility.
- Context-Aware Logging: Enhance logs with contextual information.
- Seamless Integration with slog: Utilizes slog.Logger and slog.Handler.
- Respects slog.Default: Adheres to the default logger for simplicity.
- Extended Logging Levels: Provides finer granularity with additional log levels.
- Callback Support: Allows custom handling via slog.Handler with callbacks.
- ConfigLoader Compatibility: Instantiates slog.HandlerOptions compatible with go-autumn-configloader.
To install go-autumn-slog, use the following command:
go get github.com/Roshick/go-autumn-slog
go-autumn-slog is divided into three primary areas: Loggers, Levels, and Handlers.
Creating a logging instance is simple:
myLogging := logging.New()
Given a slog.Handler
named myHandler
and a *slog.Logger
named myLogger
:
myLogger := slog.New(myHandler)
Setting the preferred logger can be prioritized in three ways:
-
Attach the logger to a context:
mySubCtx := logging.ContextWithLogger(ctx, myLogger)
-
Set the logger as the default for a new instance:
mySubLogging := myLogging.WithLogger(myLogger)
-
Set the logger as slog's default logger:
slog.SetDefault(myLogger)
The package provides configuration-based instantiation of various slog resources, compatible with go-autumn-configloader.
Supported resources include slog.HandlerOptions
, which are used by slog.TextHandler
, slog.JSONHandler
, and third-party handlers. This allows users to define log levels and manipulate record attributes, useful in standardized logging scenarios, like those defined by the Elastic Common Schema. The slog.HandlerOptions
also map new log levels to their respective string values, preventing incorrect level mappings.
Expands the default slog levels to include:
- Trace
- Debug
- Info
- Warn
- Error
- Fatal
- Panic
- Silent
Custom handlers provided by this library can be used independently of the entire logging implementation.
A handler that wraps another handler, allowing registration of callback functions of the type func(ctx context.Context, record *slog.Record) error
. These callbacks can modify the slog record and add context values, useful for adding consistent tracing information.
A no-op handler that performs no operations, useful in cases where there is no configured logger in the context, the logging system, or slog.
Below are practical examples to help integrate the library into various applications.
// Create a simple plaintext logger and set the autumn global default logger to it
aulogging.Logger = logging.New()
// Use it
aulogging.Logger.NoCtx().Info().Print("hello")
// Build a structured logger using slog.NewJSONHandler
structuredLogger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
// Set the autumn global default logger to it
aulogging.Logger = logging.New().WithLogger(structuredLogger)
// Use it (chain style or convenience style)
aulogging.Logger.NoCtx().Info().Print("hello")
aulogging.Info(context.Background(), "hello, too")
// Augment the logger with an extra field
augmentedLogger := structuredLogger.With("some-field", "some-value")
// Place it in a context
ctx := context.Background()
ctx = logging.ContextWithLogger(ctx, augmentedLogger)
// Use it from the context (chain style or convenience style)
aulogging.Logger.Ctx(ctx).Info().Print("hi")
aulogging.Info(ctx, "hi, again")
Add tracing information to every log record generated during a request to a service:
Add constant tracing information within a middleware:
myLogger := logging.FromContext(ctx)
if myLogger == nil {
myHandler := slog.NewJSONHandler(os.Stdout, nil)
myLogger = slog.New(myHandler)
}
myLogger = myLogger.With("trace-id", ctx.Value("trace-id"), "span-id", ctx.Value("span-id"))
ctx = logging.ContextWithLogger(ctx, myLogger)
For dynamic context information, use the callback handler:
myHandler := slog.NewJSONHandler(os.Stdout, nil)
myCallbackHandler := callbackhandler.New(myHandler)
err := myCallbackHandler.RegisterContextCallback(func(ctx context.Context, record *slog.Record) error {
record.Add("span-id", ctx.Value("span-id"), "request-id", ctx.Value("request-id"))
return nil
}, "add-tracing-attributes")
if err != nil {
log.Fatalf("Failed to register callback: %v", err)
}
myLogger := slog.New(myCallbackHandler)
slog.SetDefault(myLogger)
Contributions are welcome! Please fork the repository, submit a pull request, or open an issue for any bugs or feature requests.
This project is licensed under the MIT License - see the LICENSE file for details.