A structured logging package for Go applications built on top of Uber's Zap logging library. This package provides a simplified API for common logging patterns while maintaining the performance benefits of Zap.
- Structured logging with key-value pairs for better log analysis
- Multiple logging levels (Debug, Info, Warn, Error, DPanic, Panic, Fatal)
- Context-aware logging to propagate logging fields through your application
- Global logging functions for simple use cases
- Highly configurable with sensible defaults
- High performance leveraging Zap's optimized logging implementation
go get github.com/twlvprscs/logThe simplest way to use the package is with the global logging functions:
package main
import (
"time"
"github.com/twlvprscs/log"
"go.uber.org/zap"
)
func main() {
// Initialize a default logger and set it as global
log.NewLogger(log.AsGlobal())
// Use global logging functions
log.Info("Application started", zap.Int("port", 8080))
// Add structured data to your logs
log.Debug("Connection established",
zap.String("remote_addr", "192.168.1.1:3000"),
zap.Duration("latency", 5*time.Millisecond),
)
// Log errors with stack traces
if err := connectToDatabase(); err != nil {
log.Error("Database connection failed", zap.Error(err))
}
// Function defined elsewhere in your code
// func connectToDatabase() error { ... }
// Ensure logs are flushed before exiting
defer log.Sync()
}For more control, you can create a custom logger:
package main
import (
"github.com/twlvprscs/log"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func main() {
// Create a custom logger with specific options
logger := log.NewLogger(
log.WithLevel(zapcore.InfoLevel),
log.WithFields(
zap.String("service", "api"),
zap.String("version", "1.0.0"),
),
)
// Use the logger directly
logger.Info("Server starting")
// Add more fields to an existing logger
apiLogger := logger.With(zap.String("component", "auth"))
apiLogger.Debug("Processing request")
// Ensure logs are flushed
defer logger.Sync()
}The package provides context-aware logging to propagate logging fields through your application:
package main
import (
"context"
"github.com/twlvprscs/log"
"go.uber.org/zap"
)
func main() {
// Initialize the global logger
log.NewLogger(log.AsGlobal())
// Create a context with logging fields
ctx := context.Background()
ctx = log.Stash(ctx, zap.String("request_id", "abc-123"))
// Pass the context to other functions
processRequest(ctx)
}
func processRequest(ctx context.Context) {
// Get a logger from the context
logger := log.Ctx(ctx)
// Log with the fields from the context
logger.Info("Processing request")
// Add more fields for this specific log
logger.Debug("Request details",
zap.String("path", "/api/users"),
zap.String("method", "GET"),
)
// Pass the context to other functions
validateRequest(ctx)
}
func validateRequest(ctx context.Context) {
// All logs will include the request_id from the context
log.Ctx(ctx).Info("Validating request")
}For advanced configuration needs:
package main
import (
"github.com/twlvprscs/log"
"go.uber.org/zap"
)
func main() {
// Create a custom configuration
cfg := zap.NewProductionConfig()
cfg.Encoding = "json"
cfg.OutputPaths = []string{"stdout", "/var/log/app.log"}
// Customize the encoder config
cfg.EncoderConfig.TimeKey = "timestamp"
cfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
// Create a logger with the custom configuration
logger := log.NewLogger(log.WithConfig(&cfg))
// Use the logger
logger.Info("Application configured with custom settings")
}Capture logs from the standard library:
package main
import (
stdlog "log"
"github.com/twlvprscs/log"
"go.uber.org/zap/zapcore"
)
func main() {
// Redirect standard library logs to our logger at warning level
log.NewLogger(
log.AsGlobal(),
log.WithRedirectStdLog(zapcore.WarnLevel),
)
// Standard library logs will now be captured
stdlog.Println("This will be captured as a warning log")
}NewLogger(opts ...Option) *zap.Logger: Creates a new logger with the specified options
WithLevel(level zapcore.Level) Option: Sets the minimum log levelWithSampling(sampling *zap.SamplingConfig) Option: Configures log samplingAsGlobal() Option: Sets the logger as the global loggerWithFields(fields ...zap.Field) Option: Adds fields to all log entriesWithConfig(cfg *zap.Config) Option: Sets a custom configurationWithRedirectStdLog(lvl zapcore.Level) Option: Redirects standard library logs
Debug(msg string, fields ...zap.Field): Logs at debug levelInfo(msg string, fields ...zap.Field): Logs at info levelWarn(msg string, fields ...zap.Field): Logs at warning levelError(msg string, fields ...zap.Field): Logs at error levelDPanic(msg string, fields ...zap.Field): Logs at development panic levelPanic(msg string, fields ...zap.Field): Logs at panic level and panicsFatal(msg string, fields ...zap.Field): Logs at fatal level and exitsSync() error: Flushes any buffered logsWith(fields ...zap.Field) *zap.Logger: Creates a new logger with additional fields
Stash(parent context.Context, fields ...zap.Field) context.Context: Stores logging fields in a contextCtx(parent context.Context) ContextLogger: Gets a logger from a context
This project is licensed under the MIT License - see the LICENSE file for details.