Documentation
¶
Overview ¶
Package logger provides a comprehensive, production-ready structured logging solution built on top of logrus with extensive customization options, multiple output destinations, and seamless integration with popular Go frameworks and libraries.
Overview ¶
The logger package offers a unified logging interface that extends io.WriteCloser, making it compatible with any Go code expecting a standard writer. It supports:
- Multiple simultaneous output destinations (stdout/stderr, files, syslog)
- Level-based filtering with six standard levels (Debug, Info, Warn, Error, Fatal, Panic)
- Structured logging with custom fields
- Automatic caller tracking (file, line, function name, goroutine ID)
- Thread-safe concurrent logging
- Integration with standard Go log package
- Integration with spf13/jwalterweatherman (Hugo/Cobra logger)
- Integration with Gin web framework
- Integration with GORM ORM
Design Philosophy ¶
1. Flexibility: Support multiple output destinations and formats simultaneously 2. Performance: Async hook processing to minimize logging overhead 3. Safety: Thread-safe operations with proper synchronization 4. Compatibility: Seamless integration with existing logging infrastructure 5. Observability: Automatic context capture (caller info, stack traces, timestamps) 6. Standards: Follows structured logging best practices
Key Features ¶
Structured Logging:
- Custom fields injection at logger or entry level
- Automatic field propagation in logger clones
- Support for complex data types (maps, structs, etc.)
- Standardized field names via logger/types package
Multiple Output Destinations:
- Standard output (stdout/stderr) with color support
- File logging with rotation support
- Syslog integration (local and remote)
- Custom writer hooks for specialized outputs
Level Management:
- Six standard levels: Debug, Info, Warn, Error, Fatal, Panic
- Per-output level configuration
- Dynamic level changes without restart
- Separate level for io.Writer interface
Context Awareness:
- Goroutine ID tracking
- Caller information (file, line, function)
- Stack traces for error scenarios
- Timestamp with nanosecond precision
Architecture ¶
Package Structure:
┌──────────────────────────────────────────────────────────┐
│ github.com/nabbar/golib/logger │
├──────────────────────────────────────────────────────────┤
│ │
│ Logger Interface (interface.go) │
│ ├─ Main logging methods (Debug, Info, Warn, Error...) │
│ ├─ Configuration (SetOptions, SetLevel, SetFields) │
│ ├─ Integrations (SetStdLogger, SetSPF13Level) │
│ └─ Advanced (Clone, Entry, CheckError) │
│ │
│ Implementation (log.go, manage.go, model.go) │
│ ├─ Entry creation with automatic context │
│ ├─ Hook management and lifecycle │
│ ├─ Formatter configuration │
│ └─ Thread-safe operations │
│ │
│ I/O Integration (iowritecloser.go, golog.go) │
│ ├─ io.WriteCloser implementation │
│ ├─ Standard log.Logger bridge │
│ └─ Message filtering │
│ │
│ Framework Integration (spf13.go) │
│ └─ jwalterweatherman (Hugo/Cobra) integration │
│ │
└──────────────────────────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ config │ │ entry │ │ fields │
│ Package │ │ Package │ │ Package │
├───────────┤ ├───────────┤ ├───────────┤
│ Options │ │ Entry │ │ Fields │
│ Files │ │ Builder │ │ Manager │
│ Syslog │ │ Context │ │ Clone │
└───────────┘ └───────────┘ └───────────┘
│ │ │
└───────────────────┼───────────────────┘
│
┌───────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌────────────┐
│ level │ │ types │ │ Hook Impl │
│ Package │ │ Package │ │ Packages │
├───────────┤ ├───────────┤ ├────────────┤
│ Level │ │ Hook │ │ hookfile │
│ Constants │ │ Interface │ │ hookstdout │
│ Converters│ │ Field │ │ hookstderr │
└───────────┘ │ Constants │ │ hooksyslog │
└───────────┘ │ hookwriter │
└────────────┘
Data Flow:
Application
│
▼
Logger.Debug/Info/Warn/Error...
│
▼
Entry Creation (newEntry)
│
├─ Capture caller info (file, line, function)
├─ Capture goroutine ID
├─ Merge default fields
├─ Attach custom data/errors
└─ Format message
│
▼
Entry.Log()
│
▼
Logrus Logger
│
├─ Level filtering
└─ Formatter application
│
▼
Registered Hooks (parallel)
│
├─ Hook.Fire() (synchronous, quick)
├─ Queue entry for Hook.Run() (async)
│
└─ Hook.Run() (background goroutine)
│
├─ File writing
├─ Syslog transmission
├─ Network streaming
└─ Custom processing
Performance Characteristics ¶
Hook Processing:
- Fire() method is synchronous but must be fast (<1ms recommended)
- Run() method processes entries asynchronously in background goroutines
- Buffered channels prevent logging from blocking application code
- Graceful shutdown ensures all queued entries are processed
Memory Usage:
- Logger instance: ~512 bytes (excluding hooks and fields)
- Entry overhead: ~256 bytes per log entry
- Hook buffers: Configurable channel sizes (default: 1000 entries)
- Field storage: Minimal overhead with copy-on-write semantics
Thread Safety:
- All Logger methods are thread-safe
- Concurrent logging from multiple goroutines is supported
- Internal state protected by sync.RWMutex
- Atomic operations for simple state management
Logger Instantiation ¶
The package provides two main ways to create a logger instance:
New(ctx context.Context) Logger Creates a fresh logger instance with default settings (InfoLevel).
NewFrom(ctx context.Context, opt *config.Options, other ...any) (Logger, error) Creates a new logger by cloning an existing one or using a configuration. This is useful for: - Inheriting fields and levels from a parent logger - Applying new configuration options on top of an existing logger - Lazy initialization via FuncLog
Use Cases ¶
1. Application Logging
Basic structured logging for any Go application:
import (
"context"
"github.com/nabbar/golib/logger"
"github.com/nabbar/golib/logger/config"
"github.com/nabbar/golib/logger/level"
)
func main() {
log := logger.New(context.Background())
log.SetLevel(level.InfoLevel)
err := log.SetOptions(&config.Options{
Stdout: &config.OptionsStd{
EnableTrace: true,
},
})
if err != nil {
panic(err)
}
defer log.Close()
log.Info("Application started", nil)
log.Debug("Debug information", map[string]interface{}{
"module": "main",
"pid": os.Getpid(),
})
}
2. HTTP Server Logging
Integration with web frameworks:
func setupLogging(router *gin.Engine, log logger.Logger) {
router.Use(func(c *gin.Context) {
start := time.Now()
c.Next()
latency := time.Since(start)
log.Access(
c.ClientIP(), c.GetString("user"),
start, latency,
c.Request.Method, c.Request.URL.Path, c.Request.Proto,
c.Writer.Status(), int64(c.Writer.Size()),
).Log()
})
}
3. File and Syslog Logging
Multiple simultaneous destinations:
log.SetOptions(&config.Options{
Stdout: &config.OptionsStd{
DisableStandard: false,
},
LogFile: []config.OptionsFile{
{
Filepath: "/var/log/app/app.log",
Create: true,
CreatePath: true,
EnableTrace: true,
},
},
LogSyslog: []config.OptionsSyslog{
{
Network: "udp",
Host: "localhost",
Port: 514,
Severity: syslog.LOG_INFO,
Facility: syslog.LOG_USER,
},
},
})
4. Third-Party Integration
Standard library integration:
// Replace global standard logger
log.SetStdLogger(level.WarnLevel, stdlog.LstdFlags)
stdlog.Println("Now logged through custom logger")
// Create logger for third-party code
stdLogger := log.GetStdLogger(level.InfoLevel, stdlog.LstdFlags)
thirdPartyFunc(stdLogger)
5. Advanced Error Tracking
Structured error logging with context:
err := performOperation()
if log.CheckError(level.ErrorLevel, level.InfoLevel, "Operation result", err) {
// Error was logged at ErrorLevel
return err
}
// Success was logged at InfoLevel
// Or with full context:
entry := log.Entry(level.ErrorLevel, "Database operation failed")
entry.FieldAdd("query", query)
entry.FieldAdd("duration", duration)
entry.ErrorAdd(true, err)
entry.Log()
6. Inheriting Logger Context
Using NewFrom to create a sub-logger with inherited fields:
// Parent logger with common fields
parentLog := logger.New(ctx)
parentLog.SetFields(fields.NewFromMap(map[string]interface{}{
"app": "my-app",
"env": "prod",
}))
// Create child logger for a specific module
// It inherits "app" and "env" fields
childLog, _ := logger.NewFrom(ctx, nil, parentLog)
childLog.SetFields(fields.NewFromMap(map[string]interface{}{
"module": "database",
}))
childLog.Info("Connecting to DB", nil)
// Log will contain: app=my-app, env=prod, module=database
Best Practices ¶
DO:
- Always call Close() when done with a logger (use defer)
- Set appropriate log levels for production vs development
- Use structured fields instead of string formatting when possible
- Clone loggers instead of creating new ones for similar configurations
- Use Entry() for complex logging with multiple fields
- Set reasonable buffer sizes for file/syslog hooks
DON'T:
- Don't log sensitive data (passwords, tokens, etc.)
- Don't use Fatal or Panic unless absolutely necessary
- Don't create multiple loggers when one with fields would suffice
- Don't block in custom hook implementations
- Don't ignore errors from SetOptions()
- Don't use Debug level in production without careful consideration
Limitations ¶
Hook Startup Timing:
- Hooks start asynchronously when SetOptions() is called
- There's a 500ms grace period to ensure hooks are running
- Very early log entries might be delayed until hooks start
Log Ordering:
- Multiple hooks may process entries in different orders
- File writes are sequential per file but not across destinations
- Use timestamp field for accurate event ordering
Fatal/Panic Behavior:
- Fatal level calls os.Exit(1) after logging (deferred functions don't run)
- Panic level triggers panic() (use with recover() for graceful handling)
- Both levels may lose buffered log entries if exit is immediate
Memory Limits:
- Default hook buffers can hold 1000 entries
- Sustained high log volume can cause buffer overruns and dropped entries
- Adjust buffer sizes based on expected load
Sub-Packages ¶
- config: Logger configuration structures and validation
- entry: Log entry creation, manipulation, and lifecycle
- fields: Structured field management with clone and merge operations
- level: Log level definitions, conversions, and comparisons
- types: Core types, interfaces, and field constants
- hookfile: File output hook with rotation support
- hookstdout: Standard output hook with color support
- hookstderr: Standard error hook with color support
- hooksyslog: Syslog hook with local and remote support
- hookwriter: Generic io.Writer hook for custom outputs
- gorm: GORM ORM logger integration
- hashicorp: Hashicorp libraries logger integration (Vault, Consul, etc.)
External Dependencies ¶
Core:
- github.com/sirupsen/logrus: Underlying structured logging library
- github.com/spf13/jwalterweatherman: Hugo/Cobra logger integration
Sub-packages may have additional dependencies for specialized functionality.
Compatibility ¶
- Go: Requires Go 1.24 or later (hookfile requires os.OpenRoot introduced in Go 1.24)
- Logrus: Compatible with logrus v1.8+
- Platforms: Linux, macOS, Windows
- Architectures: amd64, arm64, arm, 386
Thread Safety:
- All public methods are thread-safe
- Safe for concurrent use from multiple goroutines
- Internal state protected by appropriate synchronization primitives
See Also ¶
Related packages in github.com/nabbar/golib:
- github.com/nabbar/golib/context: Context management used by logger
- github.com/nabbar/golib/ioutils/mapCloser: Closer management for hooks
- github.com/nabbar/golib/semaphore: Concurrency control for logging
External references:
- Logrus documentation: https://github.com/sirupsen/logrus
- Structured logging: https://www.thoughtworks.com/insights/blog/practical-introduction-structured-logging
- The Twelve-Factor App (Logs): https://12factor.net/logs
Example (AccessLog) ¶
Example_accessLog demonstrates HTTP access logging.
package main
import (
"context"
"fmt"
"time"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Simulate HTTP request logging
logger.Access(
"192.168.1.100", // Remote address
"john.doe", // Remote user
time.Now(), // Request time
150*time.Millisecond, // Latency
"GET", // Method
"/api/users", // Path
"HTTP/1.1", // Protocol
200, // Status
1024, // Size
).Log()
fmt.Println("Logged access entry")
}
Output: Logged access entry
Example (BasicLogging) ¶
Example_basicLogging demonstrates basic logging at different levels.
package main
import (
"context"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
// Create logger
logger := liblog.New(context.Background())
defer logger.Close()
// Configure for silent operation (no actual output in examples)
logger.SetLevel(loglvl.DebugLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Log at different levels
logger.Debug("Debug message", nil)
logger.Info("Info message", nil)
logger.Warning("Warning message", nil)
logger.Error("Error message", nil)
fmt.Println("Logged messages at multiple levels")
}
Output: Logged messages at multiple levels
Example (CloningLogger) ¶
Example_cloningLogger demonstrates creating independent logger clones.
package main
import (
"context"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
logfld "github.com/nabbar/golib/logger/fields"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Set some fields on the original
logger.SetFields(logfld.New(context.Background()).Add("logger", "main"))
// Clone creates an independent copy
clonedLogger, err := logger.Clone()
if err != nil {
panic(err)
}
defer clonedLogger.Close()
// Modify the clone without affecting original
clonedLogger.SetLevel(loglvl.DebugLevel)
clonedLogger.SetFields(logfld.New(context.Background()).Add("logger", "worker"))
logger.Info("Main logger message", nil)
clonedLogger.Debug("Cloned logger message", nil)
fmt.Println("Used cloned logger")
}
Output: Used cloned logger
Example (ConcurrentLogging) ¶
Example_concurrentLogging demonstrates thread-safe concurrent logging.
package main
import (
"context"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Launch multiple goroutines
done := make(chan bool)
for i := 0; i < 5; i++ {
go func(id int) {
logger.Info("Message from goroutine", map[string]interface{}{
"goroutine_id": id,
})
done <- true
}(i)
}
// Wait for all goroutines
for i := 0; i < 5; i++ {
<-done
}
fmt.Println("Concurrent logging completed")
}
Output: Concurrent logging completed
Example (EntryBuilder) ¶
Example_entryBuilder demonstrates using the Entry builder pattern for complex logs.
package main
import (
"context"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Build complex log entry
entry := logger.Entry(loglvl.InfoLevel, "Database query executed")
entry.FieldAdd("query", "SELECT * FROM users")
entry.FieldAdd("duration", "45ms")
entry.FieldAdd("rows", 127)
entry.Log()
fmt.Println("Logged with entry builder")
}
Output: Logged with entry builder
Example (ErrorChecking) ¶
Example_errorChecking demonstrates the CheckError convenience method.
package main
import (
"context"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Simulate an operation that might fail
performOperation := func() error {
return nil // Success
}
err := performOperation()
if logger.CheckError(loglvl.ErrorLevel, loglvl.InfoLevel, "Operation completed", err) {
fmt.Println("Error occurred")
return
}
fmt.Println("Operation successful")
}
Output: Operation successful
Example (FilteringMessages) ¶
Example_filteringMessages demonstrates filtering log messages.
package main
import (
"context"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Set up filters to drop messages containing certain patterns
logger.SetIOWriterFilter("password", "secret", "token")
// These messages will be filtered out
_, _ = logger.Write([]byte("User password is 12345"))
_, _ = logger.Write([]byte("API token: abc123"))
// This message will pass through
_, _ = logger.Write([]byte("User logged in successfully"))
fmt.Println("Filtering configured")
}
Output: Filtering configured
Example (FormattedMessages) ¶
Example_formattedMessages demonstrates using format strings in log messages.
package main
import (
"context"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Format strings work like fmt.Sprintf
userID := 42
username := "john.doe"
duration := 150
logger.Info("User %s (ID: %d) processed in %dms", nil, username, userID, duration)
fmt.Println("Logged formatted message")
}
Output: Logged formatted message
Example (IoWriterIntegration) ¶
Example_ioWriterIntegration demonstrates using logger as an io.Writer.
package main
import (
"context"
"fmt"
"io"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Set the level for io.Writer interface
logger.SetIOWriterLevel(loglvl.WarnLevel)
// Use as io.Writer
_, _ = io.WriteString(logger, "Message written through io.Writer")
fmt.Println("Used as io.Writer")
}
Output: Used as io.Writer
Example (LevelManagement) ¶
Example_levelManagement demonstrates dynamic level changes.
package main
import (
"context"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Start with Info level
logger.SetLevel(loglvl.InfoLevel)
logger.Debug("This won't be logged", nil)
logger.Info("This will be logged", nil)
// Change to Debug level
logger.SetLevel(loglvl.DebugLevel)
logger.Debug("Now this will be logged", nil)
currentLevel := logger.GetLevel()
fmt.Printf("Current level: %s\n", currentLevel.String())
}
Output: Current level: Debug
Example (LogDetails) ¶
Example_logDetails demonstrates the most flexible logging method.
package main
import (
"context"
"errors"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
logfld "github.com/nabbar/golib/logger/fields"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// LogDetails gives full control
err1 := errors.New("first error")
err2 := errors.New("second error")
errs := []error{err1, err2}
fields := logfld.New(context.Background())
fields.Add("operation", "database_migration")
fields.Add("step", 3)
data := map[string]interface{}{
"tables_affected": 5,
"records_updated": 1523,
}
logger.LogDetails(
loglvl.ErrorLevel,
"Migration encountered errors",
data,
errs,
fields,
)
fmt.Println("Logged detailed entry")
}
Output: Logged detailed entry
Example (MultipleErrors) ¶
Example_multipleErrors demonstrates logging multiple errors.
package main
import (
"context"
"errors"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.ErrorLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Multiple errors can be logged together
err1 := errors.New("connection timeout")
err2 := errors.New("retry limit exceeded")
if logger.CheckError(loglvl.ErrorLevel, loglvl.NilLevel, "Operation failed", err1, err2) {
fmt.Println("Multiple errors logged")
}
}
Output: Multiple errors logged
Example (StandardLoggerIntegration) ¶
Example_standardLoggerIntegration demonstrates using logger with standard log package.
package main
import (
"context"
"fmt"
"log"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Get a standard logger for third-party code
stdLogger := logger.GetStdLogger(loglvl.InfoLevel, log.LstdFlags)
// Use it like standard log.Logger
stdLogger.Println("Message from standard logger")
stdLogger.Printf("Formatted: %s", "message")
fmt.Println("Used standard logger integration")
}
Output: Used standard logger integration
Example (StructuredLogging) ¶
Example_structuredLogging demonstrates logging with structured data.
package main
import (
"context"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Log with structured data
userData := map[string]interface{}{
"user_id": 12345,
"email": "user@example.com",
"role": "admin",
}
logger.Info("User logged in", userData)
fmt.Println("Logged structured data")
}
Output: Logged structured data
Example (WithFields) ¶
Example_withFields demonstrates using default fields that apply to all log entries.
package main
import (
"context"
"fmt"
liblog "github.com/nabbar/golib/logger"
logcfg "github.com/nabbar/golib/logger/config"
logfld "github.com/nabbar/golib/logger/fields"
loglvl "github.com/nabbar/golib/logger/level"
)
func main() {
logger := liblog.New(context.Background())
defer logger.Close()
logger.SetLevel(loglvl.InfoLevel)
_ = logger.SetOptions(&logcfg.Options{
Stdout: &logcfg.OptionsStd{
DisableStandard: true,
},
})
// Set default fields
fields := logfld.New(context.Background())
fields.Add("service", "api")
fields.Add("environment", "production")
fields.Add("version", "1.2.3")
logger.SetFields(fields)
// These fields will be included in all log entries
logger.Info("Request processed", nil)
logger.Info("Response sent", nil)
fmt.Println("Logged with default fields")
}
Output: Logged with default fields
Index ¶
Examples ¶
- Package (AccessLog)
- Package (BasicLogging)
- Package (CloningLogger)
- Package (ConcurrentLogging)
- Package (EntryBuilder)
- Package (ErrorChecking)
- Package (FilteringMessages)
- Package (FormattedMessages)
- Package (IoWriterIntegration)
- Package (LevelManagement)
- Package (LogDetails)
- Package (MultipleErrors)
- Package (StandardLoggerIntegration)
- Package (StructuredLogging)
- Package (WithFields)
Constants ¶
const (
KeyCancel
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type FuncLog ¶ added in v1.7.0
type FuncLog func() Logger
FuncLog is a function type that returns a Logger instance. This is used for dependency injection and lazy initialization of loggers.
type Logger ¶ added in v1.7.0
type Logger interface {
io.WriteCloser
//SetLevel allow to change the minimal level of log message
SetLevel(lvl loglvl.Level)
//GetLevel return the minimal level of log message
GetLevel() loglvl.Level
//SetIOWriterLevel allow to change the minimal level of log message for io.WriterCloser interface
SetIOWriterLevel(lvl loglvl.Level)
//GetIOWriterLevel return the minimal level of log message for io.WriterCloser interface
GetIOWriterLevel() loglvl.Level
// SetIOWriterFilter allow to filter message that contained the given pattern.
// When received any message, if one pattern is found, the log is drop.
// If the given pattern is empty, the pattern list is truncated to no one pattern.
SetIOWriterFilter(pattern ...string)
// SetIOWriterFilter allow to add a filter pattern into the filter message pattern list.
AddIOWriterFilter(pattern ...string)
//SetOptions allow to set or update the options for the logger
SetOptions(opt *logcfg.Options) error
//GetOptions return the options for the logger
GetOptions() *logcfg.Options
//SetFields allow to set or update the default fields for all logger entry
// Fields are custom information added into log message
SetFields(field logfld.Fields)
//GetFields return the default fields for all logger entry
// Fields are custom information added into log message
GetFields() logfld.Fields
//Clone allow to duplicate the logger with a copy of the logger
Clone() (Logger, error)
//SetSPF13Level allow to plus spf13 logger (jww) to this logger
SetSPF13Level(lvl loglvl.Level, log *jww.Notepad)
//GetStdLogger return a golang log.logger instance linked with this main logger.
GetStdLogger(lvl loglvl.Level, logFlags int) *log.Logger
//SetStdLogger force the default golang log.logger instance linked with this main logger.
SetStdLogger(lvl loglvl.Level, logFlags int)
//Debug add an entry with DebugLevel to the logger
Debug(message string, data interface{}, args ...interface{})
//Info add an entry with InfoLevel to the logger
Info(message string, data interface{}, args ...interface{})
//Warning add an entry with WarnLevel to the logger
Warning(message string, data interface{}, args ...interface{})
//Error add an entry with ErrorLevel level to the logger
Error(message string, data interface{}, args ...interface{})
//Fatal add an entry with FatalLevel to the logger
//The function will break the process (os.exit) after log entry.
Fatal(message string, data interface{}, args ...interface{})
//Panic add an entry with PanicLevel level to the logger
//The function will break the process (os.exit) after log entry.
Panic(message string, data interface{}, args ...interface{})
//LogDetails add an entry to the logger
LogDetails(lvl loglvl.Level, message string, data interface{}, err []error, fields logfld.Fields, args ...interface{})
//CheckError will check if a not nil error is given and if yes, will add an entry to the logger.
// Othwise if the lvlOK is given (and not NilLevel) the function will add entry and said ok
CheckError(lvlKO, lvlOK loglvl.Level, message string, err ...error) bool
//Entry will return an entry struct to manage it (set gin context, add fields, log the entry...)
Entry(lvl loglvl.Level, message string, args ...interface{}) logent.Entry
//Access will return an entry struct to store info level access log message
Access(remoteAddr, remoteUser string, localtime time.Time, latency time.Duration, method, request, proto string, status int, size int64) logent.Entry
}
Logger is the main interface for structured logging operations. It extends io.WriteCloser to allow using the logger as a standard Go writer. The logger supports multiple output destinations (file, syslog, stdout/stderr), level-based filtering, custom fields injection, and integration with popular frameworks.
func New ¶ added in v1.7.0
New returns a new Logger instance with the given context. The context is used to configure the logger fields. The logger level is set to InfoLevel by default. The returned logger can be used to log messages at different levels. The logger can also be used to set the default golang log.logger instance.
func NewFrom ¶ added in v1.19.2
NewFrom creates a new Logger instance based on an existing logger or configuration. It allows cloning an existing logger's state (level, fields, options) and applying new options.
Parameters:
- ctx: The context for the new logger.
- opt: Optional configuration options to apply. If nil, defaults are used.
- other: Variadic list of sources to copy state from.
The other value will be used only if matching non-nil value of:
- Logger: Copies level, fields, and options.
- FuncLog: Executes the function and uses the returned Logger.
The function iterates through 'other' arguments and uses the last valid Logger found as the base. If a base logger is found, its level and fields are copied to the new logger. If options are provided in 'opt', they are merged with the base logger's options (if any).
Returns:
- Logger: A new initialized Logger instance.
- error: An error if applying options fails, otherwise nil.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package config provides configuration structures and validation for the logger package.
|
Package config provides configuration structures and validation for the logger package. |
|
Package entry provides a flexible, chainable logger entry wrapper for structured logging with logrus.
|
Package entry provides a flexible, chainable logger entry wrapper for structured logging with logrus. |
|
Package fields provides a thread-safe, context-aware structured logging fields management system that seamlessly integrates with logrus and Go's standard context package.
|
Package fields provides a thread-safe, context-aware structured logging fields management system that seamlessly integrates with logrus and Go's standard context package. |
|
Package gorm provides a thread-safe adapter that bridges golib's logging system with GORM v2's logger interface.
|
Package gorm provides a thread-safe adapter that bridges golib's logging system with GORM v2's logger interface. |
|
Package hashicorp provides a thread-safe adapter that bridges golib's logging system with HashiCorp's hclog interface.
|
Package hashicorp provides a thread-safe adapter that bridges golib's logging system with HashiCorp's hclog interface. |
|
Package hookfile provides file-based logging hooks for logrus.
|
Package hookfile provides file-based logging hooks for logrus. |
|
Package hookstderr provides a logrus hook for writing log entries to standard error (stderr) with configurable field filtering and formatting options.
|
Package hookstderr provides a logrus hook for writing log entries to standard error (stderr) with configurable field filtering and formatting options. |
|
Package hookstdout provides a logrus hook for writing log entries to stdout with configurable field filtering, formatting options, and cross-platform color support.
|
Package hookstdout provides a logrus hook for writing log entries to stdout with configurable field filtering, formatting options, and cross-platform color support. |
|
Package hooksyslog provides a robust and flexible logrus hook for writing log entries to syslog endpoints.
|
Package hooksyslog provides a robust and flexible logrus hook for writing log entries to syslog endpoints. |
|
Package hookwriter provides a logrus hook for writing log entries to custom io.Writer instances with configurable field filtering and formatting options.
|
Package hookwriter provides a logrus hook for writing log entries to custom io.Writer instances with configurable field filtering and formatting options. |
|
Package level defines log severity levels with conversions and parsing capabilities.
|
Package level defines log severity levels with conversions and parsing capabilities. |
|
Package types provides core types, interfaces, and constants for the logger subsystem.
|
Package types provides core types, interfaces, and constants for the logger subsystem. |