tempoPlugin.e6ea62de584e378b96ee.js.map 79 KB

1
  1. {"version":3,"file":"tempoPlugin.e6ea62de584e378b96ee.js","mappings":"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","sources":["webpack://grafana/./public/app/plugins/datasource/tempo/language_provider.ts","webpack://grafana/./public/app/plugins/datasource/tempo/syntax.ts","webpack://grafana/./public/app/plugins/datasource/tempo/QueryEditor/NativeSearch.tsx","webpack://grafana/./public/app/plugins/datasource/tempo/QueryEditor/utils.ts","webpack://grafana/./public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx","webpack://grafana/./public/app/plugins/datasource/tempo/QueryEditor/QueryField.tsx","webpack://grafana/./public/app/plugins/datasource/tempo/configuration/LokiSearchSettings.tsx","webpack://grafana/./public/app/plugins/datasource/tempo/configuration/SearchSettings.tsx","webpack://grafana/./public/app/plugins/datasource/tempo/configuration/ServiceGraphSettings.tsx","webpack://grafana/./public/app/plugins/datasource/tempo/datasource.ts","webpack://grafana/./public/app/plugins/datasource/tempo/module.ts","webpack://grafana/./public/app/plugins/datasource/tempo/configuration/ConfigEditor.tsx","webpack://grafana/./public/app/plugins/datasource/tempo/CheatSheet.tsx"],"sourcesContent":["import { Value } from 'slate';\n\nimport { HistoryItem, LanguageProvider, SelectableValue } from '@grafana/data';\nimport { CompletionItemGroup, TypeaheadInput, TypeaheadOutput } from '@grafana/ui';\n\nimport { TempoDatasource } from './datasource';\n\nexport default class TempoLanguageProvider extends LanguageProvider {\n datasource: TempoDatasource;\n tags?: string[];\n constructor(datasource: TempoDatasource, initialValues?: any) {\n super();\n\n this.datasource = datasource;\n Object.assign(this, initialValues);\n }\n\n request = async (url: string, params = {}) => {\n const res = await this.datasource.metadataRequest(url, params);\n return res?.data;\n };\n\n start = async () => {\n await this.fetchTags();\n return [];\n };\n\n async fetchTags() {\n const response = await this.request('/api/search/tags', []);\n this.tags = response.tagNames;\n }\n\n provideCompletionItems = async (\n { prefix, text, value, labelKey, wrapperClasses }: TypeaheadInput,\n context: { history: Array<HistoryItem<any>> } = { history: [] }\n ): Promise<TypeaheadOutput> => {\n const emptyResult: TypeaheadOutput = { suggestions: [] };\n\n if (!value) {\n return emptyResult;\n }\n\n const query = value.endText.getText();\n const isValue = query[query.indexOf(text) - 1] === '=';\n if (isValue || text === '=') {\n return this.getTagValueCompletionItems(value);\n }\n return this.getTagsCompletionItems();\n };\n\n getTagsCompletionItems = (): TypeaheadOutput => {\n const { tags } = this;\n const suggestions: CompletionItemGroup[] = [];\n\n if (tags?.length) {\n suggestions.push({\n label: `Tag`,\n items: tags.map((tag) => ({ label: tag })),\n });\n }\n\n return { suggestions };\n };\n\n async getTagValueCompletionItems(value: Value) {\n const tags = value.endText.getText().split(' ');\n\n let tagName = tags[tags.length - 1] ?? '';\n tagName = tagName.split('=')[0];\n\n const response = await this.request(`/api/search/tag/${tagName}/values`, []);\n const suggestions: CompletionItemGroup[] = [];\n\n if (response && response.tagValues) {\n suggestions.push({\n label: `Tag Values`,\n items: response.tagValues.map((tagValue: string) => ({ label: tagValue })),\n });\n }\n return { suggestions };\n }\n\n async getOptions(tag: string): Promise<Array<SelectableValue<string>>> {\n const response = await this.request(`/api/search/tag/${tag}/values`);\n let options: Array<SelectableValue<string>> = [];\n\n if (response && response.tagValues) {\n options = response.tagValues.map((v: string) => ({\n value: v,\n label: v,\n }));\n }\n\n return options;\n }\n}\n","import { Grammar } from 'prismjs';\n\nexport const tokenizer: Grammar = {\n key: {\n pattern: /[^\\s]+(?==)/,\n alias: 'attr-name',\n },\n operator: /[=]/,\n value: [\n {\n pattern: /\"(.+)\"/,\n },\n {\n pattern: /[^\\s]+/,\n },\n ],\n};\n","import { css } from '@emotion/css';\nimport Prism from 'prismjs';\nimport React, { useCallback, useState, useEffect, useMemo } from 'react';\nimport { Node } from 'slate';\n\nimport { GrafanaTheme2, isValidGoDuration, SelectableValue, toOption } from '@grafana/data';\nimport { getTemplateSrv, TemplateSrv } from '@grafana/runtime';\nimport {\n InlineFieldRow,\n InlineField,\n Input,\n QueryField,\n SlatePrism,\n BracesPlugin,\n TypeaheadInput,\n TypeaheadOutput,\n Alert,\n useStyles2,\n fuzzyMatch,\n Select,\n} from '@grafana/ui';\nimport { notifyApp } from 'app/core/actions';\nimport { createErrorNotification } from 'app/core/copy/appNotification';\nimport { dispatch } from 'app/store/store';\n\nimport { TempoDatasource, TempoQuery } from '../datasource';\nimport TempoLanguageProvider from '../language_provider';\nimport { tokenizer } from '../syntax';\n\ninterface Props {\n datasource: TempoDatasource;\n query: TempoQuery;\n onChange: (value: TempoQuery) => void;\n onBlur?: () => void;\n onRunQuery: () => void;\n}\n\nconst PRISM_LANGUAGE = 'tempo';\nconst durationPlaceholder = 'e.g. 1.2s, 100ms';\nconst plugins = [\n BracesPlugin(),\n SlatePrism({\n onlyIn: (node: Node) => node.object === 'block' && node.type === 'code_block',\n getSyntax: () => PRISM_LANGUAGE,\n }),\n];\n\nPrism.languages[PRISM_LANGUAGE] = tokenizer;\n\nconst NativeSearch = ({ datasource, query, onChange, onBlur, onRunQuery }: Props) => {\n const styles = useStyles2(getStyles);\n const languageProvider = useMemo(() => new TempoLanguageProvider(datasource), [datasource]);\n const [hasSyntaxLoaded, setHasSyntaxLoaded] = useState(false);\n const [serviceOptions, setServiceOptions] = useState<Array<SelectableValue<string>>>();\n const [spanOptions, setSpanOptions] = useState<Array<SelectableValue<string>>>();\n const [error, setError] = useState(null);\n const [inputErrors, setInputErrors] = useState<{ [key: string]: boolean }>({});\n const [isLoading, setIsLoading] = useState<{\n serviceName: boolean;\n spanName: boolean;\n }>({\n serviceName: false,\n spanName: false,\n });\n\n const loadOptions = useCallback(\n async (name: string, query = '') => {\n const lpName = name === 'serviceName' ? 'service.name' : 'name';\n setIsLoading((prevValue) => ({ ...prevValue, [name]: true }));\n\n try {\n const options = await languageProvider.getOptions(lpName);\n const filteredOptions = options.filter((item) => (item.value ? fuzzyMatch(item.value, query).found : false));\n return filteredOptions;\n } catch (error) {\n if (error?.status === 404) {\n setError(error);\n } else {\n dispatch(notifyApp(createErrorNotification('Error', error)));\n }\n return [];\n } finally {\n setIsLoading((prevValue) => ({ ...prevValue, [name]: false }));\n }\n },\n [languageProvider]\n );\n\n useEffect(() => {\n const fetchOptions = async () => {\n try {\n const [services, spans] = await Promise.all([loadOptions('serviceName'), loadOptions('spanName')]);\n if (query.serviceName && getTemplateSrv().containsTemplate(query.serviceName)) {\n services.push(toOption(query.serviceName));\n }\n setServiceOptions(services);\n if (query.spanName && getTemplateSrv().containsTemplate(query.spanName)) {\n spans.push(toOption(query.spanName));\n }\n setSpanOptions(spans);\n } catch (error) {\n // Display message if Tempo is connected but search 404's\n if (error?.status === 404) {\n setError(error);\n } else {\n dispatch(notifyApp(createErrorNotification('Error', error)));\n }\n }\n };\n fetchOptions();\n }, [languageProvider, loadOptions, query.serviceName, query.spanName]);\n\n useEffect(() => {\n const fetchTags = async () => {\n try {\n await languageProvider.start();\n setHasSyntaxLoaded(true);\n } catch (error) {\n dispatch(notifyApp(createErrorNotification('Error', error)));\n }\n };\n fetchTags();\n }, [languageProvider]);\n\n const onTypeahead = async (typeahead: TypeaheadInput): Promise<TypeaheadOutput> => {\n return await languageProvider.provideCompletionItems(typeahead);\n };\n\n const cleanText = (text: string) => {\n const splittedText = text.split(/\\s+(?=([^\"]*\"[^\"]*\")*[^\"]*$)/g);\n if (splittedText.length > 1) {\n return splittedText[splittedText.length - 1];\n }\n return text;\n };\n\n const onKeyDown = (keyEvent: React.KeyboardEvent) => {\n if (keyEvent.key === 'Enter' && (keyEvent.shiftKey || keyEvent.ctrlKey)) {\n onRunQuery();\n }\n };\n\n const templateSrv: TemplateSrv = getTemplateSrv();\n\n return (\n <>\n <div className={styles.container}>\n <InlineFieldRow>\n <InlineField label=\"Service Name\" labelWidth={14} grow>\n <Select\n inputId=\"service\"\n options={serviceOptions}\n onOpenMenu={() => {\n loadOptions('serviceName');\n }}\n isLoading={isLoading.serviceName}\n value={serviceOptions?.find((v) => v?.value === query.serviceName) || undefined}\n onChange={(v) => {\n onChange({\n ...query,\n serviceName: v?.value || undefined,\n });\n }}\n placeholder=\"Select a service\"\n isClearable\n onKeyDown={onKeyDown}\n aria-label={'select-service-name'}\n allowCustomValue={true}\n />\n </InlineField>\n </InlineFieldRow>\n <InlineFieldRow>\n <InlineField label=\"Span Name\" labelWidth={14} grow>\n <Select\n inputId=\"spanName\"\n options={spanOptions}\n onOpenMenu={() => {\n loadOptions('spanName');\n }}\n isLoading={isLoading.spanName}\n value={spanOptions?.find((v) => v?.value === query.spanName) || undefined}\n onChange={(v) => {\n onChange({\n ...query,\n spanName: v?.value || undefined,\n });\n }}\n placeholder=\"Select a span\"\n isClearable\n onKeyDown={onKeyDown}\n aria-label={'select-span-name'}\n allowCustomValue={true}\n />\n </InlineField>\n </InlineFieldRow>\n <InlineFieldRow>\n <InlineField label=\"Tags\" labelWidth={14} grow tooltip=\"Values should be in the logfmt format.\">\n <QueryField\n additionalPlugins={plugins}\n query={query.search}\n onTypeahead={onTypeahead}\n onBlur={onBlur}\n onChange={(value) => {\n onChange({\n ...query,\n search: value,\n });\n }}\n placeholder=\"http.status_code=200 error=true\"\n cleanText={cleanText}\n onRunQuery={onRunQuery}\n syntaxLoaded={hasSyntaxLoaded}\n portalOrigin=\"tempo\"\n />\n </InlineField>\n </InlineFieldRow>\n <InlineFieldRow>\n <InlineField label=\"Min Duration\" invalid={!!inputErrors.minDuration} labelWidth={14} grow>\n <Input\n id=\"minDuration\"\n value={query.minDuration || ''}\n placeholder={durationPlaceholder}\n onBlur={() => {\n const templatedMinDuration = templateSrv.replace(query.minDuration ?? '');\n if (query.minDuration && !isValidGoDuration(templatedMinDuration)) {\n setInputErrors({ ...inputErrors, minDuration: true });\n } else {\n setInputErrors({ ...inputErrors, minDuration: false });\n }\n }}\n onChange={(v) =>\n onChange({\n ...query,\n minDuration: v.currentTarget.value,\n })\n }\n onKeyDown={onKeyDown}\n />\n </InlineField>\n </InlineFieldRow>\n <InlineFieldRow>\n <InlineField label=\"Max Duration\" invalid={!!inputErrors.maxDuration} labelWidth={14} grow>\n <Input\n id=\"maxDuration\"\n value={query.maxDuration || ''}\n placeholder={durationPlaceholder}\n onBlur={() => {\n const templatedMaxDuration = templateSrv.replace(query.maxDuration ?? '');\n if (query.maxDuration && !isValidGoDuration(templatedMaxDuration)) {\n setInputErrors({ ...inputErrors, maxDuration: true });\n } else {\n setInputErrors({ ...inputErrors, maxDuration: false });\n }\n }}\n onChange={(v) =>\n onChange({\n ...query,\n maxDuration: v.currentTarget.value,\n })\n }\n onKeyDown={onKeyDown}\n />\n </InlineField>\n </InlineFieldRow>\n <InlineFieldRow>\n <InlineField\n label=\"Limit\"\n invalid={!!inputErrors.limit}\n labelWidth={14}\n grow\n tooltip=\"Maximum numbers of returned results\"\n >\n <Input\n id=\"limit\"\n value={query.limit || ''}\n type=\"number\"\n onChange={(v) => {\n let limit = v.currentTarget.value ? parseInt(v.currentTarget.value, 10) : undefined;\n if (limit && (!Number.isInteger(limit) || limit <= 0)) {\n setInputErrors({ ...inputErrors, limit: true });\n } else {\n setInputErrors({ ...inputErrors, limit: false });\n }\n\n onChange({\n ...query,\n limit: v.currentTarget.value ? parseInt(v.currentTarget.value, 10) : undefined,\n });\n }}\n onKeyDown={onKeyDown}\n />\n </InlineField>\n </InlineFieldRow>\n </div>\n {error ? (\n <Alert title=\"Unable to connect to Tempo search\" severity=\"info\" className={styles.alert}>\n Please ensure that Tempo is configured with search enabled. If you would like to hide this tab, you can\n configure it in the <a href={`/datasources/edit/${datasource.uid}`}>datasource settings</a>.\n </Alert>\n ) : null}\n </>\n );\n};\n\nexport default NativeSearch;\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n container: css`\n max-width: 500px;\n `,\n alert: css`\n max-width: 75ch;\n margin-top: ${theme.spacing(2)};\n `,\n});\n","import { DataSourceApi } from '@grafana/data';\nimport { getDataSourceSrv } from '@grafana/runtime';\n\nexport async function getDS(uid?: string): Promise<DataSourceApi | undefined> {\n if (!uid) {\n return undefined;\n }\n\n const dsSrv = getDataSourceSrv();\n try {\n return await dsSrv.get(uid);\n } catch (error) {\n console.error('Failed to load data source', error);\n return undefined;\n }\n}\n","import { css } from '@emotion/css';\nimport React, { useEffect, useState } from 'react';\nimport useAsync from 'react-use/lib/useAsync';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Alert, InlineField, InlineFieldRow, useStyles2 } from '@grafana/ui';\n\nimport { AdHocFilter } from '../../../../features/variables/adhoc/picker/AdHocFilter';\nimport { AdHocVariableFilter } from '../../../../features/variables/types';\nimport { PrometheusDatasource } from '../../prometheus/datasource';\nimport { TempoQuery } from '../datasource';\n\nimport { getDS } from './utils';\n\nexport function ServiceGraphSection({\n graphDatasourceUid,\n query,\n onChange,\n}: {\n graphDatasourceUid?: string;\n query: TempoQuery;\n onChange: (value: TempoQuery) => void;\n}) {\n const styles = useStyles2(getStyles);\n\n const dsState = useAsync(() => getDS(graphDatasourceUid), [graphDatasourceUid]);\n\n // Check if service graph metrics are being collected. If not, displays a warning\n const [hasKeys, setHasKeys] = useState<boolean | undefined>(undefined);\n useEffect(() => {\n async function fn(ds: PrometheusDatasource) {\n const keys = await ds.getTagKeys({\n series: [\n 'traces_service_graph_request_server_seconds_sum',\n 'traces_service_graph_request_total',\n 'traces_service_graph_request_failed_total',\n ],\n });\n setHasKeys(Boolean(keys.length));\n }\n if (!dsState.loading && dsState.value) {\n fn(dsState.value as PrometheusDatasource);\n }\n }, [dsState]);\n\n if (dsState.loading) {\n return null;\n }\n\n const ds = dsState.value as PrometheusDatasource;\n\n if (!graphDatasourceUid) {\n return <div className=\"text-warning\">Please set up a service graph datasource in the datasource settings.</div>;\n }\n\n if (graphDatasourceUid && !ds) {\n return (\n <div className=\"text-warning\">\n Service graph datasource is configured but the data source no longer exists. Please configure existing data\n source to use the service graph functionality.\n </div>\n );\n }\n const filters = queryToFilter(query.serviceMapQuery || '');\n\n return (\n <div>\n <InlineFieldRow>\n <InlineField label=\"Filter\" labelWidth={14} grow>\n <AdHocFilter\n datasource={{ uid: graphDatasourceUid }}\n filters={filters}\n getTagKeysOptions={{\n series: [\n 'traces_service_graph_request_server_seconds_sum',\n 'traces_service_graph_request_total',\n 'traces_service_graph_request_failed_total',\n ],\n }}\n addFilter={(filter: AdHocVariableFilter) => {\n onChange({\n ...query,\n serviceMapQuery: filtersToQuery([...filters, filter]),\n });\n }}\n removeFilter={(index: number) => {\n const newFilters = [...filters];\n newFilters.splice(index, 1);\n onChange({ ...query, serviceMapQuery: filtersToQuery(newFilters) });\n }}\n changeFilter={(index: number, filter: AdHocVariableFilter) => {\n const newFilters = [...filters];\n newFilters.splice(index, 1, filter);\n onChange({ ...query, serviceMapQuery: filtersToQuery(newFilters) });\n }}\n />\n </InlineField>\n </InlineFieldRow>\n {hasKeys === false ? (\n <Alert title=\"No service graph data found\" severity=\"info\" className={styles.alert}>\n Please ensure that service graph metrics are set up correctly according to the{' '}\n <a\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n href=\"https://grafana.com/docs/tempo/next/grafana-agent/service-graphs/\"\n >\n Tempo documentation\n </a>\n .\n </Alert>\n ) : null}\n </div>\n );\n}\n\nfunction queryToFilter(query: string): AdHocVariableFilter[] {\n let match;\n let filters: AdHocVariableFilter[] = [];\n const re = /([\\w_]+)(=|!=|<|>|=~|!~)\"(.*?)\"/g;\n while ((match = re.exec(query)) !== null) {\n filters.push({\n key: match[1],\n operator: match[2],\n value: match[3],\n condition: '',\n });\n }\n return filters;\n}\n\nfunction filtersToQuery(filters: AdHocVariableFilter[]): string {\n return `{${filters.map((f) => `${f.key}${f.operator}\"${f.value}\"`).join(',')}}`;\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n alert: css`\n max-width: 75ch;\n margin-top: ${theme.spacing(2)};\n `,\n});\n","import { css } from '@emotion/css';\nimport React from 'react';\nimport useAsync from 'react-use/lib/useAsync';\n\nimport { QueryEditorProps, SelectableValue } from '@grafana/data';\nimport { config, reportInteraction } from '@grafana/runtime';\nimport {\n Badge,\n FileDropzone,\n InlineField,\n InlineFieldRow,\n InlineLabel,\n QueryField,\n RadioButtonGroup,\n Themeable2,\n withTheme2,\n} from '@grafana/ui';\n\nimport { LokiQueryField } from '../../loki/components/LokiQueryField';\nimport { LokiDatasource } from '../../loki/datasource';\nimport { LokiQuery } from '../../loki/types';\nimport { TempoDatasource, TempoQuery, TempoQueryType } from '../datasource';\n\nimport NativeSearch from './NativeSearch';\nimport { ServiceGraphSection } from './ServiceGraphSection';\nimport { getDS } from './utils';\n\ninterface Props extends QueryEditorProps<TempoDatasource, TempoQuery>, Themeable2 {}\n\nconst DEFAULT_QUERY_TYPE: TempoQueryType = 'traceId';\n\nclass TempoQueryFieldComponent extends React.PureComponent<Props> {\n constructor(props: Props) {\n super(props);\n }\n\n async componentDidMount() {\n // Set initial query type to ensure traceID field appears\n if (!this.props.query.queryType) {\n this.props.onChange({\n ...this.props.query,\n queryType: DEFAULT_QUERY_TYPE,\n });\n }\n }\n\n onChangeLinkedQuery = (value: LokiQuery) => {\n const { query, onChange } = this.props;\n onChange({\n ...query,\n linkedQuery: { ...value, refId: 'linked' },\n });\n };\n\n onRunLinkedQuery = () => {\n this.props.onRunQuery();\n };\n\n onClearResults = () => {\n // Run clear query to clear results\n const { onChange, query, onRunQuery } = this.props;\n onChange({\n ...query,\n queryType: 'clear',\n });\n onRunQuery();\n };\n\n render() {\n const { query, onChange, datasource, app } = this.props;\n\n const logsDatasourceUid = datasource.getLokiSearchDS();\n\n const graphDatasourceUid = datasource.serviceMap?.datasourceUid;\n\n const queryTypeOptions: Array<SelectableValue<TempoQueryType>> = [\n { value: 'traceId', label: 'TraceID' },\n { value: 'upload', label: 'JSON file' },\n { value: 'serviceMap', label: 'Service Graph' },\n ];\n\n if (config.featureToggles.tempoSearch && !datasource?.search?.hide) {\n queryTypeOptions.unshift({ value: 'nativeSearch', label: 'Search - Beta' });\n }\n\n if (logsDatasourceUid) {\n if (!config.featureToggles.tempoSearch) {\n // Place at beginning as Search if no native search\n queryTypeOptions.unshift({ value: 'search', label: 'Search' });\n } else {\n // Place at end as Loki Search if native search is enabled\n queryTypeOptions.push({ value: 'search', label: 'Loki Search' });\n }\n }\n\n return (\n <>\n <InlineFieldRow>\n <InlineField label=\"Query type\">\n <RadioButtonGroup<TempoQueryType>\n options={queryTypeOptions}\n value={query.queryType}\n onChange={(v) => {\n reportInteraction('grafana_traces_query_type_changed', {\n datasourceType: 'tempo',\n app: app ?? '',\n newQueryType: v,\n previousQueryType: query.queryType ?? '',\n });\n\n this.onClearResults();\n\n onChange({\n ...query,\n queryType: v,\n });\n }}\n size=\"md\"\n />\n </InlineField>\n </InlineFieldRow>\n {query.queryType === 'nativeSearch' && (\n <div style={{ maxWidth: '65ch' }}>\n <Badge icon=\"rocket\" text=\"Beta\" color=\"blue\" />\n {config.featureToggles.tempoBackendSearch ? (\n <>&nbsp;Tempo search is currently in beta.</>\n ) : (\n <>\n &nbsp;Tempo search is currently in beta and is designed to return recent traces only. It ignores the\n time range picker. We are actively working on full backend search. Look for improvements in the near\n future!\n </>\n )}\n </div>\n )}\n {query.queryType === 'search' && (\n <SearchSection\n logsDatasourceUid={logsDatasourceUid}\n query={query}\n onRunQuery={this.onRunLinkedQuery}\n onChange={this.onChangeLinkedQuery}\n />\n )}\n {query.queryType === 'nativeSearch' && (\n <NativeSearch\n datasource={this.props.datasource}\n query={query}\n onChange={onChange}\n onBlur={this.props.onBlur}\n onRunQuery={this.props.onRunQuery}\n />\n )}\n {query.queryType === 'upload' && (\n <div className={css({ padding: this.props.theme.spacing(2) })}>\n <FileDropzone\n options={{ multiple: false }}\n onLoad={(result) => {\n this.props.datasource.uploadedJson = result;\n this.props.onRunQuery();\n }}\n />\n </div>\n )}\n {query.queryType === 'traceId' && (\n <InlineFieldRow>\n <InlineField label=\"Trace ID\" labelWidth={14} grow>\n <QueryField\n query={query.query}\n onChange={(val) => {\n onChange({\n ...query,\n query: val,\n queryType: 'traceId',\n linkedQuery: undefined,\n });\n }}\n onBlur={this.props.onBlur}\n onRunQuery={this.props.onRunQuery}\n placeholder={'Enter a Trace ID (run with Shift+Enter)'}\n portalOrigin=\"tempo\"\n />\n </InlineField>\n </InlineFieldRow>\n )}\n {query.queryType === 'serviceMap' && (\n <ServiceGraphSection graphDatasourceUid={graphDatasourceUid} query={query} onChange={onChange} />\n )}\n </>\n );\n }\n}\n\ninterface SearchSectionProps {\n logsDatasourceUid?: string;\n onChange: (value: LokiQuery) => void;\n onRunQuery: () => void;\n query: TempoQuery;\n}\nfunction SearchSection({ logsDatasourceUid, onChange, onRunQuery, query }: SearchSectionProps) {\n const dsState = useAsync(() => getDS(logsDatasourceUid), [logsDatasourceUid]);\n if (dsState.loading) {\n return null;\n }\n\n const ds = dsState.value as LokiDatasource;\n\n if (ds) {\n return (\n <>\n <InlineLabel>Tempo uses {ds.name} to find traces.</InlineLabel>\n <LokiQueryField\n datasource={ds}\n onChange={onChange}\n onRunQuery={onRunQuery}\n query={query.linkedQuery ?? ({ refId: 'linked' } as any)}\n history={[]}\n />\n </>\n );\n }\n\n if (!logsDatasourceUid) {\n return <div className=\"text-warning\">Please set up a Loki search datasource in the datasource settings.</div>;\n }\n\n if (logsDatasourceUid && !ds) {\n return (\n <div className=\"text-warning\">\n Loki search datasource is configured but the data source no longer exists. Please configure existing data source\n to use the search.\n </div>\n );\n }\n\n return null;\n}\n\nexport const TempoQueryField = withTheme2(TempoQueryFieldComponent);\n","import { css } from '@emotion/css';\nimport React from 'react';\n\nimport { DataSourcePluginOptionsEditorProps, GrafanaTheme, updateDatasourcePluginJsonDataOption } from '@grafana/data';\nimport { DataSourcePicker } from '@grafana/runtime';\nimport { Button, InlineField, InlineFieldRow, useStyles } from '@grafana/ui';\n\nimport { TempoJsonData } from '../datasource';\n\ninterface Props extends DataSourcePluginOptionsEditorProps<TempoJsonData> {}\n\nexport function LokiSearchSettings({ options, onOptionsChange }: Props) {\n const styles = useStyles(getStyles);\n\n // Default to the trace to logs datasource if configured and loki search was enabled\n // but only if jsonData.lokiSearch hasn't been set\n const legacyDatasource =\n options.jsonData.tracesToLogs?.lokiSearch !== false ? options.jsonData.tracesToLogs?.datasourceUid : undefined;\n if (legacyDatasource && options.jsonData.lokiSearch === undefined) {\n updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'lokiSearch', {\n datasourceUid: legacyDatasource,\n });\n }\n\n return (\n <div className={css({ width: '100%' })}>\n <h3 className=\"page-heading\">Loki Search</h3>\n\n <div className={styles.infoText}>\n Select a Loki datasource to search for traces. Derived fields must be configured in the Loki data source.\n </div>\n\n <InlineFieldRow className={styles.row}>\n <InlineField tooltip=\"The Loki data source with the service graph data\" label=\"Data source\" labelWidth={26}>\n <DataSourcePicker\n inputId=\"loki-search-data-source-picker\"\n pluginId=\"loki\"\n current={options.jsonData.lokiSearch?.datasourceUid}\n noDefault={true}\n width={40}\n onChange={(ds) =>\n updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'lokiSearch', {\n datasourceUid: ds.uid,\n })\n }\n />\n </InlineField>\n {options.jsonData.lokiSearch?.datasourceUid ? (\n <Button\n type={'button'}\n variant={'secondary'}\n size={'sm'}\n fill={'text'}\n onClick={() => {\n updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'lokiSearch', {\n datasourceUid: undefined,\n });\n }}\n >\n Clear\n </Button>\n ) : null}\n </InlineFieldRow>\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme) => ({\n infoText: css`\n label: infoText;\n padding-bottom: ${theme.spacing.md};\n color: ${theme.colors.textSemiWeak};\n `,\n\n row: css`\n label: row;\n align-items: baseline;\n `,\n});\n","import { css } from '@emotion/css';\nimport React from 'react';\n\nimport { DataSourcePluginOptionsEditorProps, GrafanaTheme, updateDatasourcePluginJsonDataOption } from '@grafana/data';\nimport { InlineField, InlineFieldRow, InlineSwitch, useStyles } from '@grafana/ui';\n\nimport { TempoJsonData } from '../datasource';\n\ninterface Props extends DataSourcePluginOptionsEditorProps<TempoJsonData> {}\n\nexport function SearchSettings({ options, onOptionsChange }: Props) {\n const styles = useStyles(getStyles);\n\n return (\n <div className={styles.container}>\n <h3 className=\"page-heading\">Search</h3>\n <InlineFieldRow className={styles.row}>\n <InlineField tooltip=\"Removes the Search tab from the Tempo query editor.\" label=\"Hide search\" labelWidth={26}>\n <InlineSwitch\n id=\"hideSearch\"\n value={options.jsonData.search?.hide}\n onChange={(event: React.SyntheticEvent<HTMLInputElement>) =>\n updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'search', {\n ...options.jsonData.search,\n hide: event.currentTarget.checked,\n })\n }\n />\n </InlineField>\n </InlineFieldRow>\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme) => ({\n container: css`\n label: container;\n width: 100%;\n `,\n row: css`\n label: row;\n align-items: baseline;\n `,\n});\n","import { css } from '@emotion/css';\nimport React from 'react';\n\nimport { DataSourcePluginOptionsEditorProps, GrafanaTheme, updateDatasourcePluginJsonDataOption } from '@grafana/data';\nimport { DataSourcePicker } from '@grafana/runtime';\nimport { Button, InlineField, InlineFieldRow, useStyles } from '@grafana/ui';\n\nimport { TempoJsonData } from '../datasource';\n\ninterface Props extends DataSourcePluginOptionsEditorProps<TempoJsonData> {}\n\nexport function ServiceGraphSettings({ options, onOptionsChange }: Props) {\n const styles = useStyles(getStyles);\n\n return (\n <div className={css({ width: '100%' })}>\n <h3 className=\"page-heading\">Service Graph</h3>\n\n <div className={styles.infoText}>\n To allow querying service graph data you have to select a Prometheus instance where the data is stored.\n </div>\n\n <InlineFieldRow className={styles.row}>\n <InlineField\n tooltip=\"The Prometheus data source with the service graph data\"\n label=\"Data source\"\n labelWidth={26}\n >\n <DataSourcePicker\n inputId=\"service-graph-data-source-picker\"\n pluginId=\"prometheus\"\n current={options.jsonData.serviceMap?.datasourceUid}\n noDefault={true}\n width={40}\n onChange={(ds) =>\n updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'serviceMap', {\n datasourceUid: ds.uid,\n })\n }\n />\n </InlineField>\n {options.jsonData.serviceMap?.datasourceUid ? (\n <Button\n type={'button'}\n variant={'secondary'}\n size={'sm'}\n fill={'text'}\n onClick={() => {\n updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'serviceMap', {\n datasourceUid: undefined,\n });\n }}\n >\n Clear\n </Button>\n ) : null}\n </InlineFieldRow>\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme) => ({\n infoText: css`\n label: infoText;\n padding-bottom: ${theme.spacing.md};\n color: ${theme.colors.textSemiWeak};\n `,\n\n row: css`\n label: row;\n align-items: baseline;\n `,\n});\n","import { identity, pick, pickBy, groupBy, startCase } from 'lodash';\nimport { EMPTY, from, merge, Observable, of, throwError } from 'rxjs';\nimport { catchError, map, mergeMap, toArray } from 'rxjs/operators';\n\nimport {\n DataQuery,\n DataQueryRequest,\n DataQueryResponse,\n DataSourceApi,\n DataSourceInstanceSettings,\n DataSourceJsonData,\n isValidGoDuration,\n LoadingState,\n ScopedVars,\n} from '@grafana/data';\nimport {\n config,\n BackendSrvRequest,\n DataSourceWithBackend,\n getBackendSrv,\n reportInteraction,\n TemplateSrv,\n getTemplateSrv,\n} from '@grafana/runtime';\nimport { NodeGraphOptions } from 'app/core/components/NodeGraphSettings';\nimport { TraceToLogsOptions } from 'app/core/components/TraceToLogs/TraceToLogsSettings';\nimport { serializeParams } from 'app/core/utils/fetch';\nimport { getDatasourceSrv } from 'app/features/plugins/datasource_srv';\n\nimport { LokiOptions, LokiQuery } from '../loki/types';\nimport { PrometheusDatasource } from '../prometheus/datasource';\nimport { PromQuery } from '../prometheus/types';\n\nimport {\n failedMetric,\n histogramMetric,\n mapPromMetricsToServiceMap,\n serviceMapMetrics,\n totalsMetric,\n} from './graphTransform';\nimport {\n transformTrace,\n transformTraceList,\n transformFromOTLP as transformFromOTEL,\n createTableFrameFromSearch,\n} from './resultTransformer';\n\n// search = Loki search, nativeSearch = Tempo search for backwards compatibility\nexport type TempoQueryType = 'search' | 'traceId' | 'serviceMap' | 'upload' | 'nativeSearch' | 'clear';\n\nexport interface TempoJsonData extends DataSourceJsonData {\n tracesToLogs?: TraceToLogsOptions;\n serviceMap?: {\n datasourceUid?: string;\n };\n search?: {\n hide?: boolean;\n };\n nodeGraph?: NodeGraphOptions;\n lokiSearch?: {\n datasourceUid?: string;\n };\n}\n\nexport interface TempoQuery extends DataQuery {\n query: string;\n // Query to find list of traces, e.g., via Loki\n linkedQuery?: LokiQuery;\n search: string;\n queryType: TempoQueryType;\n serviceName?: string;\n spanName?: string;\n minDuration?: string;\n maxDuration?: string;\n limit?: number;\n serviceMapQuery?: string;\n}\n\ninterface SearchQueryParams {\n minDuration?: string;\n maxDuration?: string;\n limit?: number;\n tags: string;\n start?: number;\n end?: number;\n}\n\nexport const DEFAULT_LIMIT = 20;\n\nexport class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJsonData> {\n tracesToLogs?: TraceToLogsOptions;\n serviceMap?: {\n datasourceUid?: string;\n };\n search?: {\n hide?: boolean;\n };\n nodeGraph?: NodeGraphOptions;\n lokiSearch?: {\n datasourceUid?: string;\n };\n uploadedJson?: string | ArrayBuffer | null = null;\n\n constructor(\n private instanceSettings: DataSourceInstanceSettings<TempoJsonData>,\n private readonly templateSrv: TemplateSrv = getTemplateSrv()\n ) {\n super(instanceSettings);\n this.tracesToLogs = instanceSettings.jsonData.tracesToLogs;\n this.serviceMap = instanceSettings.jsonData.serviceMap;\n this.search = instanceSettings.jsonData.search;\n this.nodeGraph = instanceSettings.jsonData.nodeGraph;\n this.lokiSearch = instanceSettings.jsonData.lokiSearch;\n }\n\n query(options: DataQueryRequest<TempoQuery>): Observable<DataQueryResponse> {\n const subQueries: Array<Observable<DataQueryResponse>> = [];\n const filteredTargets = options.targets.filter((target) => !target.hide);\n const targets: { [type: string]: TempoQuery[] } = groupBy(filteredTargets, (t) => t.queryType || 'traceId');\n\n if (targets.clear) {\n return of({ data: [], state: LoadingState.Done });\n }\n\n const logsDatasourceUid = this.getLokiSearchDS();\n\n // Run search queries on linked datasource\n if (logsDatasourceUid && targets.search?.length > 0) {\n reportInteraction('grafana_traces_loki_search_queried', {\n datasourceType: 'tempo',\n app: options.app ?? '',\n linkedQueryExpr: targets.search[0].linkedQuery?.expr ?? '',\n });\n\n const dsSrv = getDatasourceSrv();\n subQueries.push(\n from(dsSrv.get(logsDatasourceUid)).pipe(\n mergeMap((linkedDatasource: DataSourceApi) => {\n // Wrap linked query into a data request based on original request\n const linkedRequest: DataQueryRequest = { ...options, targets: targets.search.map((t) => t.linkedQuery!) };\n // Find trace matchers in derived fields of the linked datasource that's identical to this datasource\n const settings: DataSourceInstanceSettings<LokiOptions> = (linkedDatasource as any).instanceSettings;\n const traceLinkMatcher: string[] =\n settings.jsonData.derivedFields\n ?.filter((field) => field.datasourceUid === this.uid && field.matcherRegex)\n .map((field) => field.matcherRegex) || [];\n\n if (!traceLinkMatcher || traceLinkMatcher.length === 0) {\n return throwError(\n () =>\n new Error(\n 'No Loki datasource configured for search. Set up Derived Fields for traces in a Loki datasource settings and link it to this Tempo datasource.'\n )\n );\n } else {\n return (linkedDatasource.query(linkedRequest) as Observable<DataQueryResponse>).pipe(\n map((response) =>\n response.error ? response : transformTraceList(response, this.uid, this.name, traceLinkMatcher)\n )\n );\n }\n })\n )\n );\n }\n\n if (targets.nativeSearch?.length) {\n try {\n reportInteraction('grafana_traces_search_queried', {\n datasourceType: 'tempo',\n app: options.app ?? '',\n serviceName: targets.nativeSearch[0].serviceName ?? '',\n spanName: targets.nativeSearch[0].spanName ?? '',\n resultLimit: targets.nativeSearch[0].limit ?? '',\n search: targets.nativeSearch[0].search ?? '',\n });\n\n const timeRange = config.featureToggles.tempoBackendSearch\n ? { startTime: options.range.from.unix(), endTime: options.range.to.unix() }\n : undefined;\n const query = this.applyVariables(targets.nativeSearch[0], options.scopedVars);\n const searchQuery = this.buildSearchQuery(query, timeRange);\n subQueries.push(\n this._request('/api/search', searchQuery).pipe(\n map((response) => {\n return {\n data: [createTableFrameFromSearch(response.data.traces, this.instanceSettings)],\n };\n }),\n catchError((error) => {\n return of({ error: { message: error.data.message }, data: [] });\n })\n )\n );\n } catch (error) {\n return of({ error: { message: error.message }, data: [] });\n }\n }\n\n if (targets.upload?.length) {\n if (this.uploadedJson) {\n reportInteraction('grafana_traces_json_file_uploaded', {\n datasourceType: 'tempo',\n app: options.app ?? '',\n });\n\n const otelTraceData = JSON.parse(this.uploadedJson as string);\n if (!otelTraceData.batches) {\n subQueries.push(of({ error: { message: 'JSON is not valid OpenTelemetry format' }, data: [] }));\n } else {\n subQueries.push(of(transformFromOTEL(otelTraceData.batches, this.nodeGraph?.enabled)));\n }\n } else {\n subQueries.push(of({ data: [], state: LoadingState.Done }));\n }\n }\n\n if (this.serviceMap?.datasourceUid && targets.serviceMap?.length > 0) {\n reportInteraction('grafana_traces_service_graph_queried', {\n datasourceType: 'tempo',\n app: options.app ?? '',\n serviceMapQuery: targets.serviceMap[0].serviceMapQuery ?? '',\n });\n subQueries.push(serviceMapQuery(options, this.serviceMap.datasourceUid));\n }\n\n if (targets.traceId?.length > 0) {\n reportInteraction('grafana_traces_traceID_queried', {\n datasourceType: 'tempo',\n app: options.app ?? '',\n query: targets.traceId[0].query ?? '',\n });\n\n subQueries.push(this.handleTraceIdQuery(options, targets.traceId));\n }\n\n return merge(...subQueries);\n }\n\n applyTemplateVariables(query: TempoQuery, scopedVars: ScopedVars): Record<string, any> {\n return this.applyVariables(query, scopedVars);\n }\n\n interpolateVariablesInQueries(queries: TempoQuery[], scopedVars: ScopedVars): TempoQuery[] {\n if (!queries || queries.length === 0) {\n return [];\n }\n\n return queries.map((query) => {\n return {\n ...query,\n datasource: this.getRef(),\n ...this.applyVariables(query, scopedVars),\n };\n });\n }\n\n applyVariables(query: TempoQuery, scopedVars: ScopedVars) {\n const expandedQuery = { ...query };\n\n if (query.linkedQuery) {\n expandedQuery.linkedQuery = {\n ...query.linkedQuery,\n expr: this.templateSrv.replace(query.linkedQuery?.expr ?? '', scopedVars),\n };\n }\n\n return {\n ...expandedQuery,\n query: this.templateSrv.replace(query.query ?? '', scopedVars),\n serviceName: this.templateSrv.replace(query.serviceName ?? '', scopedVars),\n spanName: this.templateSrv.replace(query.spanName ?? '', scopedVars),\n search: this.templateSrv.replace(query.search ?? '', scopedVars),\n minDuration: this.templateSrv.replace(query.minDuration ?? '', scopedVars),\n maxDuration: this.templateSrv.replace(query.maxDuration ?? '', scopedVars),\n };\n }\n\n /**\n * Handles the simplest of the queries where we have just a trace id and return trace data for it.\n * @param options\n * @param targets\n * @private\n */\n private handleTraceIdQuery(\n options: DataQueryRequest<TempoQuery>,\n targets: TempoQuery[]\n ): Observable<DataQueryResponse> {\n const validTargets = targets.filter((t) => t.query).map((t) => ({ ...t, query: t.query.trim() }));\n if (!validTargets.length) {\n return EMPTY;\n }\n\n const traceRequest: DataQueryRequest<TempoQuery> = { ...options, targets: validTargets };\n return super.query(traceRequest).pipe(\n map((response) => {\n if (response.error) {\n return response;\n }\n return transformTrace(response, this.nodeGraph?.enabled);\n })\n );\n }\n\n async metadataRequest(url: string, params = {}) {\n return await this._request(url, params, { method: 'GET', hideFromInspector: true }).toPromise();\n }\n\n private _request(apiUrl: string, data?: any, options?: Partial<BackendSrvRequest>): Observable<Record<string, any>> {\n const params = data ? serializeParams(data) : '';\n const url = `${this.instanceSettings.url}${apiUrl}${params.length ? `?${params}` : ''}`;\n const req = { ...options, url };\n\n return getBackendSrv().fetch(req);\n }\n\n async testDatasource(): Promise<any> {\n const options: BackendSrvRequest = {\n headers: {},\n method: 'GET',\n url: `${this.instanceSettings.url}/api/echo`,\n };\n const response = await getBackendSrv().fetch<any>(options).toPromise();\n\n if (response?.ok) {\n return { status: 'success', message: 'Data source is working' };\n }\n }\n\n getQueryDisplayText(query: TempoQuery) {\n if (query.queryType === 'nativeSearch') {\n let result = [];\n for (const key of ['serviceName', 'spanName', 'search', 'minDuration', 'maxDuration', 'limit']) {\n if (query.hasOwnProperty(key) && query[key as keyof TempoQuery]) {\n result.push(`${startCase(key)}: ${query[key as keyof TempoQuery]}`);\n }\n }\n return result.join(', ');\n }\n return query.query;\n }\n\n buildSearchQuery(query: TempoQuery, timeRange?: { startTime: number; endTime?: number }): SearchQueryParams {\n let tags = query.search ?? '';\n\n let tempoQuery = pick(query, ['minDuration', 'maxDuration', 'limit']);\n // Remove empty properties\n tempoQuery = pickBy(tempoQuery, identity);\n\n if (query.serviceName) {\n tags += ` service.name=\"${query.serviceName}\"`;\n }\n if (query.spanName) {\n tags += ` name=\"${query.spanName}\"`;\n }\n\n // Set default limit\n if (!tempoQuery.limit) {\n tempoQuery.limit = DEFAULT_LIMIT;\n }\n\n // Validate query inputs and remove spaces if valid\n if (tempoQuery.minDuration) {\n tempoQuery.minDuration = this.templateSrv.replace(tempoQuery.minDuration ?? '');\n if (!isValidGoDuration(tempoQuery.minDuration)) {\n throw new Error('Please enter a valid min duration.');\n }\n tempoQuery.minDuration = tempoQuery.minDuration.replace(/\\s/g, '');\n }\n if (tempoQuery.maxDuration) {\n tempoQuery.maxDuration = this.templateSrv.replace(tempoQuery.maxDuration ?? '');\n if (!isValidGoDuration(tempoQuery.maxDuration)) {\n throw new Error('Please enter a valid max duration.');\n }\n tempoQuery.maxDuration = tempoQuery.maxDuration.replace(/\\s/g, '');\n }\n\n if (!Number.isInteger(tempoQuery.limit) || tempoQuery.limit <= 0) {\n throw new Error('Please enter a valid limit.');\n }\n\n let searchQuery: SearchQueryParams = { tags, ...tempoQuery };\n\n if (timeRange) {\n searchQuery.start = timeRange.startTime;\n searchQuery.end = timeRange.endTime;\n }\n\n return searchQuery;\n }\n\n async getServiceGraphLabels() {\n const ds = await getDatasourceSrv().get(this.serviceMap!.datasourceUid);\n return ds.getTagKeys!();\n }\n\n async getServiceGraphLabelValues(key: string) {\n const ds = await getDatasourceSrv().get(this.serviceMap!.datasourceUid);\n return ds.getTagValues!({ key });\n }\n\n // Get linked loki search datasource. Fall back to legacy loki search/trace to logs config\n getLokiSearchDS = (): string | undefined => {\n const legacyLogsDatasourceUid =\n this.tracesToLogs?.lokiSearch !== false && this.lokiSearch === undefined\n ? this.tracesToLogs?.datasourceUid\n : undefined;\n return this.lokiSearch?.datasourceUid ?? legacyLogsDatasourceUid;\n };\n}\n\nfunction queryServiceMapPrometheus(request: DataQueryRequest<PromQuery>, datasourceUid: string) {\n return from(getDatasourceSrv().get(datasourceUid)).pipe(\n mergeMap((ds) => {\n return (ds as PrometheusDatasource).query(request);\n })\n );\n}\n\nfunction serviceMapQuery(request: DataQueryRequest<TempoQuery>, datasourceUid: string) {\n return queryServiceMapPrometheus(makePromServiceMapRequest(request), datasourceUid).pipe(\n // Just collect all the responses first before processing into node graph data\n toArray(),\n map((responses: DataQueryResponse[]) => {\n const errorRes = responses.find((res) => !!res.error);\n if (errorRes) {\n throw new Error(errorRes.error!.message);\n }\n\n const { nodes, edges } = mapPromMetricsToServiceMap(responses, request.range);\n nodes.fields[0].config = {\n links: [\n makePromLink(\n 'Request rate',\n `rate(${totalsMetric}{server=\"\\${__data.fields.id}\"}[$__rate_interval])`,\n datasourceUid\n ),\n makePromLink(\n 'Request histogram',\n `histogram_quantile(0.9, sum(rate(${histogramMetric}{server=\"\\${__data.fields.id}\"}[$__rate_interval])) by (le, client, server))`,\n datasourceUid\n ),\n makePromLink(\n 'Failed request rate',\n `rate(${failedMetric}{server=\"\\${__data.fields.id}\"}[$__rate_interval])`,\n datasourceUid\n ),\n ],\n };\n\n return {\n data: [nodes, edges],\n state: LoadingState.Done,\n };\n })\n );\n}\n\nfunction makePromLink(title: string, metric: string, datasourceUid: string) {\n return {\n url: '',\n title,\n internal: {\n query: {\n expr: metric,\n } as PromQuery,\n datasourceUid,\n datasourceName: 'Prometheus',\n },\n };\n}\n\nfunction makePromServiceMapRequest(options: DataQueryRequest<TempoQuery>): DataQueryRequest<PromQuery> {\n return {\n ...options,\n targets: serviceMapMetrics.map((metric) => {\n return {\n refId: metric,\n // options.targets[0] is not correct here, but not sure what should happen if you have multiple queries for\n // service map at the same time anyway\n expr: `delta(${metric}${options.targets[0].serviceMapQuery || ''}[$__range])`,\n instant: true,\n };\n }),\n };\n}\n","import { DataSourcePlugin } from '@grafana/data';\n\nimport CheatSheet from './CheatSheet';\nimport { TempoQueryField } from './QueryEditor/QueryField';\nimport { ConfigEditor } from './configuration/ConfigEditor';\nimport { TempoDatasource } from './datasource';\n\nexport const plugin = new DataSourcePlugin(TempoDatasource)\n .setQueryEditor(TempoQueryField)\n .setConfigEditor(ConfigEditor)\n .setQueryEditorHelp(CheatSheet);\n","import React from 'react';\n\nimport { DataSourcePluginOptionsEditorProps } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { DataSourceHttpSettings } from '@grafana/ui';\nimport { NodeGraphSettings } from 'app/core/components/NodeGraphSettings';\nimport { TraceToLogsSettings } from 'app/core/components/TraceToLogs/TraceToLogsSettings';\nimport { TraceToMetricsSettings } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings';\n\nimport { LokiSearchSettings } from './LokiSearchSettings';\nimport { SearchSettings } from './SearchSettings';\nimport { ServiceGraphSettings } from './ServiceGraphSettings';\n\nexport type Props = DataSourcePluginOptionsEditorProps;\n\nexport const ConfigEditor: React.FC<Props> = ({ options, onOptionsChange }) => {\n return (\n <>\n <DataSourceHttpSettings\n defaultUrl=\"http://tempo\"\n dataSourceConfig={options}\n showAccessOptions={false}\n onChange={onOptionsChange}\n />\n\n <div className=\"gf-form-group\">\n <TraceToLogsSettings options={options} onOptionsChange={onOptionsChange} />\n </div>\n\n {config.featureToggles.traceToMetrics ? (\n <div className=\"gf-form-group\">\n <TraceToMetricsSettings options={options} onOptionsChange={onOptionsChange} />\n </div>\n ) : null}\n\n <div className=\"gf-form-group\">\n <ServiceGraphSettings options={options} onOptionsChange={onOptionsChange} />\n </div>\n\n {config.featureToggles.tempoSearch && (\n <div className=\"gf-form-group\">\n <SearchSettings options={options} onOptionsChange={onOptionsChange} />\n </div>\n )}\n\n <div className=\"gf-form-group\">\n <NodeGraphSettings options={options} onOptionsChange={onOptionsChange} />\n </div>\n\n <div className=\"gf-form-group\">\n <LokiSearchSettings options={options} onOptionsChange={onOptionsChange} />\n </div>\n </>\n );\n};\n","import React from 'react';\n\nexport default function CheatSheet() {\n return (\n <div>\n <h2 id=\"tempo-cheat-sheet\">Tempo Cheat Sheet</h2>\n <p>\n Tempo is a trace id lookup store. Enter a trace id in the above field and hit “Run Query” to retrieve your\n trace. Tempo is generally paired with other datasources such as Loki or Prometheus to find traces.\n </p>\n <p>\n Here are some{' '}\n <a href=\"https://grafana.com/docs/tempo/latest/guides/instrumentation/\" target=\"blank\">\n instrumentation examples\n </a>{' '}\n to get you started with trace discovery through logs and metrics (exemplars).\n </p>\n </div>\n );\n}\n"],"names":["TempoLanguageProvider","LanguageProvider","constructor","datasource","initialValues","super","async","url","params","res","metadataRequest","data","this","fetchTags","prefix","text","value","labelKey","wrapperClasses","emptyResult","suggestions","query","endText","getText","isValue","indexOf","getTagValueCompletionItems","getTagsCompletionItems","tags","length","push","label","items","map","tag","Object","assign","response","request","tagNames","split","tagName","tagValues","tagValue","options","v","PRISM_LANGUAGE","durationPlaceholder","plugins","BracesPlugin","SlatePrism","onlyIn","node","object","type","getSyntax","Prism","key","pattern","alias","operator","onChange","onBlur","onRunQuery","styles","useStyles2","getStyles","languageProvider","useMemo","hasSyntaxLoaded","setHasSyntaxLoaded","useState","serviceOptions","setServiceOptions","spanOptions","setSpanOptions","error","setError","inputErrors","setInputErrors","isLoading","setIsLoading","serviceName","spanName","loadOptions","useCallback","name","lpName","prevValue","getOptions","filter","item","fuzzyMatch","found","status","dispatch","notifyApp","createErrorNotification","useEffect","services","spans","Promise","all","getTemplateSrv","containsTemplate","toOption","fetchOptions","start","onKeyDown","keyEvent","shiftKey","ctrlKey","templateSrv","className","container","InlineFieldRow","InlineField","labelWidth","grow","Select","inputId","onOpenMenu","find","undefined","placeholder","isClearable","allowCustomValue","tooltip","QueryField","additionalPlugins","search","onTypeahead","provideCompletionItems","typeahead","cleanText","splittedText","syntaxLoaded","portalOrigin","invalid","minDuration","Input","id","templatedMinDuration","replace","isValidGoDuration","currentTarget","maxDuration","templatedMaxDuration","limit","parseInt","Number","isInteger","Alert","title","severity","alert","href","uid","theme","css","spacing","getDS","dsSrv","getDataSourceSrv","get","console","ServiceGraphSection","graphDatasourceUid","dsState","useAsync","hasKeys","setHasKeys","loading","ds","keys","getTagKeys","series","Boolean","fn","filters","match","re","exec","condition","queryToFilter","serviceMapQuery","AdHocFilter","getTagKeysOptions","addFilter","filtersToQuery","removeFilter","index","newFilters","splice","changeFilter","target","rel","f","join","TempoQueryFieldComponent","React","props","linkedQuery","refId","queryType","render","app","logsDatasourceUid","getLokiSearchDS","serviceMap","datasourceUid","queryTypeOptions","config","hide","unshift","RadioButtonGroup","reportInteraction","datasourceType","newQueryType","previousQueryType","onClearResults","size","style","maxWidth","Badge","icon","color","SearchSection","onRunLinkedQuery","onChangeLinkedQuery","padding","FileDropzone","multiple","onLoad","result","uploadedJson","val","InlineLabel","LokiQueryField","history","TempoQueryField","withTheme2","LokiSearchSettings","onOptionsChange","useStyles","legacyDatasource","jsonData","tracesToLogs","lokiSearch","updateDatasourcePluginJsonDataOption","width","infoText","row","DataSourcePicker","pluginId","current","noDefault","Button","variant","fill","onClick","md","colors","textSemiWeak","SearchSettings","InlineSwitch","event","checked","ServiceGraphSettings","TempoDatasource","DataSourceWithBackend","instanceSettings","legacyLogsDatasourceUid","nodeGraph","subQueries","filteredTargets","targets","groupBy","t","clear","of","state","LoadingState","linkedQueryExpr","expr","getDatasourceSrv","from","pipe","mergeMap","linkedDatasource","linkedRequest","traceLinkMatcher","derivedFields","field","matcherRegex","transformTraceList","throwError","Error","nativeSearch","resultLimit","timeRange","startTime","range","unix","endTime","to","applyVariables","scopedVars","searchQuery","buildSearchQuery","_request","createTableFrameFromSearch","traces","catchError","message","upload","otelTraceData","JSON","parse","batches","transformFromOTEL","enabled","queryServiceMapPrometheus","serviceMapMetrics","metric","instant","makePromServiceMapRequest","toArray","responses","errorRes","nodes","edges","mapPromMetricsToServiceMap","fields","links","makePromLink","totalsMetric","histogramMetric","failedMetric","traceId","handleTraceIdQuery","merge","applyTemplateVariables","interpolateVariablesInQueries","queries","getRef","expandedQuery","validTargets","trim","EMPTY","traceRequest","transformTrace","method","hideFromInspector","toPromise","apiUrl","serializeParams","req","getBackendSrv","fetch","headers","ok","getQueryDisplayText","hasOwnProperty","startCase","tempoQuery","pick","pickBy","identity","end","getTagValues","internal","datasourceName","plugin","DataSourcePlugin","setQueryEditor","setConfigEditor","DataSourceHttpSettings","defaultUrl","dataSourceConfig","showAccessOptions","TraceToLogsSettings","TraceToMetricsSettings","NodeGraphSettings","setQueryEditorHelp"],"sourceRoot":""}