diff --git a/public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx b/public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx index 14ff7b7cc83..494a4873b72 100644 --- a/public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx +++ b/public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx @@ -1,7 +1,9 @@ -import React from 'react'; +import { css } from '@emotion/css'; +import React, { useEffect, useState } from 'react'; import useAsync from 'react-use/lib/useAsync'; -import { InlineField, InlineFieldRow } from '@grafana/ui'; +import { GrafanaTheme2 } from '@grafana/data'; +import { Alert, InlineField, InlineFieldRow, useStyles2 } from '@grafana/ui'; import { AdHocFilter } from '../../../../features/variables/adhoc/picker/AdHocFilter'; import { AdHocVariableFilter } from '../../../../features/variables/types'; @@ -19,7 +21,28 @@ export function ServiceGraphSection({ query: TempoQuery; onChange: (value: TempoQuery) => void; }) { + const styles = useStyles2(getStyles); + const dsState = useAsync(() => getDS(graphDatasourceUid), [graphDatasourceUid]); + + // Check if service graph metrics are being collected. If not, displays a warning + const [hasKeys, setHasKeys] = useState(undefined); + useEffect(() => { + async function fn(ds: PrometheusDatasource) { + const keys = await ds.getTagKeys({ + series: [ + 'traces_service_graph_request_server_seconds_sum', + 'traces_service_graph_request_total', + 'traces_service_graph_request_failed_total', + ], + }); + setHasKeys(Boolean(keys.length)); + } + if (!dsState.loading && dsState.value) { + fn(dsState.value as PrometheusDatasource); + } + }, [dsState]); + if (dsState.loading) { return null; } @@ -73,6 +96,19 @@ export function ServiceGraphSection({ /> + {hasKeys === false ? ( + + Please ensure that service graph metrics are set up correctly according to the{' '} + + Tempo documentation + + . + + ) : null} ); } @@ -95,3 +131,10 @@ function queryToFilter(query: string): AdHocVariableFilter[] { function filtersToQuery(filters: AdHocVariableFilter[]): string { return `{${filters.map((f) => `${f.key}${f.operator}"${f.value}"`).join(',')}}`; } + +const getStyles = (theme: GrafanaTheme2) => ({ + alert: css` + max-width: 75ch; + margin-top: ${theme.spacing(2)}; + `, +});