logger

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2025 License: Apache-2.0 Imports: 28 Imported by: 0

README

logger

A lightweight Go logger focused on:

  • stdout logging (JSON or text)
  • structured fields (WithField / WithFields)
  • optional OpenTelemetry export via OTLP/HTTP
    • traces: stable
    • logs: experimental (in OTel Go SDK) and implemented as best-effort

The package is designed to be safe by default:

  • stdout logging works regardless of OTel availability
  • OTel init/export/shutdown failures should not crash your application
  • Close(ctx) respects context cancellation/deadlines

Installation

go get github.com/mainhippo/logger@latest
go get github.com/mainhippo/logger@v0.3.0

Quick start

package main

import (
	"context"
	"time"

	"github.com/mainhippo/logger"
)

func main() {
	l := logger.New(logger.Config{
		Level:    logger.LevelInfo,
		Format:   logger.FormatJSON,
		Producer: "my-service",
	})
	defer func() {
		ctx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond)
		defer cancel()
		_ = l.Close(ctx)
	}()

	l.Info("hello")
	l.WithField("request_id", "req-123").Warn("slow request")
}

Structured fields

l := logger.New(logger.Config{Format: logger.FormatText})

l.WithFields(map[string]any{
	"component": "worker",
	"shard":     3,
}).Info("started")

Global default logger

If you prefer a global singleton:

logger.Init(logger.Config{
	Level:    logger.LevelInfo,
	Format:   logger.FormatText,
	Producer: "my-service",
})

logger.WithField("component", "http").Info("listening")

defer func() {
	ctx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond)
	defer cancel()
	_ = logger.Close(ctx)
}()

OpenTelemetry (OTLP/HTTP)

Configuration

Endpoint must be a base URL (without /v1/traces or /v1/logs).

cfg := logger.Config{
	Level:    logger.LevelInfo,
	Format:   logger.FormatJSON,
	Producer: "my-service",
	OTel: logger.OTelConfig{
		Enabled:      true,
		ExportTraces: true,
		ExportLogs:   true, // experimental
		Endpoint:     "http://localhost:4318",
		ServiceName:  "my-service",
		HostName:     "localhost",
		// Headers: map[string]string{"signoz-ingestion-key": "..."}, // SigNoz Cloud
	},
}

l := logger.New(cfg)

Notes:

  • OTel is enabled only when OTel.Enabled=true AND the corresponding export flag is true.
  • If Endpoint or ServiceName is empty (after trimming), OTel is automatically disabled (safe degrade).
Traces (spans)
ctx := context.Background()
ctx, span := l.StartSpan(ctx, "request")
defer span.End()

l.InfoCtx(ctx, "request started")

Use OTel.TracesProcessor to switch between BATCH (default) and SIMPLE export.

Logs export (experimental)

When ExportLogs=true, logs are exported best-effort via the OTel Logs SDK.

  • stdout is written first
  • OTel emit is performed after stdout write
  • exporter errors/panics are handled best-effort (stdout should keep working)
  • correlation logs↔traces is done via context.Context (TraceID/SpanID/TraceFlags)

Shutdown / flushing (Close(ctx))

Always call Close(ctx) on application shutdown to reduce loss of batched telemetry. Use a short timeout.

ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()

_ = l.Close(ctx)

If you use Fatal and need a best-effort flush before os.Exit(1), set OTel.FatalFlushTimeout in Config.

Examples

See ./examples:

  • examples/spans_text
  • examples/spans_json
  • examples/signoz_local (traces + logs)
  • examples/signoz_logs_simple (logs, simple processor)
  • examples/signoz_logs_batch (logs, batch processor)
  • examples/signoz_logs_fatal_flush (logs, batch + fatal flush)
  • examples/signoz_simple_full (logs + traces, simple processors)
  • examples/signoz_traces_simple (traces, simple processor)
  • examples/signoz_traces_fatal_flush (traces, batch + fatal flush)

License

Licensed under the Apache License, Version 2.0. See LICENSE.

What's new in v0.4.0

  • OpenTelemetry Logs export via OTLP/HTTP (feature-flagged and experimental in the OTel Go SDK, implemented as best-effort).
  • Logs are exported after a successful stdout write (stdout remains the primary and reliable sink).
  • OTel.ExportLogs flag and logs processor settings (OTel.LogsProcessor, OTel.LogsBatchTimeout, OTel.LogsBatchExportTimeout).
  • Trace correlation for exported logs via context.Context (TraceID/SpanID/TraceFlags when an active span is present).
  • Anti-recursion guard to prevent re-entrant logging during export.
  • Close(ctx) now shuts down both traces and logs providers (best-effort, respects ctx deadline/cancel), plus best-effort fatal flush via OTel.FatalFlushTimeout.
  • New SigNoz examples for logs/traces and extended test coverage for never-panic/never-hang semantics.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Close

func Close(ctx context.Context) error

func Debug

func Debug(msg string)

func DebugCtx

func DebugCtx(ctx context.Context, msg string)

func Error

func Error(msg string)

func ErrorCtx

func ErrorCtx(ctx context.Context, msg string)

func Fatal

func Fatal(msg string)

func FatalCtx

func FatalCtx(ctx context.Context, msg string)

func Info

func Info(msg string)

func InfoCtx

func InfoCtx(ctx context.Context, msg string)

func Init

func Init(cfg Config)

func SetDefault

func SetDefault(l *Logger)

func SetLevel

func SetLevel(level Level)

func Trace

func Trace(msg string)

func TraceCtx

func TraceCtx(ctx context.Context, msg string)

func Warn

func Warn(msg string)

func WarnCtx

func WarnCtx(ctx context.Context, msg string)

Types

type Config

type Config struct {
	Level        Level
	Format       Format
	Writer       io.Writer
	TimeLocation *time.Location
	Producer     any
	OTel         OTelConfig
}

type Format

type Format int8
const (
	FormatUnset Format = iota
	FormatText
	FormatJSON
)

func (Format) String

func (f Format) String() string

type Level

type Level int8
const (
	LevelUnset Level = iota
	LevelTrace
	LevelDebug
	LevelInfo
	LevelWarn
	LevelError
	LevelFatal
)

func GetLevel

func GetLevel() Level

func ParseLevel

func ParseLevel(s string) (Level, error)

func (Level) String

func (l Level) String() string

type Logger

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

func New

func New(cfg Config) *Logger

func WithField

func WithField(key string, val any) *Logger

func WithFields

func WithFields(fields map[string]any) *Logger

func (*Logger) Close

func (l *Logger) Close(ctx context.Context) error

func (*Logger) Debug

func (l *Logger) Debug(msg string)

func (*Logger) DebugCtx

func (l *Logger) DebugCtx(ctx context.Context, msg string)

func (*Logger) Error

func (l *Logger) Error(msg string)

func (*Logger) ErrorCtx

func (l *Logger) ErrorCtx(ctx context.Context, msg string)

func (*Logger) Fatal

func (l *Logger) Fatal(msg string)

func (*Logger) FatalCtx

func (l *Logger) FatalCtx(ctx context.Context, msg string)

func (*Logger) GetLevel

func (l *Logger) GetLevel() Level

func (*Logger) Info

func (l *Logger) Info(msg string)

func (*Logger) InfoCtx

func (l *Logger) InfoCtx(ctx context.Context, msg string)

func (*Logger) SetLevel

func (l *Logger) SetLevel(level Level)

func (*Logger) StartSpan

func (l *Logger) StartSpan(ctx context.Context, name string, fields ...SpanField) (context.Context, *Span)

func (*Logger) Trace

func (l *Logger) Trace(msg string)

func (*Logger) TraceCtx

func (l *Logger) TraceCtx(ctx context.Context, msg string)

func (*Logger) Warn

func (l *Logger) Warn(msg string)

func (*Logger) WarnCtx

func (l *Logger) WarnCtx(ctx context.Context, msg string)

func (*Logger) WithField

func (l *Logger) WithField(key string, val any) *Logger

func (*Logger) WithFields

func (l *Logger) WithFields(fields map[string]any) *Logger

type OTelConfig

type OTelConfig struct {
	Enabled                  bool
	Endpoint                 string
	Headers                  map[string]string
	ServiceName              string
	HostName                 string
	ExportTraces             bool
	ExportLogs               bool
	TracesProcessor          OTelTracesProcessor
	TracesBatchTimeout       time.Duration
	TracesBatchExportTimeout time.Duration
	TracesMaxQueueSize       int
	TracesMaxExportBatchSize int
	LogsProcessor            OTelLogsProcessor
	LogsBatchTimeout         time.Duration
	LogsBatchExportTimeout   time.Duration
	FatalFlushTimeout        time.Duration
}

type OTelLogsProcessor added in v0.4.0

type OTelLogsProcessor int8
const (
	OTelLogsProcessorUnset OTelLogsProcessor = iota
	OTelLogsProcessorBatch
	OTelLogsProcessorSimple
)

func (OTelLogsProcessor) String added in v0.4.0

func (p OTelLogsProcessor) String() string

type OTelTracesProcessor added in v0.4.0

type OTelTracesProcessor int8
const (
	OTelTracesProcessorUnset OTelTracesProcessor = iota
	OTelTracesProcessorBatch
	OTelTracesProcessorSimple
)

func (OTelTracesProcessor) String added in v0.4.0

func (p OTelTracesProcessor) String() string

type Span

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

func StartSpan

func StartSpan(ctx context.Context, name string, fields ...SpanField) (context.Context, *Span)

func (*Span) End

func (s *Span) End()

func (*Span) EndError

func (s *Span) EndError(err error)

type SpanField

type SpanField struct {
	Key   string
	Value any
}

Directories

Path Synopsis
signoz_local command
spans_json command
spans_text command

Jump to

Keyboard shortcuts

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