[FEATURE] Prometheus: add Exemplars support - #799
julianocosta89 wants to merge 11 commits into
Conversation
f0fb9a8 to
7664c7d
Compare
…t method
Add an optional `exemplars: { enable: boolean }` section to the
PrometheusDatasource spec, exposed in the datasource editor as a
toggle and validated by the CUE schema.
Add a `queryExemplars` method to the Prometheus client hitting
GET /api/v1/query_exemplars with the same query parameters and
authentication handling as the other API calls. The endpoint is also
added to the default proxy allowedEndpoints list.
Related to perses/perses#3445
Signed-off-by: Juliano Costa <juliano.costa@datadoghq.com>
When the selected datasource has exemplars enabled in its spec and the query runs in range mode, fire a query_exemplars request alongside the range query (same PromQL and time range, in parallel) and attach the converted exemplar data to the returned TimeSeriesData. Exemplar timestamps are converted from seconds to ms and values are parsed as numbers. A failing exemplar request never breaks the panel: the error is logged and the query result is returned without exemplars. Related to perses/perses#3445 Signed-off-by: Juliano Costa <juliano.costa@datadoghq.com>
fc0b4a9 to
543b09a
Compare
|
Please add a screenshot to your PR desc 🙏 |
|
@AntoineThebaud screenshots added here and in perses/shared#278 |
|
This depends on perses/shared#278 |
…ditor Address maintainer feedback from PR perses#799: the Exemplars heading and toggle now render before HTTPSettingsEditor as part of the General Settings section. Signed-off-by: Juliano Costa <juliano.costa@datadoghq.com>
|
@AntoineThebaud moved up 🙏🏽
|
|
I think this new feature is worth mentionning in the functionnal documentation of the plugin, could you please add something there? https://github.com/perses/plugins/blob/main/docs%2Fprometheus%2FREADME.md |
Resolve conflict in get-time-series-data.ts: keep upstream's earlier 'isInstant' declaration (moved before the time-range alignment) and drop the duplicate introduced by the merge; keep the exemplars fetching logic. Signed-off-by: Juliano Costa <juliano.costa@datadoghq.com>
Add a functional documentation section about the new exemplars support: opt-in at the datasource level, fetched in parallel of range queries via /api/v1/query_exemplars and rendered as pin-able diamond markers on the Time Series Chart. Signed-off-by: Juliano Costa <juliano.costa@datadoghq.com>
|
@AntoineThebaud, doc added ✅ |
|
@julianocosta89 the shared package has been released & it includes the exemplar metadata dialog. Actually #817 is upgrading the dep for all plugins so once this one is merged you'll just have to update your branch with the last state of main. |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved moderate issues remain in error handling and Go SDK parity, along with a documentation nit.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds opt-in Prometheus exemplar support for datasource configuration and time-series data fetching, with rendering deferred to a follow-up.
Changes:
- Adds exemplar schema, editor toggle, proxy access, and client API support.
- Fetches and converts exemplars alongside range queries.
- Adds tests and documentation.
File summaries
| File | Summary | Final review note |
|---|---|---|
prometheus/src/plugins/types.ts |
Adds exemplar datasource types. | Moderate (2 votes): mirror the field and builder option in the Go SDK. |
prometheus/src/plugins/PrometheusDatasourceEditor.tsx |
Adds exemplar configuration UI. | — |
prometheus/src/plugins/prometheus-time-series-query/plugin.test.ts |
Tests exemplar behavior and conversion. | — |
prometheus/src/plugins/prometheus-time-series-query/get-time-series-data.ts |
Fetches and transforms exemplars. | Moderate (3 votes): handle rejection immediately. Moderate (1 vote): handle resolved API error responses. |
prometheus/src/plugins/prometheus-datasource.tsx |
Exposes the exemplar client method. | — |
prometheus/src/plugins/prometheus-datasource.test.ts |
Tests exemplar endpoint requests. | — |
prometheus/src/model/prometheus-client.ts |
Adds the exemplar API client method. | — |
prometheus/src/model/api-types.ts |
Defines exemplar API types. | — |
prometheus/schemas/datasource/prometheus.cue |
Adds exemplar datasource schema. | Moderate (1 vote): add the corresponding Go SDK field, option, documentation, and tests. |
docs/prometheus/README.md |
Documents exemplar configuration and behavior. | Nit (3 votes): correct the documented marker interaction on lines 90 and 100. |
Review details
Suppressed comments (3)
docs/prometheus/README.md:102
- The README links
docs/prometheus/model.mdas the technical model documentation, but that datasource example still omits the newexemplarsfield. Add the field there as well so users consulting the canonical model page can discover this configuration.
exemplars:
enable: true
**prometheus/schemas/datasource/prometheus.cue:28**
* This adds `exemplars` to the CUE/TypeScript datasource contract, but the public Go SDK still has no serialized `Exemplars` field in `prometheus/sdk/go/datasource/datasource.go:29-34` and no builder option in `options.go`. Dashboard-as-Code users therefore cannot enable this feature, leaving the datasource representations inconsistent; add the SDK field/option and corresponding docs/tests before publishing the schema change.
exemplars?: {
enable: bool
}
**prometheus/src/plugins/prometheus-time-series-query/get-time-series-data.ts:155**
* Prometheus can return a query failure as a resolved `status: 'error'` response, since `QueryExemplarsResponse` is an `ApiResponse` union. This code only handles rejected promises, so that failure is silently converted to missing exemplars and no warning is logged, contrary to the documented fallback; check the response status and warn/ignore error responses before attaching the data.
exemplarResponse = await exemplarPromise;
} catch (err) {
console.warn('Failed to fetch exemplars', err);
}
- **Files reviewed:** 10/10 changed files
- **Comments generated:** 3
- **Review effort level:** Lite
</details>
---
💡 <a href="/perses/plugins/new/main?filename=.github/skills/code-review/SKILL.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add a `code-review` agent skill</a> or configure MCP servers for context-aware, tailored reviews. <a href="https://docs.github.com/copilot/how-tos/use-copilot-agents/request-a-code-review/use-code-review?tool=webui#mcp-servers-and-agent-skills" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn more in the docs.</a>
…exemplars in the Go SDK - Attach the rejection handler when the exemplar promise is created so a fast-failing /api/v1/query_exemplars request cannot surface as an unhandled rejection while the range query is still running - Ignore exemplar responses that resolve with an error status - Add the exemplars field to the PrometheusDatasource Go SDK PluginSpec along with the EnableExemplars() builder option, test and docs - Document exemplars in docs/prometheus/model.md and the Go SDK doc Signed-off-by: Juliano Costa <juliano.costa@datadoghq.com>
Clicking an exemplar marker opens the ExemplarMetadataDialog with the series labels, exemplar labels, value and timestamp; it does not pin the chart tooltip. Align the docs with the actual TimeSeriesChart behavior. Signed-off-by: Juliano Costa <juliano.costa@datadoghq.com>
4f25939 to
71131a0
Compare
|
Addressed comments from Copilot |

Description
Part of #3445 (perses/perses#3445). Depends on the exemplars contract in perses/spec ().
Summary
Adds exemplars support to the Prometheus datasource and
PrometheusTimeSeriesQuery— the data path. Rendering in TimeSeriesChart follows in a follow-up PR stacked on this one.PrometheusDatasource
exemplars: { enable: boolean }section in the datasource spec — off by default, so existing datasources and dashboards are unaffected:prometheus/schemas/datasource/prometheus.cue— CUE schema for the new sectionprometheus/src/plugins/types.ts—PrometheusDatasourceSpec.exemplars?PrometheusDatasourceEditor.tsx— new "Exemplars" section with an "Enable exemplars"Switch(respects readonly mode; the section is removed from the spec when toggled off)queryExemplars()client method hittingGET /api/v1/query_exemplars?query=...&start=...&end=..., with API types (QueryExemplarsRequestParameters,ExemplarSeries,ExemplarData,QueryExemplarsResponse) modeled on the Prometheus docs.GET /api/v1/query_exemplars) and exposed onPrometheusClientvia the usualwrapClientMethod.PrometheusTimeSeriesQuery
query_exemplarsrequest with the same PromQL + time range is fired inparallel with the range query.
UnixTimeMs(× 1000), values (Prometheus strings) → numbers.TimeSeriesData.exemplarsper the spec contract.console.warn) and the series data is returned without exemplars.Testing
query_exemplarsclient call, exemplar enabled/disabled behavior, exemplar-request failure fallback, and unit conversion.turbo run type-check/test(30 packages),lint(31),oxfmtclean,make test-schemas-plugins(24 CUE schema tests),make lint-pluginspass.Follow-up
Stacked on this branch:
feat(timeserieschart)PR rendering exemplars as clickable diamond markers (#800).Screenshots
There are more screenshots available at: #800
Checklist
[<catalog_entry>] <commit message>naming convention using one of thefollowing
catalog_entryvalues:FEATURE,ENHANCEMENT,BUGFIX,BREAKINGCHANGE,DOC,IGNORE.UI Changes