diff --git a/public/app/plugins/datasource/tempo/QueryField.tsx b/public/app/plugins/datasource/tempo/QueryField.tsx index 9b77dde296f..aff4db7eae6 100644 --- a/public/app/plugins/datasource/tempo/QueryField.tsx +++ b/public/app/plugins/datasource/tempo/QueryField.tsx @@ -16,10 +16,9 @@ export class TempoQueryField extends React.PureComponent { state = { linkedDatasource: undefined, }; - linkedQuery: DataQuery; + constructor(props: Props) { super(props); - this.linkedQuery = { refId: 'linked' }; } async componentDidMount() { @@ -38,10 +37,9 @@ export class TempoQueryField extends React.PureComponent { onChangeLinkedQuery = (value: DataQuery) => { const { query, onChange } = this.props; - this.linkedQuery = value; onChange({ ...query, - linkedQuery: this.linkedQuery, + linkedQuery: { ...value, refId: 'linked' }, }); }; @@ -83,7 +81,7 @@ export class TempoQueryField extends React.PureComponent { datasource={linkedDatasource!} onChange={this.onChangeLinkedQuery} onRunQuery={this.onRunLinkedQuery} - query={this.linkedQuery as any} + query={this.props.query.linkedQuery ?? ({ refId: 'linked' } as any)} history={[]} /> diff --git a/public/app/plugins/datasource/tempo/datasource.ts b/public/app/plugins/datasource/tempo/datasource.ts index 93c73e7b1e1..4f38d7d616f 100644 --- a/public/app/plugins/datasource/tempo/datasource.ts +++ b/public/app/plugins/datasource/tempo/datasource.ts @@ -8,8 +8,8 @@ import { import { DataSourceWithBackend } from '@grafana/runtime'; import { TraceToLogsData, TraceToLogsOptions } from 'app/core/components/TraceToLogsSettings'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { merge, Observable, throwError } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { from, merge, Observable, throwError } from 'rxjs'; +import { map, mergeMap } from 'rxjs/operators'; import { LokiOptions } from '../loki/types'; import { transformTrace, transformTraceList } from './resultTransformer'; @@ -23,19 +23,11 @@ export type TempoQuery = { } & DataQuery; export class TempoDatasource extends DataSourceWithBackend { - tracesToLogs: TraceToLogsOptions; - linkedDatasource: DataSourceApi; + tracesToLogs?: TraceToLogsOptions; + constructor(instanceSettings: DataSourceInstanceSettings) { super(instanceSettings); - this.tracesToLogs = instanceSettings.jsonData.tracesToLogs || {}; - if (this.tracesToLogs.datasourceUid) { - this.linkDatasource(); - } - } - - async linkDatasource() { - const dsSrv = getDatasourceSrv(); - this.linkedDatasource = await dsSrv.get(this.tracesToLogs.datasourceUid); + this.tracesToLogs = instanceSettings.jsonData.tracesToLogs; } query(options: DataQueryRequest): Observable { @@ -47,30 +39,33 @@ export class TempoDatasource extends DataSourceWithBackend 0) { - // Wrap linked query into a data request based on original request - const linkedRequest: DataQueryRequest = { ...options, targets: searchTargets.map((t) => t.linkedQuery!) }; - // Find trace matchers in derived fields of the linked datasource that's identical to this datasource - const settings: DataSourceInstanceSettings = (this.linkedDatasource as any).instanceSettings; - const traceLinkMatcher: string[] = - settings.jsonData.derivedFields - ?.filter((field) => field.datasourceUid === this.uid && field.matcherRegex) - .map((field) => field.matcherRegex) || []; - if (!traceLinkMatcher || traceLinkMatcher.length === 0) { - subQueries.push( - throwError( - 'No Loki datasource configured for search. Set up Derived Fields for traces in a Loki datasource settings and link it to this Tempo datasource.' - ) - ); - } else { - subQueries.push( - (this.linkedDatasource.query(linkedRequest) as Observable).pipe( - map((response) => - response.error ? response : transformTraceList(response, this.uid, this.name, traceLinkMatcher) - ) - ) - ); - } + if (this.tracesToLogs?.datasourceUid && searchTargets.length > 0) { + const dsSrv = getDatasourceSrv(); + subQueries.push( + from(dsSrv.get(this.tracesToLogs.datasourceUid)).pipe( + mergeMap((linkedDatasource: DataSourceApi) => { + // Wrap linked query into a data request based on original request + const linkedRequest: DataQueryRequest = { ...options, targets: searchTargets.map((t) => t.linkedQuery!) }; + // Find trace matchers in derived fields of the linked datasource that's identical to this datasource + const settings: DataSourceInstanceSettings = (linkedDatasource as any).instanceSettings; + const traceLinkMatcher: string[] = + settings.jsonData.derivedFields + ?.filter((field) => field.datasourceUid === this.uid && field.matcherRegex) + .map((field) => field.matcherRegex) || []; + if (!traceLinkMatcher || traceLinkMatcher.length === 0) { + return throwError( + 'No Loki datasource configured for search. Set up Derived Fields for traces in a Loki datasource settings and link it to this Tempo datasource.' + ); + } else { + return (linkedDatasource.query(linkedRequest) as Observable).pipe( + map((response) => + response.error ? response : transformTraceList(response, this.uid, this.name, traceLinkMatcher) + ) + ); + } + }) + ) + ); } if (traceTargets.length > 0) { diff --git a/public/app/plugins/datasource/tempo/resultTransformer.ts b/public/app/plugins/datasource/tempo/resultTransformer.ts index 9a0b7e62013..ea3d88ab608 100644 --- a/public/app/plugins/datasource/tempo/resultTransformer.ts +++ b/public/app/plugins/datasource/tempo/resultTransformer.ts @@ -12,12 +12,18 @@ export function createTableFrame( { name: 'Time', type: FieldType.time, + config: { + custom: { + width: 150, + }, + }, }, { name: 'traceID', type: FieldType.string, config: { displayNameFromDS: 'Trace ID', + custom: { width: 300 }, links: [ { title: 'Click to open trace ${__value.raw}', @@ -85,8 +91,10 @@ export function transformTraceList( datasourceName: string, traceRegexs: string[] ): DataQueryResponse { - const frame = createTableFrame(response.data[0], datasourceId, datasourceName, traceRegexs); - response.data[0] = frame; + response.data.forEach((data, index) => { + const frame = createTableFrame(data, datasourceId, datasourceName, traceRegexs); + response.data[index] = frame; + }); return response; }