logger

package
v0.0.0-...-073742b Latest Latest
Warning

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

Go to latest
Published: May 12, 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

func DPanic(msg string)

func DPanicf

func DPanicf(template string, args ...any)

func Debug

func Debug(msg string)

func Debugf

func Debugf(template string, args ...any)

func Error

func Error(msg string)

func Errorf

func Errorf(template string, args ...any)

func Fatal

func Fatal(msg string)

func Fatalf

func Fatalf(template string, args ...any)

func Info

func Info(msg string)

func Infof

func Infof(template string, args ...any)

func InitLogger

func InitLogger(config Config)

func IsOpenTelemetryActive

func IsOpenTelemetryActive() bool

IsOpenTelemetryActive checks if OpenTelemetry is currently active and working

func L

func L() *zap.Logger

func Panic

func Panic(msg string)

func Panicf

func Panicf(template string, args ...any)

func RegisterOpenTelemetryProvider

func RegisterOpenTelemetryProvider(provider OpenTelemetryProvider)

RegisterOpenTelemetryProvider allows external packages to register OpenTelemetry implementation

func ReplaceGlobals

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

func S

func S() *zap.SugaredLogger

func SetGlobalConfig

func SetGlobalConfig(config Config) func()

func ShutdownOpenTelemetryLogger

func ShutdownOpenTelemetryLogger(ctx context.Context) error

ShutdownOpenTelemetryLogger gracefully shuts down the OpenTelemetry logger

func Sync

func Sync() error

func Warn

func Warn(msg string)

func Warnf

func Warnf(template string, args ...any)

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 any
}

type Logger

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

func GetLoggerFromContext

func GetLoggerFromContext(ctx context.Context) *Logger

func NewDevelopmentLogger

func NewDevelopmentLogger(fields ...Field) *Logger

func NewLogger

func NewLogger(opts ...any) *Logger

func NewNopLogger

func NewNopLogger() *Logger

func (*Logger) DPanic

func (l *Logger) DPanic(msg string)

func (*Logger) DPanicf

func (l *Logger) DPanicf(template string, args ...any)

func (*Logger) Debug

func (l *Logger) Debug(msg string)

func (*Logger) Debugf

func (l *Logger) Debugf(template string, args ...any)

func (*Logger) Error

func (l *Logger) Error(msg string)

func (*Logger) Errorf

func (l *Logger) Errorf(template string, args ...any)

func (*Logger) Fatal

func (l *Logger) Fatal(msg string)

func (*Logger) Fatalf

func (l *Logger) Fatalf(template string, args ...any)

func (*Logger) GetZapLogger

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 ...any)

func (*Logger) IsDebugEnabled

func (l *Logger) IsDebugEnabled() bool

func (*Logger) Panic

func (l *Logger) Panic(msg string)

func (*Logger) Panicf

func (l *Logger) Panicf(template string, args ...any)

func (*Logger) Warn

func (l *Logger) Warn(msg string)

func (*Logger) Warnf

func (l *Logger) Warnf(template string, args ...any)

func (*Logger) WithFields

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

type OpenTelemetryConfig

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

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

OpenTelemetryManager manages OpenTelemetry providers in a thread-safe way

type OpenTelemetryProvider

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