From 9a62db6943ee770286d1b39053428f05cc40a858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Bedi?= Date: Wed, 28 Jul 2021 16:34:46 +0200 Subject: [PATCH] Exemplars: Disable exemplars only on query it failed (#37296) --- .../prometheus/components/PromExemplarField.tsx | 12 +++++++----- .../prometheus/components/PromExploreExtraField.tsx | 1 + .../prometheus/components/PromQueryEditor.tsx | 7 ++++++- .../__snapshots__/PromQueryEditor.test.tsx.snap | 1 + .../app/plugins/datasource/prometheus/datasource.ts | 12 ++++++------ 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/components/PromExemplarField.tsx b/public/app/plugins/datasource/prometheus/components/PromExemplarField.tsx index 59bceca842f..42412381868 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExemplarField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExemplarField.tsx @@ -3,25 +3,27 @@ import { IconButton, InlineLabel, Tooltip, useStyles2 } from '@grafana/ui'; import { css, cx } from '@emotion/css'; import React, { useEffect, useState } from 'react'; import { PrometheusDatasource } from '../datasource'; +import { filter } from 'rxjs/operators'; interface Props { isEnabled: boolean; onChange: (isEnabled: boolean) => void; datasource: PrometheusDatasource; + refId: string; } -export function PromExemplarField({ datasource, onChange, isEnabled }: Props) { - const [error, setError] = useState(); +export function PromExemplarField({ datasource, onChange, isEnabled, refId }: Props) { + const [error, setError] = useState(null); const styles = useStyles2(getStyles); useEffect(() => { - const subscription = datasource.exemplarErrors.subscribe((err) => { - setError(err); + const subscription = datasource.exemplarErrors.pipe(filter((value) => refId === value.refId)).subscribe((err) => { + setError(err.error); }); return () => { subscription.unsubscribe(); }; - }, [datasource]); + }, [datasource, refId]); const iconButtonStyles = cx( { diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx index 283b96e2077..575b0b910a5 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx @@ -78,6 +78,7 @@ export const PromExploreExtraField: React.FC = memo( onChange({ ...query, exemplar: isEnabled })} datasource={datasource} diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx index ed72724567a..280fa6ef840 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryEditor.tsx @@ -223,7 +223,12 @@ export class PromQueryEditor extends PureComponent /> - + } /> diff --git a/public/app/plugins/datasource/prometheus/components/__snapshots__/PromQueryEditor.test.tsx.snap b/public/app/plugins/datasource/prometheus/components/__snapshots__/PromQueryEditor.test.tsx.snap index 1d8aa57be7e..daa910034ad 100644 --- a/public/app/plugins/datasource/prometheus/components/__snapshots__/PromQueryEditor.test.tsx.snap +++ b/public/app/plugins/datasource/prometheus/components/__snapshots__/PromQueryEditor.test.tsx.snap @@ -203,6 +203,7 @@ exports[`Render PromQueryEditor with basic options should render 1`] = ` } isEnabled={true} onChange={[Function]} + refId="A" /> } diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index a7623cdd43c..75cfaae4870 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -45,7 +45,7 @@ import PrometheusMetricFindQuery from './metric_find_query'; import { DEFAULT_STEP_MODE } from './components/PromQueryEditor'; export const ANNOTATION_QUERY_STEP_DEFAULT = '60s'; -const EXEMPLARS_NOT_AVAILABLE = 'Exemplars for this data source are not available.'; +const EXEMPLARS_NOT_AVAILABLE = 'Exemplars for this query are not available.'; const GET_AND_POST_METADATA_ENDPOINTS = ['api/v1/query', 'api/v1/query_range', 'api/v1/series', 'api/v1/labels']; export class PrometheusDatasource extends DataSourceApi { @@ -64,7 +64,7 @@ export class PrometheusDatasource extends DataSourceApi exemplarTraceIdDestinations: ExemplarTraceIdDestination[] | undefined; lookupsDisabled: boolean; customQueryParameters: any; - exemplarErrors: Subject = new Subject(); + exemplarErrors: Subject<{ refId: string; error: string | null }> = new Subject(); constructor( instanceSettings: DataSourceInstanceSettings, @@ -267,12 +267,12 @@ export class PrometheusDatasource extends DataSourceApi exemplarTarget.requestId += '_exemplar'; queries.push(this.createQuery(exemplarTarget, options, start, end)); activeTargets.push(exemplarTarget); - this.exemplarErrors.next(); + this.exemplarErrors.next({ refId: exemplarTarget.refId, error: null }); } target.exemplar = false; } if (target.exemplar && target.instant) { - this.exemplarErrors.next('Exemplars are not available for instant queries.'); + this.exemplarErrors.next({ refId: target.refId, error: 'Exemplars are not available for instant queries.' }); } queries.push(this.createQuery(target, options, start, end)); activeTargets.push(target); @@ -385,8 +385,8 @@ export class PrometheusDatasource extends DataSourceApi if (query.exemplar) { return this.getExemplars(query).pipe( - catchError((err: FetchError) => { - this.exemplarErrors.next(EXEMPLARS_NOT_AVAILABLE); + catchError(() => { + this.exemplarErrors.next({ refId: query.refId, error: EXEMPLARS_NOT_AVAILABLE }); return of({ data: [], state: LoadingState.Done,