Documentation
¶
Overview ¶
Package usage emits one append-only event per completed request — the raw material a future control plane aggregates into per-tenant counts, quotas, and billing. This slice is log-only: no counting, no enforcement, no entitlement state. A request finishes, we record what we already know at the convergence point (rid, tenant, sizes, timing, status), and something downstream derives everything else.
The package is interface-first so the transport is swappable without touching call sites. The default ZapSink writes a structured "usage" line through the chassis's existing zap logger; a later file / Kafka / NATS / OTEL sink drops in behind the same Sink.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Sink ¶
type Sink interface {
WriteEvent(ev UsageEvent)
Close(ctx context.Context) error
}
Sink consumes usage events. WriteEvent must be safe for concurrent calls (the bus loop emits from per-request goroutines). Close is called once on chassis shutdown; synchronous sinks return nil immediately.
type UsageEvent ¶
type UsageEvent struct {
RID string
Tenant string
Src string // "http" | "tcp" | "cron"
Stack string // entry stage the request dispatched to
DurationMS int64
Status string // "ok" | "error"
BytesIn int
BytesOut int
// MemBytes is peak guest memory for a compute invocation (src="compute").
// Zero for request-level usage (http/tcp/cron have no wasm memory) and
// omitted from the log line in that case.
MemBytes int
}
UsageEvent is the per-request record. Deliberately flat and derived-metric-free: ops counts, monthly rollups, and rate-limit inputs are a downstream consumer's job, not the runtime's.
Tenant is the resolved tenant slug when routing succeeded; it is "_sys" (or empty) for unrouted/404 traffic, which is logged as-is so rejected requests are still measured.
type ZapSink ¶
type ZapSink struct {
// contains filtered or unexported fields
}
ZapSink is the default open-core sink: it folds the event into a single structured log line. The stable "usage" message is the downstream filter key; the timestamp is zap's own. Close is a no-op — the logger's flush lifecycle is owned by the chassis, not here.
func NewZapSink ¶
NewZapSink wraps an existing chassis logger. The logger is expected to be non-nil; callers only construct a ZapSink when usage is enabled.
func (*ZapSink) WriteEvent ¶
func (s *ZapSink) WriteEvent(ev UsageEvent)