otel

package
v1.0.0-beta.162 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 19 Imported by: 0

README

OpenTelemetry Exporter

The otel-exporter is an explicit optional framework adapter. It converts agent and tool events into OTLP JSON spans and metrics and sends them to an OTLP/HTTP collector. Core composition does not register it; a binary must select the OTEL adapter explicitly.

Proven contract

  • OTLP/HTTP only. Set protocol to http; other values fail validation.
  • endpoint is the collector base URL, including http:// or https://. The default is http://localhost:4318.
  • Trace export posts OTLP JSON to /v1/traces when export_traces is enabled.
  • Metric export posts OTLP JSON to /v1/metrics when export_metrics is enabled.
  • headers are copied onto both request types.
  • batch_timeout controls the flush interval and export_timeout bounds a flush request.
  • sampling_rate controls span sampling. Metrics are not sampled.

The adapter does not implement OTLP logs, configurable resource attributes, item-count batch limits, or an insecure transport switch. HTTP versus HTTPS is selected by the endpoint URL. Supplying removed or unknown config fields fails component construction instead of being silently ignored.

Example

{
  "type": "output",
  "name": "otel-exporter",
  "enabled": true,
  "config": {
    "endpoint": "http://otel-collector:4318",
    "protocol": "http",
    "service_name": "semstreams",
    "service_version": "1.0.0",
    "export_traces": true,
    "export_metrics": true,
    "batch_timeout": "5s",
    "export_timeout": "30s",
    "sampling_rate": 1.0,
    "headers": {
      "Authorization": "Bearer replace-me"
    }
  }
}

Port definitions may be omitted to use the component defaults. The default inputs consume agent lifecycle events and tool results from the AGENT stream.

Selection and ownership

See ADR-075. OTEL remains framework-owned only as this explicit, fail-closed adapter; it is not evidence of an AGNTCY integration layer.

Documentation

Overview

Package otel exports SemStreams agent telemetry as OTLP/HTTP JSON spans and metrics. It is an explicit optional framework adapter under ADR-075, not part of the core component composition.

The component consumes agent lifecycle and tool-result events, builds correlated spans and metrics, and periodically posts accepted batches to the configured collector's /v1/traces and /v1/metrics endpoints. Collector responses outside the 2xx range are export failures.

Configuration

The proven transport is OTLP/HTTP only:

{
  "endpoint": "http://localhost:4318",
  "protocol": "http",
  "service_name": "semstreams",
  "service_version": "1.0.0",
  "export_traces": true,
  "export_metrics": true,
  "batch_timeout": "5s",
  "export_timeout": "30s",
  "sampling_rate": 1.0
}

Unknown fields fail component construction. OTLP logs, configurable resource attributes, item-count batch limits, and a separate insecure switch are not implemented. Select HTTP or HTTPS with the endpoint URL.

Trace correlation

Trace IDs are deterministically derived from loop IDs and span IDs from span keys, preserving correlation across the agent execution hierarchy.

See https://opentelemetry.io/docs/specs/ for the OTLP specification.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewComponent

func NewComponent(rawConfig json.RawMessage, deps component.Dependencies) (component.Discoverable, error)

NewComponent creates a new OTEL exporter component.

func Register

func Register(registry RegistryInterface) error

Register registers the OTEL exporter component with the given registry.

Types

type AgentEvent

type AgentEvent struct {
	// Type is the event type (loop.created, loop.completed, loop.failed, etc.)
	Type string `json:"type"`

	// LoopID is the agent loop identifier.
	LoopID string `json:"loop_id"`

	// TaskID is the task identifier (for task events).
	TaskID string `json:"task_id,omitempty"`

	// ToolName is the tool name (for tool events).
	ToolName string `json:"tool_name,omitempty"`

	// Timestamp is when the event occurred.
	Timestamp time.Time `json:"timestamp"`

	// EntityID is the agent's entity ID.
	EntityID string `json:"entity_id,omitempty"`

	// Role is the agent's role.
	Role string `json:"role,omitempty"`

	// Error is the error message for failure events.
	Error string `json:"error,omitempty"`

	// Duration is the operation duration (for completion events).
	Duration time.Duration `json:"duration,omitempty"`

	// Metadata contains additional event metadata.
	Metadata map[string]any `json:"metadata,omitempty"`
}

AgentEvent represents an agent lifecycle event from NATS.

type BucketCount

type BucketCount struct {
	// UpperBound is the bucket upper bound.
	UpperBound float64 `json:"upper_bound"`

	// Count is the cumulative count.
	Count uint64 `json:"count"`
}

BucketCount represents a histogram bucket.

type Component

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

Component implements the OTEL exporter component. It collects spans and metrics from agent events and exports them to OTEL collectors.

func (*Component) ConfigSchema

func (c *Component) ConfigSchema() component.ConfigSchema

ConfigSchema returns the configuration schema.

func (*Component) DataFlow

func (c *Component) DataFlow() component.FlowMetrics

DataFlow returns current data flow metrics.

func (*Component) GetMetricMapper

func (c *Component) GetMetricMapper() *MetricMapper

GetMetricMapper returns the metric mapper (for testing).

func (*Component) GetSpanCollector

func (c *Component) GetSpanCollector() *SpanCollector

GetSpanCollector returns the span collector (for testing).

func (*Component) Health

func (c *Component) Health() component.HealthStatus

Health returns the current health status.

func (*Component) Initialize

func (c *Component) Initialize() error

Initialize prepares the component.

func (*Component) InputPorts

func (c *Component) InputPorts() []component.Port

InputPorts returns configured input port definitions.

func (*Component) Meta

func (c *Component) Meta() component.Metadata

Meta returns component metadata.

func (*Component) OutputPorts

func (c *Component) OutputPorts() []component.Port

OutputPorts returns configured output port definitions.

func (*Component) SetExporter

func (c *Component) SetExporter(exp Exporter)

SetExporter sets the OTEL exporter (for testing).

func (*Component) Start

func (c *Component) Start(ctx context.Context) error

Start begins processing agent events and exporting OTEL data.

func (*Component) Stop

func (c *Component) Stop(ctx context.Context) error

Stop gracefully stops the component.

type Config

type Config struct {
	// Ports defines the input/output port configuration.
	Ports *component.PortConfig `json:"ports" schema:"type:ports,description:Port configuration,category:basic"`

	// Endpoint is the OTEL collector endpoint.
	Endpoint string `json:"endpoint" schema:"type:string,description:OTLP HTTP collector base URL,category:basic,default:http://localhost:4318"`

	// Protocol specifies the export protocol.
	// Only OTLP/HTTP is currently implemented. Unsupported transports fail closed.
	Protocol string `json:"protocol" schema:"type:string,description:Export protocol,category:basic,default:http"`

	// ServiceName is the service name for OTEL traces.
	ServiceName string `json:"service_name" schema:"type:string,description:Service name for traces,category:basic,default:semstreams"`

	// ServiceVersion is the service version for OTEL traces.
	ServiceVersion string `json:"service_version" schema:"type:string,description:Service version,category:basic,default:1.0.0"`

	// ExportTraces enables trace export.
	ExportTraces bool `json:"export_traces" schema:"type:bool,description:Enable trace export,category:basic,default:true"`

	// ExportMetrics enables metric export.
	ExportMetrics bool `json:"export_metrics" schema:"type:bool,description:Enable metric export,category:basic,default:true"`

	// BatchTimeout is the timeout for batching exports.
	BatchTimeout string `json:"batch_timeout" schema:"type:string,description:Batch export timeout,category:advanced,default:5s"`

	// ExportTimeout is the timeout for each export operation.
	ExportTimeout string `json:"export_timeout" schema:"type:string,description:Export operation timeout,category:advanced,default:30s"`

	// Headers are additional headers to send with exports.
	Headers map[string]string `json:"headers" schema:"type:object,description:Additional export headers,category:advanced"`

	// SamplingRate is the trace sampling rate (0.0 to 1.0).
	SamplingRate float64 `json:"sampling_rate" schema:"type:float,description:Trace sampling rate,category:advanced,default:1.0"`

	// ConsumerNameSuffix adds a suffix to consumer names for uniqueness in tests.
	ConsumerNameSuffix string `json:"consumer_name_suffix" schema:"type:string,description:Suffix for consumer names,category:advanced"`
}

Config defines the configuration for the OTEL exporter component.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default configuration.

func (*Config) GetBatchTimeout

func (c *Config) GetBatchTimeout() time.Duration

GetBatchTimeout returns the batch timeout duration.

func (*Config) GetExportTimeout

func (c *Config) GetExportTimeout() time.Duration

GetExportTimeout returns the export timeout duration.

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the configuration.

type DataPoint

type DataPoint struct {
	// Timestamp is when the data point was recorded.
	Timestamp time.Time `json:"timestamp"`

	// Value is the metric value (for counter/gauge).
	Value float64 `json:"value,omitempty"`

	// Count is the count (for histogram/summary).
	Count uint64 `json:"count,omitempty"`

	// Sum is the sum (for histogram/summary).
	Sum float64 `json:"sum,omitempty"`

	// Buckets are histogram bucket counts.
	Buckets []BucketCount `json:"buckets,omitempty"`

	// Quantiles are summary quantile values.
	Quantiles []QuantileValue `json:"quantiles,omitempty"`

	// Attributes are data point attributes.
	Attributes map[string]any `json:"attributes,omitempty"`
}

DataPoint represents a single metric data point.

type Exporter

type Exporter interface {
	// ExportSpans exports spans to the OTEL collector.
	ExportSpans(ctx context.Context, spans []*SpanData) error

	// ExportMetrics exports metrics to the OTEL collector.
	ExportMetrics(ctx context.Context, metrics []*MetricData) error

	// Shutdown gracefully shuts down the exporter.
	Shutdown(ctx context.Context) error
}

Exporter defines the interface for OTEL export operations.

type MetricData

type MetricData struct {
	// Name is the metric name.
	Name string `json:"name"`

	// Description describes the metric.
	Description string `json:"description,omitempty"`

	// Unit is the metric unit.
	Unit string `json:"unit,omitempty"`

	// Type is the metric type.
	Type MetricType `json:"type"`

	// DataPoints contains the metric values.
	DataPoints []DataPoint `json:"data_points"`

	// Attributes are metric-level attributes.
	Attributes map[string]any `json:"attributes,omitempty"`
}

MetricData represents a metric ready for export.

type MetricMapper

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

MetricMapper maps internal metrics to OTEL format.

func NewMetricMapper

func NewMetricMapper(serviceName, serviceVersion string) *MetricMapper

NewMetricMapper creates a new metric mapper.

func (*MetricMapper) FlushMetrics

func (mm *MetricMapper) FlushMetrics() []*MetricData

FlushMetrics returns and clears all collected metrics.

func (*MetricMapper) MapFromPrometheus

func (mm *MetricMapper) MapFromPrometheus(prom *PrometheusMetric)

MapFromPrometheus converts Prometheus metrics to OTEL format.

func (*MetricMapper) RecordAgentMetrics

func (mm *MetricMapper) RecordAgentMetrics(loopID, role string, stats map[string]int64)

RecordAgentMetrics records standard agent metrics.

func (*MetricMapper) RecordCounter

func (mm *MetricMapper) RecordCounter(name, description, unit string, value float64, attrs map[string]any)

RecordCounter records a counter metric.

func (*MetricMapper) RecordGauge

func (mm *MetricMapper) RecordGauge(name, description, unit string, value float64, attrs map[string]any)

RecordGauge records a gauge metric.

func (*MetricMapper) RecordHistogram

func (mm *MetricMapper) RecordHistogram(name, description, unit string, count uint64, sum float64, buckets []BucketCount, attrs map[string]any)

RecordHistogram records a histogram metric.

func (*MetricMapper) RecordSummary

func (mm *MetricMapper) RecordSummary(name, description, unit string, count uint64, sum float64, quantiles []QuantileValue, attrs map[string]any)

RecordSummary records a summary metric.

func (*MetricMapper) Stats

func (mm *MetricMapper) Stats() map[string]int64

Stats returns mapper statistics.

type MetricType

type MetricType string

MetricType represents the type of metric.

const (
	MetricTypeCounter   MetricType = "counter"
	MetricTypeGauge     MetricType = "gauge"
	MetricTypeHistogram MetricType = "histogram"
	MetricTypeSummary   MetricType = "summary"
)

MetricType constants for supported OTEL metric types.

type OTLPExporter

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

OTLPExporter implements Exporter by POSTing OTLP JSON to an HTTP endpoint. It avoids the OpenTelemetry SDK dependency by building the JSON wire format directly.

func NewOTLPExporter

func NewOTLPExporter(endpoint string, headers map[string]string, logger *slog.Logger) *OTLPExporter

NewOTLPExporter creates a new OTLP HTTP exporter. endpoint should be the base URL of the OTLP collector (e.g., "http://localhost:4318"). HTTP versus HTTPS is selected explicitly by the endpoint URL scheme.

func (*OTLPExporter) ExportMetrics

func (e *OTLPExporter) ExportMetrics(ctx context.Context, metrics []*MetricData) error

ExportMetrics marshals metrics into OTLP JSON and POSTs to /v1/metrics.

func (*OTLPExporter) ExportSpans

func (e *OTLPExporter) ExportSpans(ctx context.Context, spans []*SpanData) error

ExportSpans marshals spans into OTLP JSON and POSTs to /v1/traces.

func (*OTLPExporter) Shutdown

func (e *OTLPExporter) Shutdown(_ context.Context) error

Shutdown closes idle connections on the underlying HTTP client.

type PrometheusMetric

type PrometheusMetric struct {
	Name   string
	Help   string
	Type   string
	Labels map[string]string
	Value  float64
	// For histograms
	Buckets map[float64]uint64
	Count   uint64
	Sum     float64
	// For summaries
	Quantiles map[float64]float64
}

PrometheusMetric represents a Prometheus-style metric for mapping to OTEL format.

type QuantileValue

type QuantileValue struct {
	// Quantile is the quantile (e.g., 0.5, 0.9, 0.99).
	Quantile float64 `json:"quantile"`

	// Value is the quantile value.
	Value float64 `json:"value"`
}

QuantileValue represents a summary quantile.

type RegistryInterface

type RegistryInterface interface {
	RegisterWithConfig(config component.RegistrationConfig) error
}

RegistryInterface defines the interface for component registration.

type SpanCollector

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

SpanCollector collects spans from agent events.

func NewSpanCollector

func NewSpanCollector(serviceName, serviceVersion string, samplingRate float64) *SpanCollector

NewSpanCollector creates a new span collector.

func (*SpanCollector) FlushCompleted

func (sc *SpanCollector) FlushCompleted() []*SpanData

FlushCompleted returns and clears completed spans.

func (*SpanCollector) ProcessEvent

func (sc *SpanCollector) ProcessEvent(_ context.Context, data []byte) error

ProcessEvent processes an agent event and creates/updates spans.

func (*SpanCollector) ProcessMessage

func (sc *SpanCollector) ProcessMessage(_ context.Context, subject string, data []byte) error

ProcessMessage processes a BaseMessage envelope published by the agentic loop. It dispatches on the message category to create or update spans.

func (*SpanCollector) Stats

func (sc *SpanCollector) Stats() map[string]int64

Stats returns collector statistics.

type SpanData

type SpanData struct {
	// TraceID is the trace identifier.
	TraceID string `json:"trace_id"`

	// SpanID is the span identifier.
	SpanID string `json:"span_id"`

	// ParentSpanID is the parent span identifier.
	ParentSpanID string `json:"parent_span_id,omitempty"`

	// Name is the span name.
	Name string `json:"name"`

	// Kind is the span kind (client, server, internal, producer, consumer).
	Kind string `json:"kind"`

	// StartTime is when the span started.
	StartTime time.Time `json:"start_time"`

	// EndTime is when the span ended.
	EndTime time.Time `json:"end_time,omitempty"`

	// Status indicates the span status.
	Status SpanStatus `json:"status"`

	// Attributes are span attributes.
	Attributes map[string]any `json:"attributes,omitempty"`

	// Events are span events.
	Events []SpanEvent `json:"events,omitempty"`

	// Links are span links.
	Links []SpanLink `json:"links,omitempty"`
}

SpanData represents collected span information.

type SpanEvent

type SpanEvent struct {
	// Name is the event name.
	Name string `json:"name"`

	// Timestamp is when the event occurred.
	Timestamp time.Time `json:"timestamp"`

	// Attributes are event attributes.
	Attributes map[string]any `json:"attributes,omitempty"`
}

SpanEvent represents an event within a span.

type SpanLink struct {
	// TraceID is the linked trace ID.
	TraceID string `json:"trace_id"`

	// SpanID is the linked span ID.
	SpanID string `json:"span_id"`

	// Attributes are link attributes.
	Attributes map[string]any `json:"attributes,omitempty"`
}

SpanLink represents a link to another span.

type SpanStatus

type SpanStatus struct {
	// Code is the status code (unset, ok, error).
	Code string `json:"code"`

	// Message is an optional status message.
	Message string `json:"message,omitempty"`
}

SpanStatus represents the status of a span.

Jump to

Keyboard shortcuts

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