elastic / elastic/observability-migration-platform
native PROMQL: Kibana does not forward dashboard control params into PromQL label matchers
- Dominant language
- Python
- Stars
- 6
- Forks
- 8
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 23
Description
## Summary
Panels with Grafana template variable label matchers — e.g. `{instance=~"$instance"}` — cannot use the native `PROMQL` ES|QL command in Kibana dashboard context, and are currently translated via the ES|QL time-series path instead.
## Root cause
The ES 9.5+ PROMQL source command supports named params in PromQL label filters (e.g. `{instance=~?instance}`). However, **Kibana does not forward dashboard control values as named params inside the PROMQL expression**. Kibana only injects `?_tstart` and `?_tend` at the command-argument level (e.g. `PROMQL index=... start=?_tstart end=?_tend value=(...)`). All other `?param` references inside the PromQL expression itself are left unbound, causing Kibana to report:
```
Parameter [?instance] value not found
```
## Current behaviour
Any panel whose PromQL expression contains a template-variable label matcher (e.g. `{instance=~"$instance"}`, `{job="$job"}`) is blocked from the native PROMQL path (`panels.py:2105`, `_promql_label_matcher_has_template_variable`). The fallback is ES|QL time-series (`WHERE instance RLIKE ?instance`) where `?instance` IS forwarded correctly at the outer ES|QL level.
## Impact
This affects virtually all real-world Grafana dashboards that use instance/job/namespace controls. For the Redis 763 dashboard all 13 panels are blocked because every expression has `{instance=~"$instance"}`.
Panels without any template-variable label matchers (or with only metric-level filters that don't reference dashboard controls) could use native PROMQL, but that case is rare in practice.
## Desired behaviour
Once Kibana forwards dashboard control variables as named params inside PROMQL expressions, the translator can remove (or relax) the `_promql_label_matcher_has_template_variable` guard and let `_promql_label_matcher_vars_to_params` rewrite `{instance=~"$instance"}` → `{instance=~?instance}` as originally intended.
The guard is self-documented with a `# Revisit when Kibana forwards control params into PROMQL expressions` comment so it's easy to find once the Kibana side ships.
## References
- Translator guard: `observability_migration/adapters/source/grafana/panels.py:2105`
- Param rewriter (already implemented, unused for dashboard panels): `_promql_label_matcher_vars_to_params` in `promql.py`
- Confirmed by @felixbarny (issue #318): bare `PROMQL index=... value=(...)` works for the command arguments; the label-matcher param gap is the remaining blocker
Contributor guide
Assessment
This issue has not been assessed yet.