A Go library that enhances the standard slog package with additional handlers, context helpers, and optional gRPC integration.
- Multiple output formats: Pretty (colorized), JSON, and Logfmt
- Context-aware logging: Pass loggers through context instead of function parameters
- gRPC interceptors: Automatic logger injection for gRPC services
- Simple API: Easy-to-use wrapper around the standard slog package
- Optional gRPC support: Use build tags to exclude gRPC dependencies for smaller binaries
go get github.com/loft-orbital/slogxIf you don't need gRPC functionality, you can significantly reduce your binary size by using the nogrpc build tag:
go build -tags nogrpc ./...This excludes the gRPC dependencies and interceptors from your build, resulting in a smaller binary footprint.
slogx supports three output formats:
slogx.Pretty: Colorized, human-readable output (ideal for development)slogx.JSON: Structured JSON output (ideal for production and log aggregation)slogx.Logfmt: Key-value pair format (compatible with traditional logging systems)
You can also use the default logger which outputs to stdout with Pretty format:
slogx.Default.Info("Using the default logger")package main
import (
"os"
"github.com/loft-orbital/slogx"
)
func main() {
// Create a JSON logger
jsonLog := slogx.New(os.Stdout, slogx.JSON, false)
jsonLog.Info("Hello world!", "user", "alice", "action", "login")
// Create a pretty logger with colors (great for development)
prettyLog := slogx.New(os.Stdout, slogx.Pretty, false)
prettyLog.Info("Hello world!", "user", "alice", "action", "login")
// Create a logfmt logger
logfmtLog := slogx.New(os.Stdout, slogx.Logfmt, false)
logfmtLog.Info("Hello world!", "user", "alice", "action", "login")
// Enable verbose mode to include source location
verboseLog := slogx.New(os.Stdout, slogx.Pretty, true)
verboseLog.Debug("Debugging info", "variable", "value")
}Pass loggers through your application using context:
package main
import (
"context"
"os"
"github.com/loft-orbital/slogx"
)
func processRequest(ctx context.Context, userID string) {
// Retrieve logger from context - falls back to default logger if not found
log := slogx.FromContext(ctx)
log.Info("Processing request", "user_id", userID)
// Add request-specific attributes
requestLog := log.With("request_id", "12345")
ctx = slogx.ContextWithLogger(ctx, requestLog)
// Pass context to other functions
doSomething(ctx)
}
func doSomething(ctx context.Context) {
log := slogx.FromContext(ctx)
log.Info("Doing something") // Will include request_id attribute
}
func main() {
// Create a logger with custom configuration
log := slogx.New(os.Stdout, slogx.JSON, false)
// Inject logger into context
ctx := slogx.ContextWithLogger(context.Background(), log)
processRequest(ctx, "user123")
}Automatically inject loggers into gRPC service contexts:
package main
import (
"log/slog"
"os"
"google.golang.org/grpc"
"github.com/loft-orbital/slogx"
)
// Server-side interceptors
func setupGRPCServer() *grpc.Server {
// Create a custom logger
logger := slogx.New(os.Stdout, slogx.JSON, false)
// Add server interceptors
server := grpc.NewServer(
grpc.UnaryInterceptor(slogx.UnaryServerInterceptor(logger)),
grpc.StreamInterceptor(slogx.StreamServerInterceptor(logger)),
)
// Your gRPC handlers can now use slogx.FromContext(ctx) to get the logger
return server
}
// Client-side interceptors
func setupGRPCClient() (*grpc.ClientConn, error) {
// Use the default logger or create a custom one
logger := slogx.Default
// Add client interceptors
conn, err := grpc.Dial("localhost:50051",
grpc.WithUnaryInterceptor(slogx.UnaryClientInterceptor(logger)),
grpc.WithStreamInterceptor(slogx.StreamClientInterceptor(logger)),
// ... other dial options
)
return conn, err
}Note: If you're not using gRPC in your application, you can exclude these interceptors by building with the nogrpc tag to reduce binary size.
The gRPC functionality is optional and can be excluded using build tags. This is useful when:
- You want to minimize binary size
- You don't need gRPC functionality
- You want to avoid gRPC dependencies
To build without gRPC support:
# Build your application
go build -tags nogrpc ./...
# Run tests without gRPC
go test -tags nogrpc ./...
# Install a tool without gRPC
go install -tags nogrpc ./cmd/mytoolWhen built with the nogrpc tag, the following functions will not be available:
UnaryServerInterceptorStreamServerInterceptorUnaryClientInterceptorStreamClientInterceptor
For complete API documentation, see the godoc.
New(w io.Writer, format Format, verbose bool) *slog.Logger- Create a new loggerFromContext(ctx context.Context) *slog.Logger- Get logger from contextContextWithLogger(ctx context.Context, l *slog.Logger) context.Context- Add logger to context
Default- The default logger (Pretty format to stdout)
Format- Logger format type (Pretty, JSON, or Logfmt)
Please refer to the CONTRIBUTING.md file for information on how to contribute to this project.