logz

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2026 License: MIT Imports: 5 Imported by: 0

README

logz

A structured logging library for Go that wraps log/slog with a consistent interface, context propagation, and rich error integration. Designed as a Level 0 dependency — no internal imports, no global state, fully testable via constructor injection.

Features

  • Structured logging via log/slog (JSON or text output)
  • Constructor injection — no global singleton, no init() side effects
  • Context propagation: request IDs and arbitrary fields via context.Context
  • Rich error logging: LogError extracts code and context from apperr.AppErr-style errors via duck typing
  • Level 0 dependency — imports only the standard library

Installation

go get code.nochebuena.dev/go/logz

Quick start

import "code.nochebuena.dev/go/logz"

func main() {
    // Configured from LOG_LEVEL and LOG_JSON_OUTPUT environment variables
    logger := logz.NewFromEnv("service", "my-app")

    logger.Info("application started", "port", 8080)
    logger.Warn("disk space reaching threshold", "usage_pct", 85)
}

Constructors

// New creates a Logger from any slog.Handler.
// staticArgs are permanent key-value fields added to every log entry.
logger := logz.New(slog.NewJSONHandler(os.Stdout, nil), "service", "my-app")

// NewFromEnv reads LOG_LEVEL and LOG_JSON_OUTPUT from the environment.
logger := logz.NewFromEnv("service", "my-app")

Environment variables

Variable Values Default
LOG_LEVEL DEBUG, INFO, WARN, ERROR INFO
LOG_JSON_OUTPUT true / 1 text format

Logger interface

Use the Logger interface as the type in your structs and function signatures. This makes components testable by swapping in a mock without touching os.Stdout.

type Logger interface {
    Debug(msg string, args ...any)
    Info(msg string, args ...any)
    Warn(msg string, args ...any)
    Error(msg string, err error, args ...any)
    LogError(msg string, err error, args ...any)
    With(args ...any) Logger
    WithContext(ctx context.Context) Logger
}

Context propagation

Store request IDs and arbitrary fields in a context.Context, then materialize them onto a logger with WithContext.

// Store values in context (e.g. in HTTP middleware)
ctx = logz.WithRequestID(ctx, requestID)
ctx = logz.WithField(ctx, "tenant_id", tenantID)
ctx = logz.WithFields(ctx, map[string]any{"region": "us-east-1", "env": "prod"})

// Retrieve request ID
id := logz.GetRequestID(ctx)

// Create a new logger that includes all context values
log := logger.WithContext(ctx)
log.Info("handling request") // emits request_id, tenant_id, region, env

WithContext returns a new Logger instance; the original is unchanged.

Error logging

Error attaches any error as a structured field:

logger.Error("query failed", err, "table", "users")

LogError additionally extracts error_code and context fields from errors that implement the apperr.AppErr interface (GetCode() string, GetContext() map[string]any). For plain errors it behaves identically to Error.

if err := processData(ctx); err != nil {
    logger.LogError("data processing failed", err)
}

Fatal

Fatal is a package-level function rather than an interface method, so Logger mocks in tests do not need to call os.Exit.

if err := db.Connect(); err != nil {
    logz.Fatal(logger, "cannot connect to database", err)
}

Architecture

This library is a Level 0 dependency — it imports no other internal packages, so it can be used anywhere in a larger monorepo without risk of circular imports.

There is no global logger and no MustInit. Callers create a Logger via New or NewFromEnv and pass it through constructor injection. This keeps the library side-effect free and makes consuming code testable.

License

This project is licensed under the MIT License. See the LICENSE file for the full license text.

Documentation

Overview

Package logz provides a flexible and structured logging utility for Go applications.

It wraps the standard library's slog package to provide a consistent interface (Logger) that supports different log levels, structured data, context-aware logging, and integration with custom error types like apperr.AppErr.

Example usage:

logz.MustInit()
logger := logz.Global()

logger.Info("logz: iniciando aplicación", "version", "1.0.0")

if err != nil {
	logger.LogError("logz: fallo al procesar petición", err)
}

Index

Constants

View Source
const (
	// EnvLogLevel is the environment variable to set the minimum log level (e.g., DEBUG, INFO, WARN, ERROR).
	EnvLogLevel = "LOG_LEVEL"
	// EnvLogJSON is the environment variable to enable JSON output (set to "true" or "1").
	EnvLogJSON = "LOG_JSON_OUTPUT"
)

Variables

This section is empty.

Functions

func Fatal added in v1.0.0

func Fatal(logger Logger, msg string, err error, args ...any)

Fatal logs at ERROR level and exits the process with code 1. It is a package-level function rather than an interface method so that Logger implementations (e.g. test mocks) do not need to call os.Exit.

func GetRequestID

func GetRequestID(ctx context.Context) string

GetRequestID retrieves the correlation ID from the context, if present.

func WithField

func WithField(ctx context.Context, key string, value any) context.Context

WithField adds a single key-value pair to the context for logging.

func WithFields

func WithFields(ctx context.Context, fields map[string]any) context.Context

WithFields adds multiple key-value pairs to the context for logging.

func WithRequestID

func WithRequestID(ctx context.Context, id string) context.Context

WithRequestID adds a correlation ID to the context.

Types

type Logger

type Logger interface {
	// Debug logs a message at DEBUG level.
	Debug(msg string, args ...any)
	// Info logs a message at INFO level.
	Info(msg string, args ...any)
	// Warn logs a message at WARN level.
	Warn(msg string, args ...any)
	// Error logs a message at ERROR level with an attached error.
	Error(msg string, err error, args ...any)
	// LogError logs an error, automatically extracting code and context if it's an apperr.AppErr.
	LogError(msg string, err error, args ...any)
	// With returns a new Logger with the given attributes.
	With(args ...any) Logger
	// WithContext returns a new Logger that includes values from the context.
	WithContext(ctx context.Context) Logger
}

Logger defines the interface for our application logging.

func New

func New(handler slog.Handler, staticArgs ...any) Logger

New creates a new Logger from the given slog.Handler. staticArgs are added as permanent fields on every log entry. This is the primary constructor — prefer constructor injection over the global singleton pattern.

func NewFromEnv added in v1.0.0

func NewFromEnv(staticArgs ...any) Logger

NewFromEnv creates a Logger configured from environment variables (LOG_LEVEL, LOG_JSON_OUTPUT). This is a convenience constructor for bootstrapping in main.go.

Jump to

Keyboard shortcuts

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