Documentation
¶
Overview ¶
Package weftslognats provides a slog.Handler that fans logs out to both stderr (or any base handler) and a NATS subject. Errors and warnings published on NATS are what weft-doctor's NATSIngester subscribes to ; the stderr path stays untouched so existing tooling (operator tailing, kubectl-like CLI sniff, journald) keeps working.
Wire it once in main.go :
conn, _ := nats.Connect("nats://nats.weft.svc:4222")
log := slog.New(weftslognats.NewHandler(weftslognats.Options{
Base: slog.NewJSONHandler(os.Stderr, nil),
Conn: conn,
Subject: "weft.agent." + hostUUID + ".log",
}))
slog.SetDefault(log)
Everything that already calls slog.{Info,Warn,Error} keeps working unchanged ; WARN+ERROR records additionally flow onto NATS in slog.JSONHandler-compatible format so weft-doctor can parse them.
Index ¶
Constants ¶
const EnvNATSURL = "WEFT_NATS_URL"
EnvNATSURL is the env var the SetupFromEnv helper reads. Unset → the handler degrades to base-only (stderr) cleanly.
Variables ¶
This section is empty.
Functions ¶
func PanicReporter ¶ added in v0.3.0
func PanicReporter(name ...string)
PanicReporter recovers a panic, slog.Errors the value + stack trace, sleeps briefly to let the NATS publish flush, then re-panics so systemd still observes the abnormal exit and journalctl still prints the runtime's canonical stack.
`name` defaults to "weft" if empty ; pass the binary name when you have multiple binaries logging to the same NATS subject so classifiers can disambiguate (e.g. "weft-driver-qemu", "weft-microvm-agent").
Off-NATS hosts get identical behaviour as before : slog falls back to stderr, which is where the stack was going to land anyway.
func SetupFromEnv ¶ added in v0.2.0
SetupFromEnv wires the canonical openweft slog setup in one call. Returned Logger writes JSON to stderr (always) and additionally publishes WARN+ERROR records to NATS on the given subject (when WEFT_NATS_URL is set + reachable).
Returned io.Closer drains the NATS connection on shutdown ; safe to call when no NATS connection was opened (no-op).
Subject convention :
weft.<component>.<host_or_vm_id>.log
e.g. "weft.agent."+hostUUID+".log",
"weft.driver.qemu."+hostUUID+".log", "weft.ha.postgres."+nodeName+".log".
Failure modes :
- WEFT_NATS_URL unset → degraded mode, no error
- nats.Connect fails → degraded mode + WARN to stderr
- subject == "" → panic (Handler contract)
Types ¶
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler is a slog.Handler fan-out. Exported so callers can type- assert if needed ; constructed via NewHandler.
func NewHandler ¶
NewHandler builds the fan-out. Panics on nil Base — see Options.Base rationale.
func (*Handler) Enabled ¶
Enabled : the union of base + nats. Anything either side wants to see, we evaluate. In practice base usually allows INFO+ ; nats allows WARN+ ; the union is INFO+.
func (*Handler) Handle ¶
Handle dispatches the record to base (always) and to NATS (when conn != nil AND lvl >= minLevel). Errors from base are propagated ; NATS publish errors are surfaced via OnPublishError and otherwise swallowed — we never want logging itself to fail the caller.
type Options ¶
type Options struct {
// Base receives every record (stderr / journald / whatever the
// operator wired). Required ; nil panics — there's no use case
// for "publish to NATS only", and silent drop on a malformed
// config would mask outages.
Base slog.Handler
// Conn is the NATS connection. nil is ALLOWED and means
// "publish nowhere, Base only" : useful for dev, tests, and
// graceful degrade when NATS is unreachable at startup.
Conn Publisher
// Subject is the NATS subject WARN+ERROR records are published
// to. Required when Conn is set. Convention :
// weft.<component>.<host_id>.log
// e.g. weft.agent.dc1-r1-h1.log, weft.microvm-agent.<vm_uuid>.log.
Subject string
// MinLevel is the floor at which NATS publishing kicks in.
// Default slog.LevelWarn — keeps the diagnosis pipeline focused
// on actionable signal, not DEBUG/INFO chatter.
MinLevel slog.Level
// OnPublishError is called when a NATS publish fails. Default :
// no-op (we don't want logging to itself cascade). Set to a
// callback when you want visibility (e.g. bump a Prom metric).
OnPublishError func(err error)
}
Options configures the handler.