Documentation
¶
Overview ¶
Package observe is the agent's observability layer: structured logging, tracing, and metrics, all reached through Flynn-owned ports so the agent never depends on a concrete backend. This mirrors OpenTelemetry's own API/SDK split: this package is a dependency-light API with no-op defaults, and an opt-in adapter (observe/otel) substitutes the real SDK without any call site changing.
The standalone build uses the no-op defaults here (logs discarded, spans and metrics dropped) so the agent runs with zero setup and near-zero overhead. A host such as an Ion Alpha instance injects a real slog.Handler plus Tracer and Meter adapters via New, without this package importing either. Only this package may import log/slog; every other package logs through the Logger port.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Into ¶
func Into(ctx context.Context, o *Observability) context.Context
Into returns a context carrying o, so deep call sites reach the active logger, tracer, and meter via FromContext instead of threading them as parameters. The dispatch waist binds the run's Observability once; leaf code reads it back.
Types ¶
type Field ¶
Field is a typed key/value attribute on a log record, span, or metric. Build one with the typed constructors (String, Int, Err, ...) so call sites never touch the logging backend's own attribute types.
type Logger ¶
type Logger interface {
Debug(ctx context.Context, msg string, fields ...Field)
Info(ctx context.Context, msg string, fields ...Field)
Warn(ctx context.Context, msg string, fields ...Field)
Error(ctx context.Context, msg string, fields ...Field)
// With returns a Logger that includes fields on every record (a scoped logger),
// e.g. binding run_id and scope once at the waist.
With(fields ...Field) Logger
}
Logger is the agent's structured logging port. Call sites depend on this, never on log/slog, so the backend stays swappable and the dependency is lint-enforceable. slog backs the default; a host may inject any slog.Handler.
func NewSlogLogger ¶
NewSlogLogger returns a Logger backed by the slog.Handler h.
type Meter ¶
type Meter interface {
// Counter returns a monotonic counter (requests, tokens, errors).
Counter(name string) Counter
// Histogram returns a distribution recorder (latency, sizes).
Histogram(name string) Histogram
}
Meter creates metric instruments. Like the tracer it is a minimal port with a no-op default; an adapter (observe/otel) maps it onto a backend such as OpenTelemetry, exporting to VictoriaMetrics. Fetching an instrument is cheap, so call sites may fetch one per use.
type NopLogger ¶
type NopLogger struct{}
NopLogger is a Logger that discards every record without touching its fields. It is the standalone Default so the disabled-log path allocates nothing; a host that wants real logging injects a slog.Handler through New instead.
type NopMeter ¶
type NopMeter struct{}
NopMeter is a Meter whose instruments do nothing; the standalone default.
type NopTracer ¶
type NopTracer struct{}
NopTracer is a Tracer that does nothing; it is the standalone default.
type Observability ¶
Observability bundles the logger, tracer, and meter threaded through the runtime. The zero value is not usable; construct one with Default or New.
func Default ¶
func Default() *Observability
Default returns an Observability that discards everything: a no-op logger, a no-op tracer, and a no-op meter. It is the zero-setup standalone default. The logger is a true no-op (not slog over io.Discard), so a disabled log call on the standalone path builds no attributes and reaches no handler.
func FromContext ¶
func FromContext(ctx context.Context) *Observability
FromContext returns the Observability bound to ctx, or the no-op default if none is present, so a caller can always log, trace, and measure without a nil check.
type Span ¶
type Span interface {
// SetAttr records a key/value attribute on the span.
SetAttr(key string, value any)
// RecordError marks the span as failed and attaches err.
RecordError(err error)
// End closes the span.
End()
}
Span is a single unit of traced work. End must be called exactly once; deferring it at the call site is the expected usage.
type Tracer ¶
type Tracer interface {
// Start begins a span named name and returns a context carrying it together
// with the Span to end. The returned context must be used for nested work.
Start(ctx context.Context, name string) (context.Context, Span)
}
Tracer starts spans around units of work. It is deliberately minimal: the agent depends on this interface, and an adapter maps it onto a backend such as OpenTelemetry. Implementations must be safe for concurrent use.