logx
logx is a lightweight structured logging helper for Go, built on top of the standard log/slog API (Go 1.21+).
It enhances the default logging capabilities with hierarchical log-level routing and automatic package/type attribution.
Features
• Hierarchical log-level routing
logx supports overriding log levels at three levels:
- Global log level (default for everything)
- Package-level overrides (for example,
myapp/internal/db)
- Type-level overrides (for example,
myapp/internal/db.ConnectionPool)
Priority:
type-level > package-level > global-level
logx.For() enriches log entries with:
{
"pkg": "myapp/module",
"type": "Type"
}
This eliminates the need for per-module logger initialization.
• Development vs production output
- Set
Config.Pretty to enable human-readable colorized logs (via tint).
- Unset
Config.Pretty for pure JSON structured logs.
Installation
go get github.com/shvydky/logx
Quick Start
Initialize logger
logx.Init(&logx.Config{
Pretty: true,
DefaultLevel: slog.LevelInfo, // global level
Levels: map[string]slog.Level{
// Package-level override
"myapp/worker": slog.LevelDebug,
// Type-level override
"myapp/db.ConnectionPool": slog.LevelWarn,
},
})
Struct-based loggers
type Worker struct{}
func (w *Worker) Run() {
logger := logx.For(w)
logger.Info("worker started")
}
Example output
Development mode
INFO worker started pkg=myapp/worker type=Worker
Production (JSON)
{
"time": "2025-01-08T12:00:34.123Z",
"level": "INFO",
"msg": "worker started",
"pkg": "myapp/worker",
"type": "Worker"
}
How it works
logx wraps the default slog.Handler and applies hierarchical routing:
if type-level rule exists:
use it
else if package-level rule exists:
use it
else:
use global level
Fast-path evaluation ensures minimal overhead.
For uses the current slog.Default() handler when the logger is created. If
the default logger is replaced with slog.SetDefault, subsequent calls to
For use the replacement handler; loggers returned by earlier calls keep the
handler they were created with.
When using WithHandler, configure the custom handler to accept the lowest
level present in Config.DefaultLevel and Config.Levels. Handler-level
filtering is applied in addition to logx routing, so a custom handler can
still discard a record allowed by a package- or type-level override.
Requirements
- Go 1.21+
github.com/lmittmann/tint
License
MIT License
Contributing
Issues and pull requests are welcome.