logger

package
v1.1.3 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package logger is the project-wide slog wrapper. All logging goes through context.Context — services and handlers must NOT embed a *slog.Logger field. Use Load(ctx) to fetch the logger and WithService(ctx, name) at the service boundary so every record carries the same "service" attribute.

Output format is fixed: text handler to stderr with RFC3339 timestamps and stable attribute ordering. This guarantees a single consistent format across the entire process; do not construct ad-hoc slog.New(...) instances in service code — call NewLogger or NewTestLogger here so format and handler options stay aligned.

Index

Constants

This section is empty.

Variables

View Source
var GlobalRingBuffer = NewRequestRingBuffer(defaultBufferSize)

GlobalRingBuffer is the global buffer for the Live API Console. It stores the last 100 requests.

View Source
var Key = ctxval.NewKey[*slog.Logger]("logger") //nolint:gochecknoglobals // existing issue.

Key is the typed context key under which the logger is stored. Exported so middleware that wants raw ctxval access can reuse it.

Functions

func APIConsoleMiddleware

func APIConsoleMiddleware() echo.MiddlewareFunc

APIConsoleMiddleware captures incoming API requests and stores them in the ring buffer. It should be injected after standard loggers but before request processing.

func AddAttrs

func AddAttrs(ctx context.Context, attrs ...slog.Attr) context.Context

AddAttrs returns a child context whose logger has attrs pre-attached to every record. slog.Logger.With does not mutate the parent so this is safe for concurrent use across requests.

func EchoMiddleware

func EchoMiddleware(logger *slog.Logger) echo.MiddlewareFunc

EchoMiddleware creates an Echo middleware that injects a logger into the request context.

func Load

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

Load returns the logger carried on ctx, or slog.Default() when none is set. Always returns non-nil so callers can chain methods without a guard.

func Middleware

func Middleware(logger *slog.Logger) func(http.Handler) http.Handler

Middleware creates an HTTP middleware that injects a logger into the request context.

func NewLogger

func NewLogger(level slog.Level) *slog.Logger

NewLogger returns a logger writing text records to stderr at level.

func NewTestLogger

func NewTestLogger() *slog.Logger

NewTestLogger returns a logger with debug level enabled, useful in tests.

func Save

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

Save stores logger in ctx and returns the child context.

func WithService

func WithService(ctx context.Context, name string) context.Context

WithService returns a child context whose logger carries service=<name>. Call this once at the entry of every service handler so downstream records emitted via Load(ctx) are uniformly tagged. The service tag persists across AddAttrs calls because slog.Logger.With layers attributes.

func WithWorker

func WithWorker(ctx context.Context, service, job string) context.Context

WithWorker returns a child context whose logger carries service=<service> and worker=<service>-<job>, so records emitted by a background routine are attributable to the specific job that produced them.

Safety rules (the logger is a *slog.Logger pointer carried in ctx):

  • Call this ONCE at the entry of the worker goroutine, never inside a loop. Each call layers attributes onto a new logger; repeating it on a long-lived context would grow the attribute chain (and memory) without bound.
  • Derive ctx from the process/lifecycle context (e.g. the janitor context), never from a per-request context, so worker logs don't inherit request_id and don't pin a finished request alive.

Enrichment is copy-on-write: slog.Logger.With does not mutate the parent, so concurrent workers and requests never corrupt each other's logger.

Types

type CapturedRequest

type CapturedRequest struct {
	Timestamp time.Time         `json:"timestamp"`
	Headers   map[string]string `json:"headers"`
	ID        string            `json:"id"`
	Method    string            `json:"method"`
	Path      string            `json:"path"`
	Body      string            `json:"body,omitempty"`
	Status    int               `json:"status"`
	Duration  time.Duration     `json:"duration_ms"`
}

CapturedRequest represents a single HTTP request captured by the console middleware.

type RequestRingBuffer

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

RequestRingBuffer holds the last N captured requests.

func NewRequestRingBuffer

func NewRequestRingBuffer(maxSize int) *RequestRingBuffer

NewRequestRingBuffer creates a new ring buffer for captured requests.

func (*RequestRingBuffer) Add

func (r *RequestRingBuffer) Add(req *CapturedRequest)

Add appends a new request into the ring buffer and notifies subscribers.

func (*RequestRingBuffer) GetAll

func (r *RequestRingBuffer) GetAll() []*CapturedRequest

GetAll returns all captured requests in chronological order.

func (*RequestRingBuffer) Subscribe

func (r *RequestRingBuffer) Subscribe() chan *CapturedRequest

Subscribe adds a channel to receive incoming requests.

func (*RequestRingBuffer) Unsubscribe

func (r *RequestRingBuffer) Unsubscribe(ch chan *CapturedRequest)

Unsubscribe removes a channel from receiving requests.

Jump to

Keyboard shortcuts

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