Why this epic
Migrating Grafana (and Datadog) dashboards onto existing OTel data already in Elasticsearch fails on vocabulary, not on the query engine. Source dashboards use Prometheus/cAdvisor (or Datadog) metric names; Elastic stores dotted OTel semantic-convention fields via OTLP. Bridging them is the metric_map program started by #305.
Live evidence (origin/main @ 5da0dd2, ES seeded with real OTel k8s fields)
Real Grafana Kubernetes / Compute Resources / Pod dashboard (16 panels), --field-profile otel --es-url --preflight:
- Baseline, no map: 0/16 panels. Every metric
missing in required_target_contract.json even though the equivalent dotted OTel field exists (57 fields discovered).
- With map, Class-1 renames applied:
container_memory_working_set_bytes → container.memory.working_set and container_memory_rss → container.memory.rss flipped to confirmed.
- Class-2 not applied:
container_network_{receive,transmit}_bytes_total → k8s.pod.network.io {direction} stayed missing; recorded as a gap, k8s.pod.network.io never emitted.
- Gaps not surfaced:
metric_map_gaps()/warnings() are populated but no artifact reads them.
- Recording rules (5) and cross-data-stream limits/requests have no single-rename target.
Scope / sub-issues
Related (separate source track)
Why this epic
Migrating Grafana (and Datadog) dashboards onto existing OTel data already in Elasticsearch fails on vocabulary, not on the query engine. Source dashboards use Prometheus/cAdvisor (or Datadog) metric names; Elastic stores dotted OTel semantic-convention fields via OTLP. Bridging them is the
metric_mapprogram started by #305.Live evidence (origin/main @ 5da0dd2, ES seeded with real OTel k8s fields)
Real Grafana Kubernetes / Compute Resources / Pod dashboard (16 panels),
--field-profile otel --es-url --preflight:missinginrequired_target_contract.jsoneven though the equivalent dotted OTel field exists (57 fields discovered).container_memory_working_set_bytes → container.memory.working_setandcontainer_memory_rss → container.memory.rssflipped toconfirmed.container_network_{receive,transmit}_bytes_total → k8s.pod.network.io {direction}stayedmissing; recorded as a gap,k8s.pod.network.ionever emitted.metric_map_gaps()/warnings()are populated but no artifact reads them.Scope / sub-issues
attribute_filter→ WHERE,transform→ rate,unit_scale→ scaling); until then, surface gaps/warnings in report + panel notes.metric_mapin the native PromQL path (currently bypassed).Related (separate source track)