diff --git a/public/app/core/components/TraceToLogs/TraceToLogsSettings.tsx b/public/app/core/components/TraceToLogs/TraceToLogsSettings.tsx index 0b7933461f6..b80b7320ed6 100644 --- a/public/app/core/components/TraceToLogs/TraceToLogsSettings.tsx +++ b/public/app/core/components/TraceToLogs/TraceToLogsSettings.tsx @@ -34,7 +34,12 @@ interface Props extends DataSourcePluginOptionsEditorProps {} export function TraceToLogsSettings({ options, onOptionsChange }: Props) { const styles = useStyles2(getStyles); - const supportedDataSourceTypes = ['loki', 'grafana-splunk-datasource', 'elasticsearch']; + const supportedDataSourceTypes = [ + 'loki', + 'elasticsearch', + 'grafana-splunk-datasource', // external + 'grafana-opensearch-datasource', // external + ]; return (
diff --git a/public/app/features/explore/TraceView/createSpanLink.test.ts b/public/app/features/explore/TraceView/createSpanLink.test.ts index f65a1241f1c..daa46073e2f 100644 --- a/public/app/features/explore/TraceView/createSpanLink.test.ts +++ b/public/app/features/explore/TraceView/createSpanLink.test.ts @@ -594,14 +594,14 @@ describe('createSpanLinkFactory', () => { }); }); - describe('elasticsearch link', () => { - const elasticsearchUID = 'elasticsearchUID'; + describe('elasticsearch/opensearch link', () => { + const searchUID = 'searchUID'; beforeAll(() => { setDataSourceSrv({ getInstanceSettings() { return { - uid: elasticsearchUID, + uid: searchUID, name: 'Elasticsearch', type: 'elasticsearch', } as unknown as DataSourceInstanceSettings; @@ -614,7 +614,7 @@ describe('createSpanLinkFactory', () => { it('creates link with correct simple query', () => { const createLink = setupSpanLinkFactory({ - datasourceUid: elasticsearchUID, + datasourceUid: searchUID, }); const links = createLink!(createTraceSpan()); @@ -622,14 +622,14 @@ describe('createSpanLinkFactory', () => { expect(linkDef).toBeDefined(); expect(linkDef!.href).toContain( encodeURIComponent( - `datasource":"${elasticsearchUID}","queries":[{"query":"cluster:\\"cluster1\\" AND hostname:\\"hostname1\\"","refId":"","metrics":[{"id":"1","type":"logs"}]}]` + `datasource":"${searchUID}","queries":[{"query":"cluster:\\"cluster1\\" AND hostname:\\"hostname1\\"","refId":"","metrics":[{"id":"1","type":"logs"}]}]` ) ); }); it('automatically timeshifts the time range by one second in a query', () => { const createLink = setupSpanLinkFactory({ - datasourceUid: elasticsearchUID, + datasourceUid: searchUID, }); const links = createLink!(createTraceSpan()); @@ -646,11 +646,11 @@ describe('createSpanLinkFactory', () => { it('formats query correctly if filterByTraceID and or filterBySpanID is true', () => { const createLink = setupSpanLinkFactory( { - datasourceUid: elasticsearchUID, + datasourceUid: searchUID, filterByTraceID: true, filterBySpanID: true, }, - elasticsearchUID + searchUID ); expect(createLink).toBeDefined(); @@ -660,7 +660,7 @@ describe('createSpanLinkFactory', () => { expect(linkDef).toBeDefined(); expect(linkDef!.href).toBe( `/explore?left=${encodeURIComponent( - `{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${elasticsearchUID}","queries":[{"query":"\\"6605c7b08e715d6c\\" AND \\"7946b05c2e2e4e5a\\" AND cluster:\\"cluster1\\" AND hostname:\\"hostname1\\"","refId":"","metrics":[{"id":"1","type":"logs"}]}],"panelsState":{}}` + `{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${searchUID}","queries":[{"query":"\\"6605c7b08e715d6c\\" AND \\"7946b05c2e2e4e5a\\" AND cluster:\\"cluster1\\" AND hostname:\\"hostname1\\"","refId":"","metrics":[{"id":"1","type":"logs"}]}],"panelsState":{}}` )}` ); }); @@ -670,7 +670,7 @@ describe('createSpanLinkFactory', () => { { tags: ['ip'], }, - elasticsearchUID + searchUID ); expect(createLink).toBeDefined(); const links = createLink!( @@ -686,7 +686,7 @@ describe('createSpanLinkFactory', () => { expect(linkDef).toBeDefined(); expect(linkDef!.href).toBe( `/explore?left=${encodeURIComponent( - `{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${elasticsearchUID}","queries":[{"query":"ip:\\"192.168.0.1\\"","refId":"","metrics":[{"id":"1","type":"logs"}]}],"panelsState":{}}` + `{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${searchUID}","queries":[{"query":"ip:\\"192.168.0.1\\"","refId":"","metrics":[{"id":"1","type":"logs"}]}],"panelsState":{}}` )}` ); }); @@ -696,7 +696,7 @@ describe('createSpanLinkFactory', () => { { tags: ['ip', 'hostname'], }, - elasticsearchUID + searchUID ); expect(createLink).toBeDefined(); const links = createLink!( @@ -715,7 +715,7 @@ describe('createSpanLinkFactory', () => { expect(linkDef).toBeDefined(); expect(linkDef!.href).toBe( `/explore?left=${encodeURIComponent( - `{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${elasticsearchUID}","queries":[{"query":"hostname:\\"hostname1\\" AND ip:\\"192.168.0.1\\"","refId":"","metrics":[{"id":"1","type":"logs"}]}],"panelsState":{}}` + `{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${searchUID}","queries":[{"query":"hostname:\\"hostname1\\" AND ip:\\"192.168.0.1\\"","refId":"","metrics":[{"id":"1","type":"logs"}]}],"panelsState":{}}` )}` ); }); @@ -729,7 +729,7 @@ describe('createSpanLinkFactory', () => { { key: 'k8s.pod.name', value: 'pod' }, ], }, - elasticsearchUID + searchUID ); expect(createLink).toBeDefined(); const links = createLink!( @@ -748,7 +748,7 @@ describe('createSpanLinkFactory', () => { expect(linkDef).toBeDefined(); expect(linkDef!.href).toBe( `/explore?left=${encodeURIComponent( - `{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${elasticsearchUID}","queries":[{"query":"service:\\"serviceName\\" AND pod:\\"podName\\"","refId":"","metrics":[{"id":"1","type":"logs"}]}],"panelsState":{}}` + `{"range":{"from":"2020-10-14T01:00:00.000Z","to":"2020-10-14T01:00:01.000Z"},"datasource":"${searchUID}","queries":[{"query":"service:\\"serviceName\\" AND pod:\\"podName\\"","refId":"","metrics":[{"id":"1","type":"logs"}]}],"panelsState":{}}` )}` ); }); diff --git a/public/app/features/explore/TraceView/createSpanLink.tsx b/public/app/features/explore/TraceView/createSpanLink.tsx index 6d06f8c8ec6..a88d77d18ae 100644 --- a/public/app/features/explore/TraceView/createSpanLink.tsx +++ b/public/app/features/explore/TraceView/createSpanLink.tsx @@ -22,7 +22,6 @@ import { SpanLinkFunc, TraceSpan } from '@jaegertracing/jaeger-ui-components'; import { TraceToLogsOptions } from 'app/core/components/TraceToLogs/TraceToLogsSettings'; import { TraceToMetricQuery, TraceToMetricsOptions } from 'app/core/components/TraceToMetrics/TraceToMetricsSettings'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; -import { ElasticsearchQuery } from 'app/plugins/datasource/elasticsearch/types'; import { PromQuery } from 'app/plugins/datasource/prometheus/types'; import { LokiQuery } from '../../../plugins/datasource/loki/types'; @@ -116,7 +115,11 @@ function legacyCreateSpanLinkFactory( dataLink = getLinkForSplunk(span, traceToLogsOptions, logsDataSourceSettings); break; case 'elasticsearch': - dataLink = getLinkForElasticsearch(span, traceToLogsOptions, logsDataSourceSettings); + dataLink = getLinkForElasticsearchOrOpensearch(span, traceToLogsOptions, logsDataSourceSettings); + break; + case 'grafana-opensearch-datasource': + dataLink = getLinkForElasticsearchOrOpensearch(span, traceToLogsOptions, logsDataSourceSettings); + break; } if (dataLink) { @@ -283,7 +286,17 @@ function getLinkForLoki(span: TraceSpan, options: TraceToLogsOptions, dataSource return dataLink; } -function getLinkForElasticsearch( +// we do not have access to the dataquery type for opensearch, +// so here is a minimal interface that handles both elasticsearch and opensearch. +interface ElasticsearchOrOpensearchQuery extends DataQuery { + query: string; + metrics: Array<{ + id: string; + type: 'logs'; + }>; +} + +function getLinkForElasticsearchOrOpensearch( span: TraceSpan, options: TraceToLogsOptions, dataSourceSettings: DataSourceInstanceSettings @@ -316,7 +329,7 @@ function getLinkForElasticsearch( query = `"${span.spanID}" AND ` + query; } - const dataLink: DataLink = { + const dataLink: DataLink = { title: dataSourceSettings.name, url: '', internal: {