dynamic foundation for logging
Intelligent channel-based logging built on Go’s slog
The dl package provides structured logging with channel-based routing, allowing different log categories to have independent destinations, formats, and configurations. Built on Go’s standard slog package for performance and compatibility.
Quick Reference
Section titled “Quick Reference”1. Basic Logging - Hello World
Section titled “1. Basic Logging - Hello World”Simple structured logging
import "github.com/michaelquigley/df/dl"
// Basic loggingdl.Log().Info("application started")dl.Log().Error("connection failed")
// Contextual logging with attributesdl.Log().With("user", "alice").Info("user logged in")dl.Log().With("port", 8080).With("host", "localhost").Info("server listening")
// Builder pattern for complex contextlogger := dl.Log().With("request_id", "req-123").With("user_id", "user-456")logger.Info("processing request")logger.With("duration", "250ms").Info("request completed")2. Formatted Logging - Printf Style
Section titled “2. Formatted Logging - Printf Style”Traditional printf-style logging
// Formatted messagesdl.Log().Infof("server started on port %d", 8080)dl.Log().Errorf("connection failed after %d attempts", retries)dl.Log().Warnf("disk usage at %d%% on %s", usage, disk)
// With contextdl.Log().With("user", "alice").Infof("login attempt #%d", attempts)3. Channel Routing - Categorized Logging
Section titled “3. Channel Routing - Categorized Logging”Route different categories to different destinations
// Different categories use different channelsdl.ChannelLog("database").Info("connection established")dl.ChannelLog("http").With("method", "GET").With("path", "/api/users").Info("request")dl.ChannelLog("auth").With("user", "alice").Info("authentication successful")dl.ChannelLog("errors").With("code", 500).Error("internal server error")
// Channels work with builder patterndbLogger := dl.ChannelLog("database").With("connection_id", "conn-123")dbLogger.Info("query started")dbLogger.With("duration", "45ms").Info("query completed")4. Channel Configuration - Independent Settings
Section titled “4. Channel Configuration - Independent Settings”Configure each channel independently
import "os"
// Database logs → file (no color)dbFile, _ := os.Create("logs/database.log")dl.ConfigureChannel("database", dl.DefaultOptions().SetOutput(dbFile))
// HTTP logs → stderr in JSON formatdl.ConfigureChannel("http", dl.DefaultOptions().JSON().SetOutput(os.Stderr))
// Error logs → console with colorsdl.ConfigureChannel("errors", dl.DefaultOptions().Color())
// Now each channel routes to its configured destinationdl.ChannelLog("database").Info("logged to file") // → logs/database.logdl.ChannelLog("http").Info("logged as JSON") // → stderr (JSON)dl.ChannelLog("errors").Error("logged with colors") // → console (colored)5. Output Formats - Pretty and JSON
Section titled “5. Output Formats - Pretty and JSON”Different output formats for different needs
// Pretty format (human-readable, default for console)dl.ConfigureChannel("console", dl.DefaultOptions().Pretty().Color())
// JSON format (machine-readable, for log aggregation)dl.ConfigureChannel("api", dl.DefaultOptions().JSON())
// No color (for files)logFile, _ := os.Create("app.log")dl.ConfigureChannel("file", dl.DefaultOptions().Pretty().NoColor().SetOutput(logFile))
// Examples of output:// Pretty: 2024-01-15 14:30:25 INFO user authenticated user_id=123// JSON: {"time":"2024-01-15T14:30:25Z","level":"INFO","msg":"user authenticated","user_id":123}6. Log Levels - Filtering
Section titled “6. Log Levels - Filtering”Control verbosity with log levels
import "log/slog"
// Configure different levels per channeldl.ConfigureChannel("debug", dl.DefaultOptions().SetLevel(slog.LevelDebug))dl.ConfigureChannel("errors", dl.DefaultOptions().SetLevel(slog.LevelError))
// Global initialization with leveldl.Init(dl.DefaultOptions().SetLevel(slog.LevelInfo))
// All standard levels availabledl.Log().Debug("debug message") // only shown if level <= Debugdl.Log().Info("info message") // shown if level <= Infodl.Log().Warn("warning message") // shown if level <= Warndl.Log().Error("error message") // shown if level <= Error7. Multiple Destinations - Flexible Routing
Section titled “7. Multiple Destinations - Flexible Routing”Route to multiple destinations simultaneously
// Create multiple outputsconsoleOut := os.StdoutfileOut, _ := os.Create("app.log")errorOut, _ := os.Create("errors.log")
// Configure different channels for different purposesdl.ConfigureChannel("general", dl.DefaultOptions().Pretty().SetOutput(consoleOut))dl.ConfigureChannel("audit", dl.DefaultOptions().JSON().SetOutput(fileOut))dl.ConfigureChannel("alerts", dl.DefaultOptions().Color().SetOutput(errorOut))
// Route events appropriatelydl.ChannelLog("general").Info("application event") // → console (pretty)dl.ChannelLog("audit").Info("user action logged") // → app.log (JSON)dl.ChannelLog("alerts").Error("critical failure") // → errors.log (colored)8. Initialization - Global Settings
Section titled “8. Initialization - Global Settings”Configure default behavior
// Initialize with custom defaultsdl.Init(dl.DefaultOptions(). SetLevel(slog.LevelDebug). Color(). SetTrimPrefix("github.com/mycompany/myapp"))
// All subsequent logging uses these defaults unless channel is configureddl.Log().Debug("this will be shown and colored")
// Per-channel config overrides global defaultsdl.ConfigureChannel("api", dl.DefaultOptions().JSON().SetLevel(slog.LevelWarn))dl.ChannelLog("api").Debug("this won't be shown (level too low)")dl.ChannelLog("api").Warn("this will be shown as JSON")9. Advanced Options - Fine Control
Section titled “9. Advanced Options - Fine Control”Detailed configuration options
opts := dl.DefaultOptions()
// Time formattingopts.TimestampFormat = "15:04:05.000" // custom time formatopts.AbsoluteTime = true // show absolute vs relative time
// Function name trimmingopts.TrimPrefix = "github.com/mycompany/myapp" // trim from function names
// Custom colorsopts.ErrorColor = "\033[91m" // bright redopts.InfoColor = "\033[92m" // bright greenopts.TimestampColor = "\033[90m" // dark gray
// Level labelsopts.ErrorLabel = " ERR"opts.InfoLabel = "INFO"opts.DebugLabel = " DBG"
dl.ConfigureChannel("custom", opts)10. Context Integration - Request Tracking
Section titled “10. Context Integration - Request Tracking”Integrate with request context and tracing
// Build context throughout request lifecyclefunc handleRequest(w http.ResponseWriter, r *http.Request) { requestID := generateRequestID()
// Base logger for this request reqLogger := dl.ChannelLog("http"). With("request_id", requestID). With("method", r.Method). With("path", r.URL.Path)
reqLogger.Info("request started")
// Pass context to deeper functions processUser(reqLogger.With("component", "user_service"), userID)
reqLogger.With("status", 200).Info("request completed")}
func processUser(logger *dl.Builder, userID string) { // Logger already has request context + component logger.With("user_id", userID).Info("processing user")
// Database operations with same context dbLogger := logger.With("table", "users") dbLogger.Info("querying user") dbLogger.With("rows", 1).Info("query completed")}11. Performance Patterns - High Volume
Section titled “11. Performance Patterns - High Volume”Optimize for high-volume logging
// Pre-build loggers for hot pathsvar ( dbLogger = dl.ChannelLog("database") httpLogger = dl.ChannelLog("http") authLogger = dl.ChannelLog("auth"))
// Conditional logging to avoid expensive operationsif dl.Log().Enabled(context.Background(), slog.LevelDebug) { dl.Log().Debug("expensive debug info", "data", expensiveOperation())}
// Use appropriate levelsdl.Log().Debug("detailed trace") // disabled in productiondl.Log().Info("normal operation") // general informationdl.Log().Warn("something unusual") // attention neededdl.Log().Error("operation failed") // errors requiring action12. Integration Patterns - With Applications
Section titled “12. Integration Patterns - With Applications”Integrate logging into larger applications
// Application startupfunc main() { // Initialize logging first setupLogging()
// Start application components app := da.NewApplication(config) da.WithFactory(app, &LoggerFactory{}) // provides dl loggers to other components
app.Initialize() app.Start()}
func setupLogging() { // Global setup dl.Init(dl.DefaultOptions().SetLevel(slog.LevelInfo))
// Per-service channels dbFile, _ := os.Create("logs/database.log") dl.ConfigureChannel("database", dl.DefaultOptions().SetOutput(dbFile))
apiFile, _ := os.Create("logs/api.log") dl.ConfigureChannel("api", dl.DefaultOptions().JSON().SetOutput(apiFile))
// Error aggregation dl.ConfigureChannel("errors", dl.DefaultOptions().Color().SetLevel(slog.LevelError))}
// Factory provides loggers to application componentstype LoggerFactory struct{}
func (f *LoggerFactory) Build(app *da.Application[Config]) error { // Register channel-specific loggers da.SetNamed(app.R, "database", dl.ChannelLog("database")) da.SetNamed(app.R, "api", dl.ChannelLog("api")) da.SetNamed(app.R, "errors", dl.ChannelLog("errors")) return nil}Core Functions
Section titled “Core Functions”| Function | Purpose | Use Case |
|---|---|---|
dl.Log() | Default logger builder | General application logging |
dl.ChannelLog(name) | Channel-specific logger | Categorized logging |
dl.ConfigureChannel(name, opts) | Configure channel behavior | Route/format specific channels |
dl.Init(opts) | Initialize global defaults | Application startup |
dl.DefaultOptions() | Create configuration | Channel and global setup |
Builder Methods
Section titled “Builder Methods”| Method | Purpose | Example |
|---|---|---|
.With(key, value) | Add context attribute | .With("user_id", 123) |
.Info(msg) | Log info message | .Info("operation completed") |
.Warn(msg) | Log warning message | .Warn("disk space low") |
.Error(msg) | Log error message | .Error("connection failed") |
.Debug(msg) | Log debug message | .Debug("detailed trace") |
.Infof(fmt, args...) | Printf-style info | .Infof("port %d", 8080) |
Options Methods
Section titled “Options Methods”| Method | Purpose | Example |
|---|---|---|
.SetOutput(w) | Set output destination | .SetOutput(os.Stderr) |
.SetLevel(level) | Set minimum level | .SetLevel(slog.LevelDebug) |
.JSON() | Enable JSON format | .JSON() |
.Pretty() | Enable pretty format | .Pretty() |
.Color() | Enable colors | .Color() |
.NoColor() | Disable colors | .NoColor() |
Common Patterns
Section titled “Common Patterns”Multi-Service Application
Section titled “Multi-Service Application”// Service-specific channelsdl.ChannelLog("user-service").With("user_id", 123).Info("user updated")dl.ChannelLog("order-service").With("order_id", 456).Info("order processed")dl.ChannelLog("payment-service").With("transaction_id", 789).Error("payment failed")Request Correlation
Section titled “Request Correlation”// All logs for a request share contextreqLogger := dl.ChannelLog("api").With("request_id", id).With("user_id", userID)reqLogger.Info("request started")reqLogger.With("duration", elapsed).Info("request completed")Environment-Specific Configuration
Section titled “Environment-Specific Configuration”if isProduction() { dl.Init(dl.DefaultOptions().JSON().SetLevel(slog.LevelWarn)) dl.ConfigureChannel("audit", dl.DefaultOptions().JSON().SetOutput(auditFile))} else { dl.Init(dl.DefaultOptions().Pretty().Color().SetLevel(slog.LevelDebug))}See dl/examples/ for complete working examples of each feature.