Fast and flexible structured logging library for Go inspired by zerolog
- High Performance: Zero-allocation logging with memory pooling
- Structured Logging: Type-safe field methods for all Go primitives
- Multiple Output Formats: JSON and human-readable text output
- Configurable Log Levels: TRACE, DEBUG, INFO, WARN, ERROR, FATAL
- Context Support: Log attributes can be stored in and retrieved from context
- Colorized Output: Beautiful colored console output with customizable colorizers
- Flexible Configuration: Multiple writers, filters, and level configurations
- HTTP Middleware: Built-in HTTP request/response logging
- UUID Support: Native UUID logging support
- Call Stack Tracing: Capture and log call stacks for debugging
- Memory Safety: Nil-safe logger implementation prevents panics
- Sub-loggers: Create child loggers with inherited attributes
go get github.com/domonda/golog
package main
import (
"os"
"github.com/domonda/golog"
)
func main() {
// Create a basic text logger
config := golog.NewConfig(
&golog.DefaultLevels,
golog.AllLevelsActive,
golog.NewTextWriterConfig(os.Stdout, nil, nil),
)
log := golog.NewLogger(config)
// Simple logging
log.Info("Hello, World!").Log()
log.Error("Something went wrong").Err(errors.New("example error")).Log()
}
// Create a JSON logger
config := golog.NewConfig(
&golog.DefaultLevels,
golog.AllLevelsActive,
golog.NewJSONWriterConfig(os.Stdout, nil),
)
log := golog.NewLogger(config)
log.Info("User login").
Str("username", "john_doe").
Str("ip", "192.168.1.1").
Duration("login_time", time.Since(start)).
Log()
Output:
{"timestamp":"2024-01-15T10:30:45Z","level":"INFO","message":"User login","username":"john_doe","ip":"192.168.1.1","login_time":"150ms"}
log.Info("Processing request").
Str("method", "POST").
Str("path", "/api/users").
Int("user_id", 12345).
Bool("authenticated", true).
Float("response_time", 0.145).
UUID("request_id", requestID).
Time("started_at", time.Now()).
Strs("tags", []string{"api", "user", "create"}).
JSON("metadata", jsonBytes).
Log()
golog supports six standard log levels:
- TRACE (-20): Most verbose, for tracing execution flow
- DEBUG (-10): Debug information for development
- INFO (0): General information messages
- WARN (10): Warning messages for potentially harmful situations
- ERROR (20): Error conditions that don't require immediate attention
- FATAL (30): Critical errors that may cause application termination
log.Trace("Entering function").Str("function", "processData").Log()
log.Debug("Variable state").Int("counter", counter).Log()
log.Info("Operation completed").Log()
log.Warn("Deprecated API used").Str("api", "/old/endpoint").Log()
log.Error("Failed to connect").Err(err).Log()
log.Fatal("Critical system failure").Log() // Calls panic after logging
// Create a sub-logger with common attributes
subLog := log.With().
Str("service", "user-management").
UUID("request_id", requestID).
SubLogger()
// All logs from subLog will include the above attributes
subLog.Info("User created").Str("username", "john").Log()
subLog.Error("User validation failed").Err(validationErr).Log()
// Add attributes to context
ctx = golog.ContextWithAttribs(ctx,
golog.Str("correlation_id", correlationID),
golog.Str("user_id", userID),
)
// Create logger from context
ctxLogger := log.WithCtx(ctx)
ctxLogger.Info("Operation started").Log() // Includes context attributes
// Log to multiple outputs with different formats
config := golog.NewConfig(
&golog.DefaultLevels,
golog.AllLevelsActive,
golog.NewTextWriterConfig(os.Stdout, nil, golog.NewStyledColorizer()),
golog.NewJSONWriterConfig(logFile, nil, golog.LevelFilterFrom(golog.DefaultLevels.Warn)),
)
log := golog.NewLogger(config)
// This will appear in colored text on stdout and as JSON in the file (if WARN+)
log.Error("Database connection failed").Err(err).Log()
func loggingMiddleware(log *golog.Logger) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// Log request
log.Info("HTTP request").
Request(r).
Log()
next.ServeHTTP(w, r)
// Log response
log.Info("HTTP response").
Str("method", r.Method).
Str("path", r.URL.Path).
Duration("duration", time.Since(start)).
Log()
})
}
}
colorizer := golog.NewStyledColorizer()
// or implement your own Colorizer interface
config := golog.NewConfig(
&golog.DefaultLevels,
golog.AllLevelsActive,
golog.NewTextWriterConfig(os.Stdout, nil, colorizer),
)
log.Error("Panic recovered").
CallStack("stack").
Any("panic_value", panicValue).
Log()
customLevels := &golog.Levels{
Trace: -20,
Debug: -10,
Info: 0,
Warn: 10,
Error: 20,
Fatal: 30,
Names: map[golog.Level]string{
-20: "TRACE",
-10: "DEBUG",
0: "INFO",
10: "WARN",
20: "ERROR",
30: "FATAL",
},
}
// Only log WARN and above
filter := golog.LevelFilterFrom(golog.DefaultLevels.Warn)
// Multiple filters
filter := golog.JoinLevelFilters(
golog.LevelFilterFrom(golog.DefaultLevels.Debug),
golog.NewLevelFilterFunction(func(ctx context.Context, level golog.Level) bool {
// Custom filter logic
return shouldLog(ctx, level)
}),
)
golog is designed for high performance:
- Zero-allocation logging in most cases
- Object pooling for message and writer instances
- Efficient JSON encoding
- Lazy evaluation of expensive operations
- Minimal overhead for inactive log levels
- Logger: Main logging interface
- Message: Fluent message builder
- Config: Logger configuration
- WriterConfig: Output writer configuration
- Level: Log level type
- LevelFilter: Level filtering interface
- JSONWriter: Structured JSON output
- TextWriter: Human-readable text output
- CallbackWriter: Custom callback-based writer
- MultiWriter: Multiple writer composition
- NopWriter: No-operation writer for testing
For complete API documentation, see pkg.go.dev.
This project is licensed under the MIT License - see the LICENSE file for details.