Overview
The New() function is the primary constructor for creating Logger instances in go_logs v3. It uses the Option pattern for flexible, readable configuration.
Function Signature
func New(opts ...Option) (Logger, error)
Zero or more Option functions to configure the logger (WithLevel, WithOutput, WithFormatter, etc.)
Returns:
Logger - A configured Logger instance
error - An error if configuration fails (e.g., invalid file path)
Default Configuration
If no options are provided, the logger uses sensible defaults:
| Setting | Default Value | Description |
|---|
| Level | InfoLevel | Minimum log level |
| Output | os.Stdout | Where logs are written |
| Formatter | TextFormatter | Log format (or from LOG_FORMAT env var) |
| Hooks | [] (empty) | No hooks configured |
| Redactor | nil | No redaction |
| Caller | false | Caller info disabled |
| StackTrace | false | Stack traces disabled |
Example:
// Logger with all defaults
logger, err := go_logs.New()
if err != nil {
log.Fatal(err)
}
logger.Info("Server started") // Uses defaults
Configuration Options
WithLevel
Sets the minimum log level threshold.
func WithLevel(level Level) Option
Minimum level: TraceLevel (10), DebugLevel (20), InfoLevel (30), WarnLevel (40), ErrorLevel (50), FatalLevel (60), SilentLevel (0)
Example:
logger, _ := go_logs.New(
go_logs.WithLevel(go_logs.DebugLevel),
)
logger.Debug("This will be logged")
logger.Trace("This will be filtered out")
WithOutput
Sets where logs are written.
func WithOutput(output io.Writer) Option
Any io.Writer (os.Stdout, os.Stderr, file, buffer, custom writer)
Example:
file, _ := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
defer file.Close()
logger, _ := go_logs.New(
go_logs.WithOutput(file),
)
logger.Info("Logged to file")
Sets the log format.
func WithFormatter(formatter Formatter) Option
TextFormatter (colored output for development) or JSONFormatter (structured JSON for production)
Example:
// JSON formatter for production
logger, _ := go_logs.New(
go_logs.WithFormatter(go_logs.NewJSONFormatter()),
)
logger.Info("User login", go_logs.String("user_id", "123"))
// Output: {"timestamp":"2026-03-03T10:30:00Z","level":"INFO","message":"User login","user_id":"123"}
// Text formatter for development
devLogger, _ := go_logs.New(
go_logs.WithFormatter(go_logs.NewTextFormatter()),
)
devLogger.Info("Server started")
// Output: 2026/03/03 10:30:00 [INFO] Server started
WithRotatingFile
Configures automatic log file rotation by size.
func WithRotatingFile(filename string, maxSizeMB int, maxBackups int) Option
Path to the log file (e.g., “/var/log/app.log”)
Maximum file size in MB before rotation (e.g., 100)
Number of backup files to keep (e.g., 5)
Example:
logger, err := go_logs.New(
go_logs.WithRotatingFile("/var/log/app.log", 100, 5),
)
if err != nil {
log.Fatal(err)
}
// Automatically rotates when app.log reaches 100MB
// Keeps: app.log, app.log.1, app.log.2, app.log.3, app.log.4, app.log.5
WithHook
Adds a hook for custom log processing.
func WithHook(hook Hook) Option
A Hook interface implementation for custom processing (e.g., SlackHook, MetricsHook)
Example:
import "github.com/drossan/go_logs/hooks"
slackHook := hooks.NewSlackHook("xoxb-token", "C123456", go_logs.ErrorLevel)
logger, _ := go_logs.New(
go_logs.WithHook(slackHook),
)
// Errors and above are sent to Slack
logger.Error("Database connection failed", go_logs.Err(err))
WithRedactor
Enables automatic redaction of sensitive fields.
func WithRedactor(keys ...string) Option
Field keys to redact (e.g., “password”, “token”, “api_key”)
Example:
logger, _ := go_logs.New(
go_logs.WithRedactor("password", "token", "api_key"),
)
logger.Info("User login",
go_logs.String("username", "john"),
go_logs.String("password", "secret123"),
)
// Output: INFO User login username=john password=***
Common Redaction:
// Redacts: password, passwd, pwd, token, secret, api_key, apikey, authorization, auth
logger, _ := go_logs.New(
go_logs.WithCommonRedaction(),
)
WithCaller
Enables automatic capture of caller information (file, line, function).
func WithCaller(enabled bool) Option
true to enable caller information, false to disable
Example:
logger, _ := go_logs.New(
go_logs.WithCaller(true),
)
logger.Info("Server started")
// Output: 2026/03/03 10:30:00 [INFO] main.go:42 main() Server started
WithCallerLevel
Enables automatic caller capture only for specific levels and above.
func WithCallerLevel(level Level) Option
Minimum level for automatic caller capture (default: ErrorLevel)
Example:
logger, _ := go_logs.New(
go_logs.WithCallerLevel(go_logs.ErrorLevel),
)
// No caller info for Info
logger.Info("Normal operation")
// Caller info automatically added for Error
logger.Error("Failed to connect", go_logs.Err(err))
// Output: 2026/03/03 10:30:00 [ERROR] service.go:123 Connect() Failed to connect error=...
WithStackTrace
Enables stack trace capture.
func WithStackTrace(enabled bool) Option
true to enable stack traces, false to disable
Example:
logger, _ := go_logs.New(
go_logs.WithStackTrace(true),
go_logs.WithStackTraceLevel(go_logs.ErrorLevel),
)
logger.Error("Critical error", go_logs.Err(err))
// Output includes full stack trace for errors
WithMultiOutput
Writes logs to multiple outputs simultaneously.
func WithMultiOutput(writers ...io.Writer) Option
Multiple io.Writer destinations (e.g., stdout + file)
Example:
file, _ := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
defer file.Close()
logger, _ := go_logs.New(
go_logs.WithMultiOutput(os.Stdout, file),
)
// Logs to both console and file
logger.Info("Server started")
Complete Examples
Development Logger
devLogger, err := go_logs.New(
go_logs.WithLevel(go_logs.DebugLevel),
go_logs.WithFormatter(go_logs.NewTextFormatter()),
go_logs.WithOutput(os.Stdout),
go_logs.WithCaller(true),
)
if err != nil {
log.Fatal(err)
}
devLogger.Debug("Starting service", go_logs.String("env", "development"))
Production Logger
prodLogger, err := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel),
go_logs.WithFormatter(go_logs.NewJSONFormatter()),
go_logs.WithRotatingFile("/var/log/app.log", 100, 10),
go_logs.WithCommonRedaction(),
go_logs.WithCallerLevel(go_logs.ErrorLevel),
go_logs.WithStackTraceLevel(go_logs.ErrorLevel),
)
if err != nil {
log.Fatal(err)
}
defer prodLogger.Sync()
prodLogger.Info("Application started",
go_logs.String("version", "1.0.0"),
go_logs.String("env", "production"),
)
Service Logger with Hooks
import "github.com/drossan/go_logs/hooks"
slackHook := hooks.NewSlackHook(
os.Getenv("SLACK_TOKEN"),
os.Getenv("SLACK_CHANNEL_ID"),
go_logs.ErrorLevel,
)
logger, err := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel),
go_logs.WithFormatter(go_logs.NewJSONFormatter()),
go_logs.WithOutput(os.Stdout),
go_logs.WithHook(slackHook),
)
if err != nil {
log.Fatal(err)
}
// Errors are logged to stdout AND sent to Slack
logger.Error("Payment processing failed",
go_logs.String("order_id", "12345"),
go_logs.Err(err),
)
Multi-Environment Logger
func NewLogger(env string) (go_logs.Logger, error) {
opts := []go_logs.Option{
go_logs.WithLevel(go_logs.InfoLevel),
}
switch env {
case "development":
opts = append(opts,
go_logs.WithLevel(go_logs.DebugLevel),
go_logs.WithFormatter(go_logs.NewTextFormatter()),
go_logs.WithOutput(os.Stdout),
go_logs.WithCaller(true),
)
case "production":
opts = append(opts,
go_logs.WithFormatter(go_logs.NewJSONFormatter()),
go_logs.WithRotatingFile("/var/log/app.log", 100, 10),
go_logs.WithCommonRedaction(),
go_logs.WithCallerLevel(go_logs.ErrorLevel),
)
}
return go_logs.New(opts...)
}
Error Handling
Configuration Errors
logger, err := go_logs.New(
go_logs.WithRotatingFile("/invalid/path/app.log", 100, 5),
)
if err != nil {
// Handle configuration errors
log.Fatalf("Failed to create logger: %v", err)
}
Common Errors
| Error | Cause | Solution |
|---|
| ”failed to create rotating file writer” | Invalid file path or permissions | Check path exists and is writable |
| ”failed to create enhanced rotating file writer” | Invalid rotation configuration | Verify maxSizeMB > 0 and maxBackups >= 0 |
Environment Variables
The New() function respects environment variables for default configuration:
# Set default log level
export LOG_LEVEL=debug
# Set default format (text or json)
export LOG_FORMAT=json
Example:
// Uses LOG_FORMAT and LOG_LEVEL from environment
logger, _ := go_logs.New()
// Override environment with explicit options
logger, _ := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel), // Overrides LOG_LEVEL
)
Zero Overhead Options
The following options have zero performance overhead:
WithLevel - Fast-path filtering
WithFormatter - Same performance for Text/JSON
WithOutput - Direct write
Low Overhead Options
Minimal performance impact:
WithRedactor - Only processes configured keys
WithCallerLevel - Only captures when level threshold met
WithRotatingFile - Buffered writes
Higher Overhead Options
Use these selectively:
WithCaller(true) - Runtime stack inspection on every log
WithStackTrace(true) - Full stack capture
WithHook - Depends on hook implementation
Thread Safety
The New() function is thread-safe. You can create multiple loggers concurrently:
var wg sync.WaitGroup
loggers := make([]go_logs.Logger, 10)
for i := 0; i < 10; i++ {
wg.Add(1)
go func(idx int) {
defer wg.Done()
logger, _ := go_logs.New(
go_logs.WithLevel(go_logs.InfoLevel),
)
loggers[idx] = logger
}(i)
}
wg.Wait()
See Also