logx
logx
logx is a structured logging package built on zerolog with option-based configuration and optional slog interoperability.
Roadmap
- Module roadmap: logx roadmap
- Global roadmap: ArcGo roadmap
Features
- Strongly typed levels (
TraceLevel,DebugLevel,InfoLevel…) - Console and file output
- File rotation via
lumberjack - Optional caller and global logger setting
slogbridge helpers- Oops integration helpers
Quick Start
logger, err := logx.New(
logx.WithConsole(true),
logx.WithLevel(logx.InfoLevel),
)
if err != nil {
panic(err)
}
defer logger.Close()
logger.Info("service started", "service", "user-api")Common Scenarios
1) Development Configuration
logger, err := logx.NewDevelopment()
if err != nil { panic(err) }
defer logger.Close()2) Production Configuration
logger, err := logx.NewProduction()
if err != nil { panic(err) }
defer logger.Close()3) File Output + Rotation
logger, err := logx.New(
logx.WithConsole(false),
logx.WithFile("./logs/app.log"),
logx.WithFileRotation(100, 7, 20), // 100MB, 7 days, 20 backups
logx.WithCompress(true),
)4) Structured Fields
logger.WithField("request_id", reqID).Info("request accepted")
logger.WithFields(map[string]any{
"order_id": orderID,
"user_id": userID,
}).Info("order placed")5) Context and slog Bridge
slogLogger := logx.NewSlog(logger)
slogLogger.Info("hello", "module", "billing")6) Attach trace/span ID from context
ctx := trace.ContextWithSpanContext(context.Background(), spanContext)
logx.WithFieldT(logger, "tenant", "acme").
WithTraceContext(ctx).
Info("request accepted")Level Helpers
- Parse from string:
ParseLevel("debug") - Panic on invalid level:
MustParseLevel("info") - Convenience constructors:
Trace(),Debug(),Info()…
Error/Oops Helpers
logger.WithError(err).Error("operation failed")logger.LogOops(err)logger.Oops(),logger.Oopsf(...),logger.OopsWith(ctx)
Operational Notes
- Always call
Close()when file output is enabled. - Only use
WithGlobalLogger()when you intend to share a single logger instance across the process.
Testing Tips
- Use
WithConsole(true)in unit tests. - Use temp files for file rotation tests.
- Assert
GetLevel()/GetLevelString()for configuration level tests.
FAQ
Should I use the logx logger directly or via slog?
Both are supported:
- Use
logxmethods for directzerologstyle. - Use
NewSlogif your application standardizes on theslogAPI surface.
Do I need Close() before process exit?
Close() is the critical lifecycle call when file output is enabled. If you’re only logging to console, Close() is not required (but calling it is still safe).
Can I set a global logger?
Yes, via WithGlobalLogger() or SetGlobalLogger().
Only use this when the process intentionally shares a single logger instance.
Troubleshooting
Log file not created
Check:
WithFile(path)is set.- Process has write permission to target directory.
WithConsole(false)isn’t hiding file setup failures.
Expected debug logs missing
Verify log level (WithLevel(DebugLevel) or equivalent).
Higher levels filter lower severity logs.
Log rotation behavior not as expected
Check WithFileRotation(maxSizeMB, maxAgeDays, maxBackups) values and units.
maxSize is in MB, not bytes.
Anti-Patterns
- Creating short-lived logger instances per request.
- Forgetting
Close()when using file output. - Logging high-cardinality, unbounded fields without sampling control.
- Using panic/fatal levels in recoverable business error paths.