Orca ORCA v0.174.2

logs

Log Gopher

The canonical Corti logger. New returns a *log/slog.Logger configured from environment variables — there is no wrapper type and no re-exported Level. The standard library is the API; this package is a thin, opinionated constructor so every service starts with the same level, format, and output.

Installation

go get github.com/corticph/gocomo/logger

Quick start

package main

import "github.com/corticph/gocomo/logger"

func main() {
    l := logger.New()
    l.Info("started", "service", "transcription")
}

New returns *slog.Logger, so handlers accept *slog.Logger (or a narrower interface they declare consumer-side) and call the stdlib methods directly.

Configuration

New reads two environment variables, set by the container at runtime. There are no functional options for level/format by design — one configuration path, twelve-factor style.

Env var Values Default Effect
LOG_LEVEL debug info warn error info Minimum level emitted. Case-insensitive.
LOG_FORMAT json text json Handler format. Case-insensitive.

Unknown values fall back to the defaults and a warning is logged to the configured writer; output goes to os.Stdout by default.

// Defaults: INFO level, JSON to stdout.
l := logger.New()

// LOG_LEVEL=warn, LOG_FORMAT=text (set in the environment) -> same call.

Output destination: WithWriter

WithWriter overrides the destination (the only functional option). It is the intended seam for tests: point it at a buffer to assert output, or at io.Discard to silence it.

// Capture output in a test.
var buf bytes.Buffer
l := logger.New(logger.WithWriter(&buf))
l.Info("handled")
// buf holds the JSON record.

// Silence a logger entirely (e.g. a test that only exercises behavior,
// not content).
l := logger.New(logger.WithWriter(io.Discard))

Bad env values are reported to the same writer as the real logger, so a test capturing via WithWriter(&buf) can assert them and a silenced logger (WithWriter(io.Discard)) stays quiet.

Usage

args are alternating key/value pairs, exactly as in log/slog:

l.With("tenant", "acme", "request_id", "r-1").Info("handled")
// {"time":"...","level":"INFO","msg":"handled","tenant":"acme","request_id":"r-1"}

For level values, import log/slog and use slog.LevelDebug etc. directly — this package does not re-export them.

Testing

Tests build a logger through New with WithWriter so they don't touch os.Stdout:

var buf bytes.Buffer
l := logger.New(logger.WithWriter(&buf))
l.Info("handled")
// assert on buf.String()

Set LOG_LEVEL/LOG_FORMAT with t.Setenv to test env-var behavior; clear them first if you need the default to be deterministic:

t.Setenv("LOG_LEVEL", "")
t.Setenv("LOG_FORMAT", "")
l := logger.New(logger.WithWriter(&buf))