log

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 7 Imported by: 0

README

go-log 🪵

Tiny structured logging for Go services on zerolog, with OpenTelemetry trace_id/span_id correlation baked in.

📦 Install

go get github.com/Bugs5382/go-log

🚀 Usage

logger := log.New("my-service")
logger.Info().Msg("started")

// Inside a request/span, correlate logs with the active trace:
l := log.Ctx(ctx)
l.Info().Msg("handling request")

New writes JSON to stdout with a timestamp and a service field. Ctx derives a logger that adds trace_id and span_id from the active OpenTelemetry span, pairing with go-otel. 🔗

Neutral Logger (no zerolog dependency)

New and Ctx above return a concrete zerolog.Logger, so a wrapper package that holds one is forced to import github.com/rs/zerolog just to type the variable. NewLogger and LoggerFromContext return the neutral Logger interface instead: no zerolog type appears in any of its method signatures, so a consumer can depend on it (or an interface shaped like it) without ever importing zerolog. zerolog stays an internal implementation detail behind this path -- LOG_LEVEL, LOG_FORMAT, and OpenTelemetry trace correlation all behave exactly as they do for New/Ctx.

var logger log.Logger = log.NewLogger("my-service")
logger.Info("started", log.F("port", 8080))

child := logger.With(log.F("request_id", reqID))
child.Warn("slow downstream call", log.F("elapsed_ms", 420))
child.Error(err, "request failed")

// Inside a request/span, correlate logs with the active trace:
l := log.LoggerFromContext(ctx)
l.Info("handling request")

Logger covers Debug/Info/Warn/Error/Fatal with structured Fields (build one with log.F(key, val)), a With(fields...) Logger for child loggers, and a Ctx(ctx) Logger method mirroring the package-level Ctx. New/Ctx are unchanged and continue to work side by side with the neutral path.

🛠 Develop

task build    # go build ./...
task test     # go test ./...
task lint     # gofmt check + golangci-lint + yamllint
task license  # inject MIT headers (golic)

⚖️ License

MIT © 2026 Shane

Documentation

Overview

Package log provides zerolog-based structured logging for Go services, with OpenTelemetry trace_id/span_id correlation drawn from the active span context.

New and Ctx return a concrete zerolog.Logger for callers that already depend on zerolog. NewLogger and LoggerFromContext return the neutral Logger interface instead: no zerolog type appears in its method signatures, so a consumer can wrap or depend on it without importing zerolog directly. Both paths honor the same LOG_LEVEL/LOG_FORMAT environment controls and the same trace correlation; zerolog stays an internal implementation detail behind the neutral path.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Ctx

func Ctx(ctx context.Context) zerolog.Logger

Ctx returns a zerolog.Logger derived from the base logger with the active span's trace_id and span_id attached when ctx carries a valid span. This lets every log line be correlated with its trace in the tracing backend. When no valid span is present, it returns the plain base logger.

func New

func New(service string) zerolog.Logger

New returns a zerolog.Logger with a timestamp and the given service name attached to every line, filtered to the level from LOG_LEVEL (default info) and rendered per LOG_FORMAT (JSON by default, console/pretty for dev). Consumers no longer need to parse LOG_LEVEL or wire a writer themselves -- calling New is enough.

Types

type Field added in v1.2.0

type Field struct {
	Key string
	Val any
}

Field is a structured key/value pair attached to a Logger call. Build one with F, or construct it directly since both fields are exported.

func F added in v1.2.0

func F(key string, val any) Field

F builds a Field for a neutral Logger call, e.g. log.F("order_id", id).

type Logger added in v1.2.0

type Logger interface {
	// Debug logs msg at debug level with the given structured fields.
	Debug(msg string, fields ...Field)
	// Info logs msg at info level with the given structured fields.
	Info(msg string, fields ...Field)
	// Warn logs msg at warn level with the given structured fields.
	Warn(msg string, fields ...Field)
	// Error logs msg at error level, attaching err, with the given
	// structured fields.
	Error(err error, msg string, fields ...Field)
	// Fatal logs msg at fatal level, attaching err, with the given
	// structured fields, then terminates the process with a non-zero exit
	// code.
	Fatal(err error, msg string, fields ...Field)
	// With returns a child Logger that carries fields on every subsequent
	// line, in addition to whatever the receiver already carries.
	With(fields ...Field) Logger
	// Ctx returns a Logger correlated with the trace/span carried by ctx,
	// the neutral equivalent of the package-level Ctx function. Like Ctx, it
	// rebuilds from the service's base logger rather than the receiver, so
	// fields added via With are not carried over -- call With after Ctx if
	// both are needed.
	Ctx(ctx context.Context) Logger
}

Logger is the neutral logging surface: no zerolog type appears in any method signature here, so a consumer can depend on this interface alone and never import zerolog directly. zerolog remains an internal implementation detail behind it. New/Ctx (which do return a concrete zerolog.Logger) are unchanged and continue to work side by side with this interface.

Example

ExampleLogger shows the neutral surface: a consumer only needs the Logger interface, F, NewLogger, and LoggerFromContext -- zerolog is never imported or referenced.

package main

import (
	"context"
	"errors"

	log "github.com/Bugs5382/go-log"
)

func main() {
	logger := log.NewLogger("billing")

	logger.Info("service started", log.F("port", 8080))

	child := logger.With(log.F("request_id", "r-123"))
	child.Warn("slow downstream call", log.F("elapsed_ms", 420))

	err := errors.New("payment gateway timeout")
	child.Error(err, "request failed")

	// Inside a request/span, correlate logs with the active trace without
	// ever touching a zerolog type.
	ctx := context.Background()
	log.LoggerFromContext(ctx).Info("handling request")
}

func LoggerFromContext added in v1.2.0

func LoggerFromContext(ctx context.Context) Logger

LoggerFromContext returns a neutral Logger correlated with the trace/span carried by ctx -- the neutral equivalent of Ctx.

func NewLogger added in v1.2.0

func NewLogger(service string) Logger

NewLogger returns a neutral Logger for a service, honoring LOG_LEVEL and LOG_FORMAT exactly like New. Use this when the caller must not import zerolog directly; use New when a concrete zerolog.Logger is wanted instead.

Jump to

Keyboard shortcuts

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