logger

package
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Feb 16, 2026 License: MIT Imports: 8 Imported by: 0

README

Logger

Structured logging with per-subsystem log levels and OpenTelemetry trace context integration.

Features

  • Per-subsystem configurable log levels
  • Automatic trace_id/span_id injection when OTel is active
  • Context-based logger propagation
  • JSON output format
  • Per-instance log files via InstanceLogHandler

Configuration

Variable Description Default
LOG_LEVEL Default log level info
LOG_LEVEL_<SUBSYSTEM> Per-subsystem level inherits default

Subsystems: API, IMAGES, INSTANCES, NETWORK, VOLUMES, VMM, SYSTEM, EXEC

Example:

LOG_LEVEL=info LOG_LEVEL_NETWORK=debug ./hypeman

Usage

// Create subsystem-specific logger
cfg := logger.NewConfig()
log := logger.NewSubsystemLogger(logger.SubsystemInstances, cfg)

// Add logger to context
ctx = logger.AddToContext(ctx, log)

// Retrieve from context
log = logger.FromContext(ctx)
log.InfoContext(ctx, "instance created", "instance_id", instanceID)

Per-Instance Logging

The InstanceLogHandler automatically writes logs with an "instance_id" attribute to per-instance hypeman.log files. This provides an operations audit trail for each VM.

// Wrap any handler with instance logging
handler := logger.NewInstanceLogHandler(baseHandler, func(id string) string {
    return paths.InstanceHypemanLog(id)
})

// Logs with "instance_id" attribute are automatically written to that instance's hypeman.log
log.InfoContext(ctx, "starting VM", "instance_id", instanceID)

// Related operations (e.g., ingress creation) can also include instance_id
// to appear in the instance's audit log
log.InfoContext(ctx, "ingress created", "ingress_id", ingressID, "instance_id", targetInstance)

Output

When OTel tracing is active, logs include trace context:

{
  "level": "INFO",
  "msg": "instance created",
  "subsystem": "INSTANCES",
  "trace_id": "abc123...",
  "span_id": "def456...",
  "instance_id": "instance-123"
}

Documentation

Overview

Package logger provides structured logging with subsystem-specific levels and OpenTelemetry trace context integration.

Package logger provides structured logging with subsystem-specific levels and OpenTelemetry trace context integration.

Index

Constants

View Source
const (
	SubsystemAPI       = "API"
	SubsystemCaddy     = "CADDY"
	SubsystemImages    = "IMAGES"
	SubsystemIngress   = "INGRESS"
	SubsystemInstances = "INSTANCES"
	SubsystemNetwork   = "NETWORK"
	SubsystemVolumes   = "VOLUMES"
	SubsystemVMM       = "VMM"
	SubsystemSystem    = "SYSTEM"
	SubsystemExec      = "EXEC"
)

Subsystem names for per-subsystem logging configuration.

Variables

This section is empty.

Functions

func AddToContext

func AddToContext(ctx context.Context, logger *slog.Logger) context.Context

AddToContext adds a logger to the context.

func FromContext

func FromContext(ctx context.Context) *slog.Logger

FromContext retrieves the logger from context, or returns default.

func NewLogger

func NewLogger(cfg Config) *slog.Logger

NewLogger creates a new slog.Logger with JSON output.

func NewSubsystemLogger

func NewSubsystemLogger(subsystem string, cfg Config, otelHandler slog.Handler) *slog.Logger

NewSubsystemLogger creates a logger for a specific subsystem with its configured level. If otelHandler is provided, logs will be sent both to stdout and to OTel.

func With

func With(logger *slog.Logger, args ...any) *slog.Logger

With returns a logger with additional attributes.

Types

type Config

type Config struct {
	// DefaultLevel is the default log level for all subsystems.
	DefaultLevel slog.Level
	// SubsystemLevels maps subsystem names to their specific log levels.
	// If a subsystem is not in this map, DefaultLevel is used.
	SubsystemLevels map[string]slog.Level
	// AddSource adds source file information to log entries.
	AddSource bool
}

Config holds logging configuration.

func NewConfig

func NewConfig() Config

NewConfig creates a Config from environment variables. Reads LOG_LEVEL for default level and LOG_LEVEL_<SUBSYSTEM> for per-subsystem levels.

func (Config) LevelFor

func (c Config) LevelFor(subsystem string) slog.Level

LevelFor returns the log level for the given subsystem.

type InstanceLogHandler

type InstanceLogHandler struct {
	slog.Handler
	// contains filtered or unexported fields
}

InstanceLogHandler wraps an slog.Handler and additionally writes logs that have an "id" attribute to a per-instance hypeman.log file. This provides automatic per-instance logging without manual instrumentation.

Implementation follows the slog handler guide for shared state across WithAttrs/WithGroup: https://pkg.go.dev/golang.org/x/example/slog-handler-guide

func NewInstanceLogHandler

func NewInstanceLogHandler(wrapped slog.Handler, logPathFunc func(id string) string) *InstanceLogHandler

NewInstanceLogHandler creates a new handler that wraps the given handler and writes instance-related logs to per-instance log files. logPathFunc should return the path to hypeman.log for a given instance ID.

func (*InstanceLogHandler) Enabled

func (h *InstanceLogHandler) Enabled(ctx context.Context, level slog.Level) bool

Enabled reports whether the handler handles records at the given level.

func (*InstanceLogHandler) Handle

func (h *InstanceLogHandler) Handle(ctx context.Context, r slog.Record) error

Handle processes a log record, passing it to the wrapped handler and optionally writing to a per-instance log file if "id" attribute is present.

func (*InstanceLogHandler) WithAttrs

func (h *InstanceLogHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new handler with the given attributes. Tracks attrs locally so we can find "id" even when added via With().

func (*InstanceLogHandler) WithGroup

func (h *InstanceLogHandler) WithGroup(name string) slog.Handler

WithGroup returns a new handler with the given group name.

Jump to

Keyboard shortcuts

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