Observability toolkit for Go applications: structured logging with automatic rotation + OpenTelemetry instrumentation.
📖 Complete Documentation

go get github.com/weka/go-weka-observabilityIf you're seeing deprecation warnings for GetLoggerForContext, SetupOTelSDK, GetLogSpan, or NewZeroLogger, you're using the old API.
Quick migration examples:
// OLD (deprecated)
ctx, logger := instrumentation.GetLoggerForContext(ctx, nil, name)
shutdownFn, err := instrumentation.SetupOTelSDK(ctx, name, version, logger)
// NEW (recommended - SetupOTelSDK first, then ContextWithLogr)
logr := logger.CreateLogger(logger.WithInfoLevel())
shutdownFn, err := instrumentation.SetupOTelSDKWithOptions(ctx, name, version, logr)
ctx = logger.ContextWithLogr(ctx, logr) // Must be before CreateLogSpan, order with SetupOTelSDK doesn't matter// OLD (deprecated)
ctx, logger, end := instrumentation.GetLogSpan(ctx, "operation")
defer end()
// NEW - Choose based on your use case:
// 1. Creating owned spans with key-value pairs (most common)
ctx, logger := instrumentation.CreateLogSpan(ctx, "operation", "key", "value")
defer logger.End()
// 2. Type-safe span creation with OpenTelemetry options (RECOMMENDED: use WithValues for attributes)
ctx, logger := instrumentation.CreateLogSpanWithOptions(ctx, "database-query",
trace.WithSpanKind(trace.SpanKindClient),
)
// Add attributes to BOTH logger and span
ctx, logger = logger.WithValues(
"db.system", "postgresql",
"db.statement", "SELECT * FROM users",
)
defer logger.End() // Recommended: defer after enrichment
// 3. Convenience functions for common span kinds (with optional key-value pairs)
ctx, logger := instrumentation.CreateClientLogSpan(ctx, "http-request",
"http.url", "https://api.example.com",
"http.method", "GET",
)
defer logger.End() // Recommended: defer after enrichment
// 4. Logging under current span (helper functions)
view := instrumentation.CurrentSpanLogger(ctx)
view.Info("Helper logging")
// No End() call - compile-time safety!
// 5. Independent traces (background jobs)
ctx, logger := instrumentation.CreateRootLogSpan(ctx, "background-job", "job_id", "123")
defer logger.End()📖 Complete Migration Guide - Covers all migration scenarios including:
GetLoggerForContext→CreateLogger+ContextWithLogrmigrationGetLogSpan→CreateLogSpan/CurrentSpanLogger/CreateRootLogSpanmigration (see examples)zerologr.New()pattern migration- Custom formatting and file logging
LogrFromContextOrDefaultfor flexible logger retrieval- Complete API reference table
Note: All logger creation methods automatically respect environment variables (LOG_MODE, LOG_LEVEL, LOG_FORMAT, etc.) following the 12-factor app pattern. Environment variables always override code defaults.
import "github.com/weka/go-weka-observability/logger"
// Creates default logger: console sink, JSON format, info level
// Override via env: LOG_MODE=file LOG_LEVEL=0 LOG_FORMAT=raw
logr := logger.CreateLogger()
logr.Info("Application started")// File logger with automatic rotation (overrideable via LOG_* env vars)
logr := logger.CreateLogger(
logger.WithFileSink("/var/log", "app.log"),
logger.WithRotation(100, 5, 28), // 100MB, 5 files, 28 days
)
// Override via env: LOG_MODE=console to switch to stderr// Set explicit defaults (still overrideable via LOG_* env vars)
logr := logger.CreateLogger(
logger.WithConsoleSink(),
logger.WithInfoLevel(),
logger.WithJSONFormat(),
)
ctx = logger.ContextWithLogr(ctx, logr)
// Use logger
logger := logger.MustLogrFromContext(ctx)
logger.Info("Operation started")import (
"github.com/weka/go-weka-observability/instrumentation"
"github.com/weka/go-weka-observability/logger"
)
// Initialize logger (overrideable via LOG_* env vars)
logr := logger.CreateLogger(
logger.WithConsoleSink(),
logger.WithInfoLevel(),
)
// Setup OpenTelemetry (OTEL_EXPORTER_OTLP_ENDPOINT env var can override)
shutdownFn, err := instrumentation.SetupOTelSDKWithOptions(
ctx, "my-service", "v1.0.0", logr,
instrumentation.WithDefaultOTLPEndpoint("http://otel-collector:4317"),
)
if err != nil {
panic(err)
}
defer shutdownFn(ctx)
// Store logger in context (can also be done before SetupOTelSDK)
ctx = logger.ContextWithLogr(ctx, logr)
// Create traced operations with automatic logging
// Multiple API functions for different span ownership patterns:
// 1. CreateLogSpan - Create child span with key-value pairs (simple, recommended for most cases)
ctx, spanLogger := instrumentation.CreateLogSpan(ctx, "operation-name", "key", "value")
defer spanLogger.End() // Required!
spanLogger.Info("Operation in progress")
// 2. CreateLogSpanWithOptions - Type-safe span creation (RECOMMENDED: use WithValues for attributes)
import "go.opentelemetry.io/otel/trace"
ctx, dbLogger := instrumentation.CreateLogSpanWithOptions(ctx, "database-query",
trace.WithSpanKind(trace.SpanKindClient),
)
defer dbLogger.End() // Required!
// Add attributes to BOTH logger and span
ctx, dbLogger = dbLogger.WithValues(
"db.system", "postgresql",
"db.name", "users_db",
)
dbLogger.Info("Executing database query")
// 3. Convenience functions for common span kinds (with optional key-value pairs)
ctx, httpLogger := instrumentation.CreateClientLogSpan(ctx, "http-api-call",
"http.method", "GET",
"http.url", "https://api.example.com/users",
)
defer httpLogger.End()
httpLogger.Info("Making HTTP request")
// 4. CurrentSpanLogger - Borrow current span (no End call, no new span)
view := instrumentation.CurrentSpanLogger(ctx)
view.Info("Helper function logging") // Cannot call view.End() - compile error!
// 5. CreateRootLogSpan - Start independent trace (new trace ID)
ctx, rootLogger := instrumentation.CreateRootLogSpan(ctx, "background-job", "job_id", "123")
defer rootLogger.End() // Required!
rootLogger.Info("Background job with independent trace")
// 6. Advanced: Direct tracer access (for OTel library integration)
tracer := instrumentation.GetTracer(ctx)
ctx, span := tracer.Start(ctx, "custom-operation")
defer span.End()
// Note: No SpanLogger integration - manual span management- Logger Configuration API - Complete configuration guide, use cases, environment variables, best practices, troubleshooting
- Migration Guide - Upgrade from deprecated
GetLoggerForContextAPI
- Instrumentation Configuration API - Complete tracing configuration guide, usage patterns, environment variables, best practices
- SpanLogger API - Complete guide to type-safe span creation with OpenTelemetry options, convenience functions, and SpanLogger integration
- Trace Management - Smart tracer resolution system, provider detection, context-based injection, and testing strategies
- Versioning Strategy - Library versioning, OpenTelemetry instrumentation scope, CI/CD release process
- Examples - Runnable code examples demonstrating common patterns
Important: All logger creation methods (CreateLogger(), CreateLoggerFrom()) automatically apply environment variable overrides. You can set application defaults in code, and users can override them via environment variables at runtime.
All environment variables are optional and override code defaults:
| Variable | Default | Description |
|---|---|---|
LOG_MODE |
console |
Output mode: console or file |
LOG_DIR |
/var/log |
Log directory (file mode only) |
LOG_FILE_NAME |
- | Log file name (file mode only) |
LOG_MAX_SIZE_MB |
100 |
Max file size before rotation (MB) |
LOG_MAX_FILES |
5 |
Max number of backup files |
LOG_MAX_AGE_DAYS |
28 |
Max age for log retention (days) |
LOG_LEVEL |
1 (info) |
Minimum log level (-1=trace, 0=debug, 1=info, 2=warn, 3=error) |
LOG_FORMAT |
json |
Output format: json, raw, plain |
LOG_TIME_ONLY |
false |
Use time-only format instead of full timestamp |
LOG_CALLER_DIR_LVL |
-1 |
Number of directory levels in caller field (-1=disabled) |
| Variable | Default | Description |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
- | OTLP collector endpoint (e.g., http://localhost:4317) |
Note: WithDefaultOTLPEndpoint() sets a code default that OTEL_EXPORTER_OTLP_ENDPOINT can override.
See Logger Configuration Guide and Instrumentation Configuration Guide for complete details.
- Structured Logging: Zero-allocation JSON logging via zerolog
- Automatic Rotation: File rotation with lumberjack
- Environment-Aware: 12-factor app configuration via environment variables
- Context Management: Logger propagation through context
- Flexible Configuration: Functional options + struct-based config
- OpenTelemetry Integration: Automatic span creation with logger injection
- Multi-Level Files: Separate files for info and error logs