otel

package
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package otel is the optional OpenTelemetry export adapter for obs/v1 — the OTelEmitter (RFC §11.3, brief 05 §3.4).

It is a driver behind the obs emitter seam (CLAUDE.md §4.4): it registers itself under the driver name "otel" via obs.RegisterDriver, exactly like the ring-buffer and SSE drivers. It is OFF BY DEFAULT — local observation (the ring buffer + the SSE sink) works with zero OTel configuration; OTel is an interoperability option, never a prerequisite to observe locally (CLAUDE.md §8). The adapter is constructed only when a caller explicitly opens the driver or calls New.

Why a separate package

OTel is an EXPORT ADAPTER behind obs/v1, never the internal model (brief 05 §4 risk 1). obs/v1 is Dockyard's stable, versioned contract; the OTel dependency and the still-"Development" MCP semantic conventions are contained here so an attribute-name shift is a localized edit. runtime/obs itself takes no OTel dependency.

The mapping

An obs.Event lowers onto an OpenTelemetry span carrying MCP semantic- convention attributes (mcp.* / gen_ai.*): a tool.call becomes a span "tools/call {tool}" with mcp.method.name, gen_ai.tool.name, gen_ai.operation.name=execute_tool, mcp.session.id, network.transport, and — on failure — error.type. The W3C Trace Context IDs obs/v1 already puts on every event (obs.SpanContext) become the OTel span's trace-id and span-id, and the event's ParentSpanID becomes the exported span's parent — both intra-trace (a handler `log` child of its `tool.call`, D-079/D-114) and cross-process (the streamable-HTTP transport's W3C traceparent extractor inherits the caller's trace id and span id at the handler edge, R5/D-122). A Dockyard span therefore nests natively under a calling Harbor agent's execute_tool span when the agent emits a traceparent header — the OTel adapter just exports what the obs/v1 event already carries. A log event is exported as a span event on the correlated span (D-076).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type OTelEmitter

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

OTelEmitter is the optional OpenTelemetry export adapter for obs/v1. It is an obs.Emitter: the runtime emits obs.Events to it through the same seam as any other driver, and it lowers each event onto an OTel span.

OTelEmitter is a reusable concurrent artifact — Emit is safe from many goroutines, because the underlying OTel Tracer is. Emit is non-blocking from the runtime's point of view: span export is handed to the span processor, which the OTel SDK runs asynchronously (a batching processor) — the runtime is never stalled on an OTel exporter (CLAUDE.md §8).

The emitter owns an internal TracerProvider built over the caller-supplied span processor(s) and a context-keyed IDGenerator (idGen). The IDGenerator is what makes a Dockyard span carry the obs/v1 event's OWN W3C trace-id and span-id rather than fresh OTel-generated IDs: combined with the ParentSpanID-driven parent linkage (startContext, D-114) and the HTTP transport's W3C traceparent extractor (R5/D-122), a Dockyard span nests natively under a calling Harbor agent's execute_tool span (RFC §11.2).

When an obs/v1 event carries a ParentSpanID — e.g. a handler `log` event that is a true child of its enclosing `tool.call` (the obs/v1 trace-correlation, D-079) — the emitter additionally seats a remote parent span context on the start context so the exported OTel span nests under that parent rather than being a trace root (D-114).

The otel.OTelEmitter "stutter" is intentional: OTelEmitter is the RFC §11.3-binding name for this adapter — it appears verbatim in the RFC and the master plan — so it is the intended public vocabulary, not an accident.

func New

func New(processors ...sdktrace.SpanProcessor) *OTelEmitter

New constructs an OTelEmitter that exports spans to the caller-supplied OpenTelemetry span processors (e.g. a batching processor over an OTLP exporter, or an in-memory recorder under test). With NO processors the emitter discards every event — OTel stays off unless a real export pipeline is supplied (CLAUDE.md §8), so a caller can wire New unconditionally and only a configured pipeline activates export.

func (*OTelEmitter) Emit

func (o *OTelEmitter) Emit(ctx context.Context, e obs.Event)

Emit lowers e onto an OpenTelemetry span. A nil tracer (OTel off) discards the event. The span carries the MCP semantic-convention attributes for e's kind and the W3C Trace Context IDs obs/v1 already assigned, so the exported span shares e's trace and span identity.

Jump to

Keyboard shortcuts

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