# OpenTelemetry Collector. Mounted read-only by the root docker-compose.yml. # Development defaults: no auth, no TLS. # # The gateway exports OTLP/HTTP spans here when OTEL_EXPORTER_OTLP_ENDPOINT is # set. The traces pipeline fans out three ways, each independent - Tempo being # down cannot stop metrics: # # gateway --OTLP--> otlp receiver --+--> otlp/tempo --> Tempo (storage) # +--> spanmetrics --> :8889 --> Prometheus # \--> debug --> stdout receivers: otlp: protocols: http: endpoint: 0.0.0.0:4318 grpc: endpoint: 0.0.0.0:4317 connectors: # Spans in, RED metrics out: traces_span_metrics_calls_total (rate + errors # via status_code) and _duration_milliseconds (latency). spanmetrics: namespace: traces.span.metrics histogram: explicit: buckets: [5ms, 25ms, 100ms, 250ms, 500ms, 1s, 2s, 5s, 10s, 30s, 60s, 120s] # Every dimension multiplies the series count, so only bounded attributes # are listed. gen_ai.request.model / gen_ai.response.model are deliberately # ABSENT - they stay on the span for Tempo but are unbounded. The gateway # supplies frosty.metrics.model as their bounded twin, capped at # FROSTY_OTEL_MODEL_CARDINALITY_CAP distinct values (see decision-log 53). dimensions: - name: gen_ai.provider.name - name: frosty.metrics.model - name: gen_ai.response.finish_reason - name: gen_ai.stream exemplars: enabled: false # Divides the 15s scrape interval, so a scrape never reads a half-updated # series. Expiration stops a dead series being exported forever. metrics_flush_interval: 15s metrics_expiration: 30m processors: batch: {} exporters: otlp/tempo: endpoint: tempo-distributor:4317 tls: insecure: true # Scraped as job `otel-spanmetrics`. Resource attributes are not converted to # labels wholesale, to keep cardinality bounded. prometheus: endpoint: 0.0.0.0:8889 send_timestamps: true metric_expiration: 30m resource_to_telemetry_conversion: enabled: false # `docker compose logs -f otel-collector`. Raise to `detailed` to see attributes. debug: verbosity: normal service: telemetry: metrics: # `address` defaults to :8888 and applies IN ADDITION to `readers`, which # double-binds the port and crash-loops the collector. Blanking it makes # `readers` authoritative and silences the deprecation warning. address: "" readers: - pull: exporter: prometheus: host: 0.0.0.0 port: 8888 pipelines: traces: receivers: [otlp] processors: [batch] exporters: [otlp/tempo, spanmetrics, debug] metrics/spanmetrics: receivers: [spanmetrics] processors: [batch] exporters: [prometheus]