logger

package
v0.30.0 Latest Latest
Warning

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

Go to latest
Published: Mar 20, 2026 License: Apache-2.0 Imports: 5 Imported by: 1

README

Logger Package

A structured logging package built on top of uber-go/zap, providing both global and context-aware logging capabilities with sensible defaults and optional OpenTelemetry integration.

Features

  • Built on top of the high-performance zap logger
  • Supports both structured and printf-style logging
  • Context-aware logging
  • Global and instance-based logging
  • Configurable log levels and encoding formats
  • Request ID tracking support
  • OpenTelemetry integration for distributed tracing and observability
  • Easy integration with existing applications

Installation

go get -u github.com/zondax/golem/pkg/logger

Quick Start

// Initialize with default configuration
logger.InitLogger(logger.Config{
    Level:    "info",
    Encoding: "json",
})

// Basic logging
logger.Info("Server started")
logger.Error("Connection failed")

// Structured logging with fields
log := logger.NewLogger(
    logger.Field{Key: "service", Value: "api"},
    logger.Field{Key: "version", Value: "1.0.0"},
)
log.Info("Service initialized")

Configuration

Logger Config
type Config struct {
    Level         string                 `json:"level"`         // Logging level
    Encoding      string                 `json:"encoding"`      // Output format
    OpenTelemetry *OpenTelemetryConfig   `json:"opentelemetry"` // Optional OpenTelemetry config
}

type OpenTelemetryConfig struct {
    Enabled     bool              `json:"enabled"`      // Enable OpenTelemetry integration
    ServiceName string            `json:"service_name"` // Service name for telemetry
    Endpoint    string            `json:"endpoint"`     // OTLP endpoint URL
    Protocol    string            `json:"protocol"`     // Protocol: "http" or "grpc"
    Insecure    bool              `json:"insecure"`     // Use insecure connection
    Headers     map[string]string `json:"headers"`      // Additional headers
}
Log Levels

Available log levels (in order of increasing severity):

  • debug: Detailed information for debugging
  • info: General operational information
  • warn: Warning messages for potentially harmful situations
  • error: Error conditions that should be addressed
  • dpanic: Critical errors in development that cause panic
  • panic: Critical errors that cause panic in production
  • fatal: Fatal errors that terminate the program
Encoding Formats
  1. JSON Format (Default)

    • Recommended for production
    • Machine-readable structured output
    {"level":"INFO","ts":"2024-03-20T10:00:00.000Z","msg":"Server started","service":"api"}
    
  2. Console Format

    • Recommended for development
    • Human-readable output
    2024-03-20T10:00:00.000Z INFO Server started service=api
    

OpenTelemetry Integration

The logger package provides seamless integration with OpenTelemetry for distributed tracing and observability platforms like SigNoz, Jaeger, and others.

Basic OpenTelemetry Setup
import (
    "github.com/zondax/golem/pkg/logger"
    "github.com/zondax/golem/pkg/logger/otel"
)

// Register the OpenTelemetry provider
provider := otel.NewProvider()
logger.RegisterOpenTelemetryProvider(provider)

// Configure logger with OpenTelemetry
config := logger.Config{
    Level:    "info",
    Encoding: "json",
    OpenTelemetry: &logger.OpenTelemetryConfig{
        Enabled:     true,
        ServiceName: "my-service",
        Endpoint:    "http://localhost:4318", // OTLP HTTP endpoint
        Protocol:    "http",                  // or "grpc"
        Insecure:    true,                    // for development
        Headers: map[string]string{
            "Authorization": "Bearer your-token",
        },
    },
}

// Initialize logger - logs will be sent to both console and OpenTelemetry
logger.InitLogger(config)

// Use logger normally - logs automatically go to OpenTelemetry
logger.Info("Service started")
SigNoz Integration Example
config := logger.Config{
    Level:    "info",
    Encoding: "json",
    OpenTelemetry: &logger.OpenTelemetryConfig{
        Enabled:     true,
        ServiceName: "my-api-service",
        Endpoint:    "http://signoz-otel-collector:4318", // SigNoz OTLP endpoint
        Protocol:    "http",
        Insecure:    false,
        Headers: map[string]string{
            "signoz-access-token": "your-signoz-token",
        },
    },
}
Jaeger Integration Example
config := logger.Config{
    Level:    "info",
    Encoding: "json",
    OpenTelemetry: &logger.OpenTelemetryConfig{
        Enabled:     true,
        ServiceName: "my-service",
        Endpoint:    "http://jaeger-collector:14268", // Jaeger OTLP endpoint
        Protocol:    "http",
        Insecure:    true,
    },
}
gRPC Protocol Example
config := logger.Config{
    Level:    "info",
    Encoding: "json",
    OpenTelemetry: &logger.OpenTelemetryConfig{
        Enabled:     true,
        ServiceName: "grpc-service",
        Endpoint:    "localhost:4317", // OTLP gRPC endpoint
        Protocol:    "grpc",
        Insecure:    true,
    },
}
Graceful Shutdown
import "context"

// Ensure proper cleanup of OpenTelemetry resources
defer func() {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    if err := logger.ShutdownOpenTelemetryLogger(ctx); err != nil {
        log.Printf("Error shutting down OpenTelemetry logger: %v", err)
    }
}()

Advanced Usage

Context-Aware Logging
// Create a context with logger
ctx := context.Background()
log := logger.NewLogger(logger.Field{
    Key: logger.RequestIDKey,
    Value: "req-123",
})
ctx = logger.ContextWithLogger(ctx, log)

// Get logger from context
contextLogger := logger.GetLoggerFromContext(ctx)
contextLogger.Info("Processing request")
Structured Logging with Fields
log := logger.NewLogger()
log.WithFields(
    zap.String("user_id", "12345"),
    zap.String("action", "login"),
    zap.Int("attempt", 1),
).Info("User login attempt")
Printf-Style Logging
logger.Infof("Processing item %d of %d", current, total)
logger.Errorf("Failed to connect to %s: %v", host, err)

Best Practices

  1. Use Structured Logging

    // Good
    log.WithFields(
        zap.String("user_id", "12345"),
        zap.String("action", "purchase"),
        zap.Float64("amount", 99.99),
    ).Info("Purchase completed")
    
    // Avoid
    log.Infof("User %s completed purchase of $%.2f", userID, amount)
    
  2. Include Request IDs

    log.WithFields(
        zap.String(logger.RequestIDKey, requestID),
    ).Info("Handling request")
    
  3. Proper Error Logging

    if err != nil {
        log.WithFields(
            zap.Error(err),
            zap.String("operation", "database_query"),
        ).Error("Query failed")
    }
    
  4. Resource Cleanup

    defer logger.Sync()
    
    // For OpenTelemetry integration
    defer func() {
        ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
        defer cancel()
        logger.ShutdownOpenTelemetryLogger(ctx)
    }()
    
  5. OpenTelemetry Best Practices

    • Always set a meaningful ServiceName for better observability
    • Use appropriate protocol (http vs grpc) based on your infrastructure
    • Include authentication headers when required by your observability platform
    • Handle shutdown gracefully to ensure all logs are flushed
    • Test connectivity to your OpenTelemetry endpoint before production deployment

Configuration Examples

Development Configuration
# config.yaml
logger:
  level: "debug"
  encoding: "console"
  opentelemetry:
    enabled: true
    service_name: "my-service-dev"
    endpoint: "http://localhost:4318"
    protocol: "http"
    insecure: true
Production Configuration
# config.yaml
logger:
  level: "info"
  encoding: "json"
  opentelemetry:
    enabled: true
    service_name: "my-service-prod"
    endpoint: "https://otel-collector.company.com:4318"
    protocol: "http"
    insecure: false
    headers:
      authorization: "Bearer your-token-here"
      x-api-key: "your-api-key-here"

Performance Considerations

  • The logger is designed to be zero-allocation in most cases
  • JSON encoding is more CPU-intensive but provides structured data
  • Log level checks are performed atomically
  • Field allocation is optimized for minimal overhead
  • OpenTelemetry integration adds minimal overhead when properly configured
  • Batch processing is used for OpenTelemetry exports to optimize performance

Thread Safety

The logger is completely thread-safe and can be used concurrently from multiple goroutines. The OpenTelemetry integration maintains thread safety through proper synchronization mechanisms.

Documentation

Index

Constants

View Source
const (
	ConsoleEncode = "console"
)
View Source
const (
	RequestIDKey = "request_id"
)

Variables

This section is empty.

Functions

func ContextWithLogger

func ContextWithLogger(ctx context.Context, logger *Logger) context.Context

func DPanic added in v0.19.2

func DPanic(msg string)

func DPanicf added in v0.19.2

func DPanicf(template string, args ...interface{})

func Debug added in v0.19.2

func Debug(msg string)

func Debugf added in v0.19.2

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

func Error added in v0.19.2

func Error(msg string)

func Errorf added in v0.19.2

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

func Fatal added in v0.19.2

func Fatal(msg string)

func Fatalf added in v0.19.2

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

func Info added in v0.19.2

func Info(msg string)

func Infof added in v0.19.2

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

func InitLogger

func InitLogger(config Config)

func IsOpenTelemetryActive added in v0.23.0

func IsOpenTelemetryActive() bool

IsOpenTelemetryActive checks if OpenTelemetry is currently active and working

func L added in v0.19.2

func L() *zap.Logger

func Panic added in v0.19.2

func Panic(msg string)

func Panicf added in v0.19.2

func Panicf(template string, args ...interface{})

func RegisterOpenTelemetryProvider added in v0.23.0

func RegisterOpenTelemetryProvider(provider OpenTelemetryProvider)

RegisterOpenTelemetryProvider allows external packages to register OpenTelemetry implementation

func ReplaceGlobals added in v0.19.2

func ReplaceGlobals(logger *zap.Logger) func()

func S added in v0.19.2

func S() *zap.SugaredLogger

func SetGlobalConfig added in v0.19.2

func SetGlobalConfig(config Config) func()

func ShutdownOpenTelemetryLogger added in v0.23.0

func ShutdownOpenTelemetryLogger(ctx context.Context) error

ShutdownOpenTelemetryLogger gracefully shuts down the OpenTelemetry logger

func Sync

func Sync() error

func Warn added in v0.19.2

func Warn(msg string)

func Warnf added in v0.19.2

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

Types

type Config

type Config struct {
	Level         string               `json:"level"`
	Encoding      string               `json:"encoding"`
	OpenTelemetry *OpenTelemetryConfig `json:"opentelemetry,omitempty"`
}

type Field

type Field struct {
	Key   string
	Value interface{}
}

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

func GetLoggerFromContext

func GetLoggerFromContext(ctx context.Context) *Logger

func NewDevelopmentLogger added in v0.20.0

func NewDevelopmentLogger(fields ...Field) *Logger

func NewLogger

func NewLogger(opts ...interface{}) *Logger

func NewNopLogger added in v0.20.0

func NewNopLogger() *Logger

func (*Logger) DPanic

func (l *Logger) DPanic(msg string)

func (*Logger) DPanicf

func (l *Logger) DPanicf(template string, args ...interface{})

func (*Logger) Debug

func (l *Logger) Debug(msg string)

func (*Logger) Debugf

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

func (*Logger) Error

func (l *Logger) Error(msg string)

func (*Logger) Errorf

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

func (*Logger) Fatal

func (l *Logger) Fatal(msg string)

func (*Logger) Fatalf

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

func (*Logger) GetZapLogger added in v0.23.0

func (l *Logger) GetZapLogger() *zap.Logger

GetZapLogger returns the underlying zap.Logger instance This method is primarily intended for testing and advanced use cases

func (*Logger) Info

func (l *Logger) Info(msg string)

func (*Logger) Infof

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

func (*Logger) IsDebugEnabled added in v0.15.1

func (l *Logger) IsDebugEnabled() bool

func (*Logger) Panic

func (l *Logger) Panic(msg string)

func (*Logger) Panicf

func (l *Logger) Panicf(template string, args ...interface{})

func (*Logger) Warn

func (l *Logger) Warn(msg string)

func (*Logger) Warnf

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

func (*Logger) WithFields

func (l *Logger) WithFields(fields ...zap.Field) *Logger

type OpenTelemetryConfig added in v0.23.0

type OpenTelemetryConfig struct {
	Enabled        bool              `json:"enabled" yaml:"enabled" mapstructure:"enabled"`
	Endpoint       string            `json:"endpoint" yaml:"endpoint" mapstructure:"endpoint"`
	ServiceName    string            `json:"service_name" yaml:"service_name" mapstructure:"service_name"`
	ServiceVersion string            `json:"service_version,omitempty" yaml:"service_version,omitempty" mapstructure:"service_version,omitempty"`
	Environment    string            `json:"environment,omitempty" yaml:"environment,omitempty" mapstructure:"environment,omitempty"`
	Hostname       string            `json:"hostname,omitempty" yaml:"hostname,omitempty" mapstructure:"hostname,omitempty"`
	Headers        map[string]string `json:"headers,omitempty" yaml:"headers,omitempty" mapstructure:"headers,omitempty"`
	Insecure       bool              `json:"insecure,omitempty" yaml:"insecure,omitempty" mapstructure:"insecure,omitempty"`
	Protocol       string            `json:"protocol,omitempty" yaml:"protocol,omitempty" mapstructure:"protocol,omitempty"` // "grpc" or "http"
}

OpenTelemetryConfig holds OpenTelemetry logging configuration

type OpenTelemetryManager added in v0.23.0

type OpenTelemetryManager struct {
	// contains filtered or unexported fields
}

OpenTelemetryManager manages OpenTelemetry providers in a thread-safe way

type OpenTelemetryProvider added in v0.23.0

type OpenTelemetryProvider interface {
	CreateLogger(config Config, standardLogger *zap.Logger) (*zap.Logger, error)
	Shutdown(ctx context.Context) error
}

OpenTelemetryProvider interface for clean abstraction

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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