logger

package
v0.0.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 19, 2025 License: MIT Imports: 9 Imported by: 0

README

Logger Package

A simple, concise zapper-based logger package with configurable output formats, log levels, file rotation, and context-based tracing integration for Datadog and OpenTelemetry.

Features

  • Embedded zap.Logger: Inherit all standard zap methods
  • Context-aware tracing: Automatic trace/span ID extraction from context
  • Global logger support: Use logger.Info() anywhere in your project
  • Multiple output formats: JSON, text, and file output
  • File rotation: Automatic log rotation with configurable retention
  • Print functions: Drop-in replacement for fmt.Print* functions
  • Thread-safe: Atomic level changes and thread-safe operations

Quick Start

Basic Usage
package main

import (
    "context"
    "github.com/laziness-coders/go-utils/logger"
    "go.uber.org/zap"
)

func main() {
    // Initialize global logger with functional options
    err := logger.Init(
        logger.WithLevel(logger.LevelInfo),
        logger.WithFormat(logger.FormatJSON),
    )
    if err != nil {
        panic(err)
    }

    // Use global logger
    logger.Info("application started")
    logger.Debug("debug message", zap.String("key", "value"))

    // Use with context for tracing
    ctx := context.Background() // context with trace info
    logger.Trace(ctx).Info("processing request")
    logger.Trace(ctx).Warn("warning message", zap.Int("count", 5))
}
Print Functions (fmt replacement)
// Instead of fmt.Print*, use logger functions
logger.Print("simple message")
logger.Println("message with newline")
logger.Printf("formatted message: %s", "value")

// Level-specific printf functions
logger.Debugf("debug: %d", 42)
logger.Infof("info: %s", "information")
logger.Warnf("warning: %s", "warning message")
logger.Errorf("error: %s", "error message")
Sugar Logger
// Get sugar logger
sugar := logger.Sugar()

// Use sugar methods
sugar.Infow("user action",
    "action", "login",
    "user_id", "123",
)

// Sugar with tracing
sugar.Trace(ctx).Infow("processing with trace",
    "request_id", "req-123",
)

Configuration

Config Struct
type Config struct {
    Level      string // debug, info, warn, error (default: debug)
    Format     string // json, text, file (default: text)
    FilePath   string // file or directory path (only for file format)
    MaxSize    int    // max size in MB before rotation (default: 100)
    MaxAge     int    // max days to retain old logs (default: 30)
    MaxBackups int    // max number of old log files (default: 3)
    Compress   bool   // compress rotated files (default: false)
    IsDev      bool   // use zap's development config for human-readable output (default: false)
}
Configuration Examples
Console Output (JSON)
logger.Init(
    logger.WithLevel(logger.LevelInfo),
    logger.WithFormat(logger.FormatJSON),
)
Console Output (Text)
logger.Init(
    logger.WithLevel(logger.LevelDebug),
    logger.WithFormat(logger.FormatText),
)
File Output with Rotation
// Using functional options (recommended)
logger.Init(
    logger.WithLevel(logger.LevelInfo),
    logger.WithFileOutput("/var/log/myapp"),
    logger.WithMaxSize(100),
    logger.WithMaxAge(30),
    logger.WithMaxBackups(3),
    logger.WithCompress(true),
)

Single File Output
// Using functional options (recommended)
logger.Init(
    logger.WithLevel(logger.LevelInfo),
    logger.WithFileOutput("/var/log/myapp.log"),
    logger.WithMaxSize(50),
    logger.WithMaxAge(7),
    logger.WithMaxBackups(5),
    logger.WithCompress(false),
)

Development Mode
// Use zap's development config for human-readable output
// This is useful during local development
logger.Init(
    logger.WithLevel(logger.LevelDebug),
    logger.WithFormat(logger.FormatText),
    logger.WithDev(true),
)

// Or use the predefined development defaults
logger.Init(logger.WithDevelopmentDefaults())
Production Debug Mode
// Sometimes you need debug level in production for troubleshooting
// but still want structured JSON logs (not development format)
logger.Init(
    logger.WithLevel(logger.LevelDebug),
    logger.WithFormat(logger.FormatJSON),
    logger.WithDev(false), // Keep production format
)

// This gives you debug-level logs in production-friendly JSON format

Advanced Usage

Custom Logger Instance
// Create custom logger with functional options
log, err := logger.New(
    logger.WithLevel(logger.LevelDebug),
    logger.WithFormat(logger.FormatJSON),
)
if err != nil {
    log.Fatal("Failed to create logger", zap.Error(err))
}

// Use custom logger
log.Info("custom logger message")
log.Trace(ctx).Debug("debug with trace")

// Change log level dynamically
log.SetLevel(zapcore.ErrorLevel)
Context Integration

The logger automatically extracts tracing information from context:

OpenTelemetry
import "go.opentelemetry.io/otel/trace"

// OpenTelemetry trace context is automatically extracted
span := trace.SpanFromContext(ctx)
logger.Trace(ctx).Info("processing request") // Includes trace_id and span_id
Datadog
// Datadog trace context is automatically extracted
ctx := context.WithValue(context.Background(), "trace_id", "12345")
ctx = context.WithValue(ctx, "span_id", "67890")
logger.Trace(ctx).Info("processing request") // Includes dd.trace_id and dd.span_id
Custom Trace Fields
// Custom trace fields
ctx := context.WithValue(context.Background(), "trace_id", "custom-trace")
ctx = context.WithValue(ctx, "span_id", "custom-span")
logger.Trace(ctx).Info("processing request") // Includes trace_id and span_id
Functional Options

The logger supports functional configuration options for cleaner, more readable setup:

// Initialize with functional options
logger.Init(
    logger.WithLevel(logger.LevelDebug),
    logger.WithFormat(logger.FormatText),
    logger.WithDev(true), // Use development config
)

// Predefined option sets
logger.Init(logger.WithProductionDefaults())
logger.Init(logger.WithDevelopmentDefaults())

// Console output
logger.Init(logger.WithConsoleOutput())

// Text output
logger.Init(logger.WithTextOutput())

// File output with rotation
logger.Init(
    logger.WithFileOutput("/var/log/myapp"),
    logger.WithMaxSize(100),
    logger.WithMaxAge(30),
    logger.WithMaxBackups(3),
    logger.WithCompress(true),
)
Available Options
  • WithLevel(level string) - Set log level (debug, info, warn, error)
  • WithFormat(format string) - Set log format (json, text, file)
  • WithFilePath(path string) - Set file path or directory for logs
  • WithMaxSize(mb int) - Set max size in MB before rotation
  • WithMaxAge(days int) - Set max days to retain old logs
  • WithMaxBackups(n int) - Set max number of old log files
  • WithCompress(compress bool) - Enable/disable compression of rotated files
  • WithDev(isDev bool) - Use zap's development config for human-readable output
  • WithProductionDefaults() - Apply production-friendly defaults
  • WithDevelopmentDefaults() - Apply development-friendly defaults
  • WithConsoleOutput() - Configure JSON console output
  • WithTextOutput() - Configure text console output
  • WithFileOutput(path string) - Configure file output with rotation
Dynamic Level Changes
// Change log level at runtime
logger.Global().SetLevel(zapcore.DebugLevel)

// Check current level
level := logger.Global().GetLevel()
Child Loggers
// Create child logger with additional fields
childLogger := logger.With(
    zap.String("service", "api"),
    zap.String("version", "1.0.0"),
)

childLogger.Info("service event") // Includes service and version fields

Testing

// Use no-op logger for testing
testLogger := logger.NewNop()
testLogger.Info("this won't actually log anything")

// Or set global logger for tests
logger.SetGlobal(logger.NewNop())
logger.Info("test message") // Won't output anything

Constants

// Log levels
logger.LevelDebug
logger.LevelInfo
logger.LevelWarn
logger.LevelError

// Log formats
logger.FormatJSON
logger.FormatText
logger.FormatFile

Thread Safety

The logger is thread-safe and can be used concurrently from multiple goroutines. The global logger uses a read-write mutex for safe access.

Dependencies

  • go.uber.org/zap - Core logging functionality
  • gopkg.in/natefinch/lumberjack.v2 - Log rotation
  • go.opentelemetry.io/otel/trace - OpenTelemetry integration (already in your project)

Migration from fmt

Replace fmt calls with logger calls:

// Before
fmt.Print("message")
fmt.Println("message")
fmt.Printf("formatted: %s", value)

// After
logger.Print("message")
logger.Println("message")
logger.Printf("formatted: %s", value)

This provides structured logging with proper levels and formatting while maintaining the same API.

Documentation

Overview

Example

Example demonstrates basic usage of the logger package

// Initialize global logger with functional options
Init(
	WithLevel(LevelInfo),
	WithFormat(FormatJSON),
)

// Basic logging
Info("application started")
Debug("debug message", zap.String("key", "value"))

// Print functions (fmt replacement)
Print("simple message")
Println("message with newline")
Printf("formatted message: %s", "value")

// Level-specific printf functions
Debugf("debug: %d", 42)
Infof("info: %s", "information")
Warnf("warning: %s", "warning message")
Errorf("error: %s", "error message")

// Sugar logger
sugar := Sugar()
sugar.Infow("user action",
	"action", "login",
	"user_id", "123",
)

// Context with tracing
ctx := context.WithValue(context.Background(), traceIDKey, "12345")
ctxWithValue := context.WithValue(ctx, spanIDKey, "67890")

Trace(ctx).Info("processing request")
Trace(ctx).Warn("warning with trace", zap.Int("count", 5))

// Sugar with tracing
sugar.Trace(ctxWithValue).Infow("processing with trace",
	"request_id", "req-123",
)

Index

Examples

Constants

View Source
const (
	FormatJSON = "json"
	FormatText = "text"
	FormatFile = "file"
)

Log format constants

View Source
const (
	LevelDebug = "debug"
	LevelInfo  = "info"
	LevelWarn  = "warn"
	LevelError = "error"
)

Log level constants

Variables

This section is empty.

Functions

func Debug

func Debug(msg string, fields ...zap.Field)

func Debugf

func Debugf(format string, args ...interface{})

func Error

func Error(msg string, fields ...zap.Field)

func Errorf

func Errorf(format string, args ...interface{})

func ExtractTraceFields

func ExtractTraceFields(ctx context.Context) []zap.Field

ExtractTraceFields extracts tracing information from context for both Datadog and OpenTelemetry.

func Fatal

func Fatal(msg string, fields ...zap.Field)

func Fatalf

func Fatalf(format string, args ...interface{})

func Info

func Info(msg string, fields ...zap.Field)

func Infof

func Infof(format string, args ...interface{})

func Init

func Init(opts ...Option)

Init initializes the global logger with functional options. This should be called once at application startup.

func Panic

func Panic(msg string, fields ...zap.Field)

func Print

func Print(args ...interface{})

Package-level print functions

func Printf

func Printf(format string, args ...interface{})

func Println

func Println(args ...interface{})

func Warn

func Warn(msg string, fields ...zap.Field)

func Warnf

func Warnf(format string, args ...interface{})

Types

type Config

type Config struct {
	Level      string // debug, info, warn, error (default: info)
	Format     string // json, text, file (default: json)
	FilePath   string // file or directory path (only for file format)
	MaxSize    int    // max size in MB before rotation (default: 100)
	MaxAge     int    // max days to retain old logs (default: 30)
	MaxBackups int    // max number of old log files (default: 3)
	Compress   bool   // compress rotated files (default: false)
	IsDev      *bool  // use zap's development config for human-readable output (default: false)

	AtomicLevel zap.AtomicLevel // atomic level for dynamic level changes
}

Config defines the logger configuration.

func (Config) IsDevelopment

func (c Config) IsDevelopment() bool

type Logger

type Logger struct {
	*zap.Logger
}

Logger embeds zap.Logger to inherit all standard methods.

func GetLogger

func GetLogger() *Logger

GetLogger returns the global logger instance. It panics if the logger is not initialized.

func Trace

func Trace(ctx context.Context) *Logger

Trace extracts tracing fields from context using the global logger.

Example

ExampleTrace demonstrates tracing integration

// Context with OpenTelemetry-style trace
ctx := context.Background()
// In real usage, this would come from OpenTelemetry or Datadog

// Context with custom trace
ctx = context.WithValue(ctx, traceIDKey, "custom-trace-789")
ctx = context.WithValue(ctx, spanIDKey, "custom-span-012")

// All these will include trace information
Trace(ctx).Info("processing request")
Trace(ctx).Debug("debug with trace")
Trace(ctx).Error("error with trace")

func With

func With(fields ...zap.Field) *Logger

With creates a child logger with additional fields using the global logger.

func (*Logger) Debugf

func (l *Logger) Debugf(format string, args ...interface{})

func (*Logger) Errorf

func (l *Logger) Errorf(format string, args ...interface{})

func (*Logger) Fatalf

func (l *Logger) Fatalf(format string, args ...interface{})

func (*Logger) Infof

func (l *Logger) Infof(format string, args ...interface{})

func (*Logger) Print

func (l *Logger) Print(args ...interface{})

Print functions (fmt replacement)

func (*Logger) Printf

func (l *Logger) Printf(format string, args ...interface{})

func (*Logger) Println

func (l *Logger) Println(args ...interface{})

func (*Logger) Sugar

func (l *Logger) Sugar() *SugaredLogger

Sugar returns a SugaredLogger with tracing support.

func (*Logger) Trace

func (l *Logger) Trace(ctx context.Context) *Logger

Trace extracts tracing fields from context and returns a logger with those fields. Usage: logger.Trace(ctx).Info("processing request")

func (*Logger) Warnf

func (l *Logger) Warnf(format string, args ...interface{})

type Option

type Option func(*Config)

Option is a functional option for configuring the logger.

func WithCompress

func WithCompress(compress bool) Option

WithCompress enables compression of rotated files.

func WithConsoleOutput

func WithConsoleOutput() Option

WithConsoleOutput configures console output (JSON format).

func WithDebugLevel

func WithDebugLevel() Option

WithDebugLevel configures debug level logging.

func WithDev

func WithDev(isDev bool) Option

WithDev sets whether to use zap's development config for human-readable output.

func WithErrorLevel

func WithErrorLevel() Option

WithErrorLevel configures error level logging.

func WithFileOutput

func WithFileOutput(filePath string) Option

WithFileOutput configures file output with rotation.

func WithFilePath

func WithFilePath(filePath string) Option

WithFilePath sets the file path for file output.

func WithFormat

func WithFormat(format string) Option

WithFormat sets the log format.

func WithInfoLevel

func WithInfoLevel() Option

WithInfoLevel configures info level logging.

func WithLevel

func WithLevel(level string) Option

WithLevel sets the log level.

func WithMaxAge

func WithMaxAge(maxAge int) Option

WithMaxAge sets the maximum age in days to retain old logs.

func WithMaxBackups

func WithMaxBackups(maxBackups int) Option

WithMaxBackups sets the maximum number of old log files to retain.

func WithMaxSize

func WithMaxSize(maxSize int) Option

WithMaxSize sets the maximum size in MB before rotation.

func WithProductionDefaults

func WithProductionDefaults() Option

WithProductionDefaults sets production-ready defaults.

func WithTextOutput

func WithTextOutput() Option

WithTextOutput configures text output to console.

func WithWarnLevel

func WithWarnLevel() Option

WithWarnLevel configures warn level logging.

type SugaredLogger

type SugaredLogger struct {
	*zap.SugaredLogger
	// contains filtered or unexported fields
}

SugaredLogger embeds zap.SugaredLogger with tracing support.

func Sugar

func Sugar() *SugaredLogger

Sugar returns a sugared logger from the global logger.

func (*SugaredLogger) Trace

func (sl *SugaredLogger) Trace(ctx context.Context) *SugaredLogger

Trace extracts tracing fields from context and returns a sugared logger with those fields.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL