Tracing: Release trace to logs feature (#29443)

* Remove feature flag

* Add data source setting for Jaeger

* Refactor trace to logs settings

* Fix tests

* Get ds settings in two steps

* Add info to settings

* Update docs for trace to logs

* Update yarn.lock

* Apply suggestions from code review

Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>

* Update TraceToLogsSettings after merge with master

* Add config for tags

* Add tags to check for keys

* Apply suggestions from code review

Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>

* Update docs

Co-authored-by: achatterjee-grafana <70489351+achatterjee-grafana@users.noreply.github.com>
This commit is contained in:
Zoltán Bedi 2020-12-10 19:42:43 +01:00 committed by GitHub
parent 8a3fdc3055
commit b3838d372e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 340 additions and 135 deletions

View File

@ -11,19 +11,29 @@ weight = 800
Grafana ships with built-in support for Jaeger, which provides open source, end-to-end distributed tracing.
Just add it as a data source and you are ready to query your traces in [Explore]({{< relref "../explore/index.md" >}}).
## Adding the data source
To access Jaeger settings, click the **Configuration** (gear) icon, then click **Data Sources**, and then click **Jaeger**.
## Add data source
To access Jaeger settings, click the **Configuration** (gear) icon, then click **Data Sources** > **Jaeger**.
| Name | Description |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `Name` | The data source name. This is how you refer to the data source in panels, queries, and Explore. |
| `Default` | Default data source means that it will be pre-selected for new panels. |
| `URL` | The URL of the Jaeger instance, e.g., `http://localhost:16686` |
| `Access` | Server (default) = URL needs to be accessible from the Grafana backend/server, Browser = URL needs to be accessible from the browser. |
| `Default` | Data source will be pre-selected for new panels. |
| `URL` | The URL of the Jaeger instance, for example, `http://localhost:16686` |
| `Access` | Server (default) = URL needs to be accessible from the Grafana backend/server. Browser = URL needs to be accessible from the browser. |
| `Basic Auth` | Enable basic authentication to the Jaeger data source. |
| `User` | User name for basic authentication. |
| `Password` | Password for basic authentication. |
### Trace to logs
{{< docs-imagebox img="/img/docs/v74/trace-to-logs-settings.png" class="docs-image--no-shadow" caption="Screenshot of the trace to logs settings" >}}
This is a configuration for the [trace to logs feature]({{< relref "../explore/index.md#trace-to-logs" >}}). Select target data source (at this moment limited to Loki data sources) and select which tags will be used in the logs query.
- **Data source -** Target data source.
- **Tags -** The tags that will be used in the Loki query. Default is `'cluster', 'hostname', 'namespace', 'pod'`.
## Query traces
You can query and display traces from Jaeger via [Explore]({{< relref "../explore/index.md" >}}).
@ -35,6 +45,7 @@ The Jaeger query editor allows you to query by trace ID directly or selecting a
{{< docs-imagebox img="/img/docs/v70/jaeger-query-editor-open.png" class="docs-image--no-shadow" caption="Screenshot of the Jaeger query editor with trace selector expanded" >}}
Use the trace selector to pick particular trace from all traces logged in the time range you have selected in Explore. The trace selector has three levels of nesting:
1. The service you are interested in.
1. Particular operation is part of the selected service.
1. Specific trace in which the selected operation occurred, represented by the root operation name and trace duration.

View File

@ -3,24 +3,34 @@ title = "Tempo"
description = "High volume, minimal dependency trace storage. OSS tracing solution from Grafana Labs."
keywords = ["grafana", "tempo", "guide", "tracing"]
aliases = ["/docs/grafana/latest/features/datasources/tempo"]
weight = 800
weight = 1400
+++
# Tempo data source
Grafana ships with built-in support for Tempo a high volume, minimal dependency trace storage, OSS tracing solution from Grafana Labs. Add it as a data source, and you are ready to query your traces in [Explore]({{< relref "../explore/index.md" >}}).
## Adding the data source
## Add data source
To access Tempo settings, click the **Configuration** (gear) icon, then click **Data Sources** > **Tempo**.
| Name | Description |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| _Name_ | The data source name using which you will refer to the data source in panels, queries, and Explore. |
| _Default_ | The default data source will be pre-selected for new panels. |
| _URL_ | The URL of the Tempo instance, e.g., `http://localhost:16686` |
| _Basic Auth_ | Enable basic authentication to the Tempo data source. |
| _User_ | User name for basic authentication. |
| _Password_ | Password for basic authentication. |
| ------------ | --------------------------------------------------------------------------------------- |
| `Name` | The name using which you will refer to the data source in panels, queries, and Explore. |
| `Default` | The default data source will be pre-selected for new panels. |
| `URL` | The URL of the Tempo instance, e.g., `http://localhost:16686` |
| `Basic Auth` | Enable basic authentication to the Tempo data source. |
| `User` | User name for basic authentication. |
| `Password` | Password for basic authentication. |
### Trace to logs
{{< docs-imagebox img="/img/docs/v74/trace-to-logs-settings.png" class="docs-image--no-shadow" caption="Screenshot of the trace to logs settings" >}}
This is a configuration for the [trace to logs feature]({{< relref "../explore/index.md#trace-to-logs" >}}). Select target data source (at this moment limited to Loki data sources) and select which tags will be used in the logs query.
- **Data source -** Target data source.
- **Tags -** The tags that will be used in the Loki query. Default is `'cluster', 'hostname', 'namespace', 'pod'`.
## Query traces

View File

@ -2,7 +2,7 @@
title = "TestData"
keywords = ["grafana", "dashboard", "documentation", "panels", "testdata"]
aliases = ["/docs/grafana/latest/features/datasources/testdata"]
weight = 1400
weight = 1500
+++
# Grafana TestData DB

View File

@ -3,7 +3,7 @@ title = "Zipkin"
description = "Guide for using Zipkin in Grafana"
keywords = ["grafana", "zipkin", "guide", "tracing"]
aliases = ["/docs/grafana/latest/datasources/zipkin"]
weight = 1500
weight = 1600
+++
# Zipkin data source
@ -12,18 +12,28 @@ Grafana ships with built-in support for Zipkin, an open source, distributed trac
Just add it as a data source and you are ready to query your traces in [Explore]({{< relref "../explore" >}}).
## Adding the data source
To access Zipkin settings, click the **Configuration** (gear) icon, then click **Data Sources**, and then click **Zipkin**.
To access Zipkin settings, click the **Configuration** (gear) icon, then click **Data Sources** > **Zipkin**.
| Name | Description |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `Name` | The data source name. This is how you refer to the data source in panels, queries, and Explore. |
| `Default` | Default data source means that it will be pre-selected for new panels. |
| `URL` | The URL of the Zipkin instance, e.g., `http://localhost:9411` |
| `Access` | Server (default) = URL needs to be accessible from the Grafana backend/server, Browser = URL needs to be accessible from the browser. |
| `Default` | Data source will be pre-selected for new panels. |
| `URL` | The URL of the Zipkin instance, e.g., `http://localhost:9411`. |
| `Access` | Server (default) = URL needs to be accessible from the Grafana backend/server. Browser = URL needs to be accessible from the browser. |
| `Basic Auth` | Enable basic authentication to the Zipkin data source. |
| `User` | User name for basic authentication. |
| `Password` | Password for basic authentication. |
### Trace to logs
{{< docs-imagebox img="/img/docs/v74/trace-to-logs-settings.png" class="docs-image--no-shadow" caption="Screenshot of the trace to logs settings" >}}
This is a configuration for the [trace to logs feature]({{< relref "../explore/index.md#trace-to-logs" >}}). Select target data source (at this moment limited to Loki data sources) and select which tags will be used in the logs query.
- **Data source -** Target data source.
- **Tags -** The tags that will be used in the Loki query. Default is `'cluster', 'hostname', 'namespace', 'pod'`.
## Query traces
Querying and displaying traces from Zipkin is available via [Explore]({{< relref "../explore" >}}).
@ -35,6 +45,7 @@ The Zipkin query editor allows you to query by trace ID directly or selecting a
{{< docs-imagebox img="/img/docs/v70/zipkin-query-editor-open.png" class="docs-image--no-shadow" caption="Screenshot of the Zipkin query editor with trace selector expanded" >}}
Use the trace selector to pick particular trace from all traces logged in the time range you have selected in Explore. The trace selector has three levels of nesting:
1. The service you are interested in.
1. Particular operation is part of the selected service
1. Specific trace in which the selected operation occurred, represented by the root operation name and trace duration.

View File

@ -258,6 +258,8 @@ You can visualize traces from tracing data sources in explore. Data sources curr
- [Jaeger]({{< relref "../datasources/jaeger.md" >}})
- [Zipkin]({{< relref "../datasources/zipkin.md" >}})
- [Tempo]({{< relref "../datasources/tempo.md" >}})
- [X-Ray](https://grafana.com/grafana/plugins/grafana-x-ray-datasource)
For information about how to use the query editor see documentation for specific data source.
@ -300,10 +302,19 @@ Clicking anywhere on the span row shows span details.
- Process metadata: Metadata about the process that logged this span.
- Logs: List of logs logged by this span and associated key values. In case of Zipkin logs section shows Zipkin annotations.
## Navigating between Explore and a dashboard
##### Trace to logs
To help accelerate workflows that involve regularly switching from Explore to a dashboard and vice-versa, we've added the ability to return to the origin dashboard
after navigating to Explore from the panel's dropdown.
> This feature is only available in Grafana 7.4+.
You can navigate from a span in a trace view directly to logs relevant for that span. This is available for Tempo, Jaeger and Zipkin data source at this moment. See their relevant documentation for instruction how to configure this feature.
{{< docs-imagebox img="/img/docs/v74/trace-to-logs.png" class="docs-image--no-shadow" caption="Screenshot of the trace view in Explore with new icon next to the spans" >}}
Click the document icon to open a split view in Explore with the configured data source and query relevant logs for the span.
## Navigate between Explore and a dashboard
To help accelerate workflows that involve regularly switching from Explore to a dashboard and vice-versa, we've added the ability to return to the origin dashboard after navigating to Explore from the panel's dropdown.
{{< docs-imagebox img="/img/docs/v64/panel_dropdown.png" class="docs-image--no-shadow" caption="Screenshot of the panel dropdown" >}}

View File

@ -35,8 +35,6 @@ export interface FeatureToggles {
live: boolean;
expressions: boolean;
ngalert: boolean;
// Just for demo at the moment
traceToLogs: boolean;
panelLibrary: boolean;
/**

View File

@ -56,7 +56,6 @@ export class GrafanaBootConfig implements GrafanaConfig {
expressions: false,
meta: false,
ngalert: false,
traceToLogs: false,
panelLibrary: false,
};
licenseInfo: LicenseInfo = {} as LicenseInfo;

View File

@ -0,0 +1,72 @@
import {
DataSourceJsonData,
DataSourcePluginOptionsEditorProps,
GrafanaTheme,
updateDatasourcePluginJsonDataOption,
} from '@grafana/data';
import { InlineFormLabel, TagsInput, useStyles } from '@grafana/ui';
import { css } from 'emotion';
import React from 'react';
import { DataSourcePicker } from './Select/DataSourcePicker';
export interface TraceToLogsOptions {
datasourceUid?: string;
tags?: string[];
}
export interface TraceToLogsData extends DataSourceJsonData {
tracesToLogs?: TraceToLogsOptions;
}
interface Props extends DataSourcePluginOptionsEditorProps<TraceToLogsData> {}
export function TraceToLogsSettings({ options, onOptionsChange }: Props) {
const styles = useStyles(getStyles);
return (
<>
<h3 className="page-heading">Trace to logs</h3>
<div className={styles.infoText}>
Trace to logs let&apos;s you navigate from a trace span to the selected data source&apos;s log.
</div>
<div className="gf-form">
<InlineFormLabel tooltip="The data source the trace is going to navigate to">Data source</InlineFormLabel>
<DataSourcePicker
pluginId="loki"
current={options.jsonData.tracesToLogs?.datasourceUid}
noDefault={true}
onChange={ds =>
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'tracesToLogs', {
datasourceUid: ds.uid,
tags: options.jsonData.tracesToLogs?.tags,
})
}
/>
</div>
<div className="gf-form">
<InlineFormLabel tooltip="Tags that will be used in the Loki query. Default tags: 'cluster', 'hostname', 'namespace', 'pod'">
Tags
</InlineFormLabel>
<TagsInput
tags={options.jsonData.tracesToLogs?.tags}
onChange={tags =>
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'tracesToLogs', {
datasourceUid: options.jsonData.tracesToLogs?.datasourceUid,
tags: tags,
})
}
/>
</div>
</>
);
}
const getStyles = (theme: GrafanaTheme) => ({
infoText: css`
padding-bottom: ${theme.spacing.md};
color: ${theme.colors.textSemiWeak};
`,
});

View File

@ -4,6 +4,11 @@ import { render } from '@testing-library/react';
import { TraceView } from './TraceView';
import { TracePageHeader, TraceTimelineViewer } from '@jaegertracing/jaeger-ui-components';
import { TraceSpanData, TraceData } from '@grafana/data';
import { setDataSourceSrv } from '@grafana/runtime';
jest.mock('react-redux', () => ({
useSelector: jest.fn(() => undefined),
}));
function renderTraceView() {
const wrapper = shallow(<TraceView trace={response} splitOpenFn={() => {}} />);
@ -15,6 +20,14 @@ function renderTraceView() {
}
describe('TraceView', () => {
beforeAll(() => {
setDataSourceSrv({
getInstanceSettings() {
return undefined;
},
} as any);
});
it('renders TraceTimelineViewer', () => {
const { timeline, header } = renderTraceView();
expect(timeline).toHaveLength(1);

View File

@ -18,6 +18,10 @@ import { useHoverIndentGuide } from './useHoverIndentGuide';
import { colors, useTheme } from '@grafana/ui';
import { TraceViewData, Trace, TraceSpan, TraceKeyValuePair, TraceLink } from '@grafana/data';
import { createSpanLinkFactory } from './createSpanLink';
import { useSelector } from 'react-redux';
import { StoreState } from 'app/types';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import { TraceToLogsData } from 'app/core/components/TraceToLogsSettings';
type Props = {
trace?: TraceViewData;
@ -54,6 +58,9 @@ export function TraceView(props: Props) {
const traceProp = useMemo(() => transformTraceData(props.trace), [props.trace]);
const { search, setSearch, spanFindMatches } = useSearch(traceProp?.spans);
const dataSourceName = useSelector((state: StoreState) => state.explore.left.datasourceInstance?.name);
const traceToLogsOptions = (getDatasourceSrv().getInstanceSettings(dataSourceName)?.jsonData as TraceToLogsData)
?.tracesToLogs;
const theme = useTheme();
const traceTheme = useMemo(
@ -82,7 +89,10 @@ export function TraceView(props: Props) {
[childrenHiddenIDs, detailStates, hoverIndentGuideIds, spanNameColumnWidth, traceProp?.traceID]
);
const createSpanLink = useMemo(() => createSpanLinkFactory(props.splitOpenFn), [props.splitOpenFn]);
const createSpanLink = useMemo(() => createSpanLinkFactory(props.splitOpenFn, traceToLogsOptions), [
props.splitOpenFn,
traceToLogsOptions,
]);
const scrollElement = document.getElementsByClassName('scroll-canvas')[0];
if (!traceProp) {

View File

@ -1,47 +1,22 @@
import { createSpanLinkFactory } from './createSpanLink';
import { config, setDataSourceSrv, setTemplateSrv } from '@grafana/runtime';
import { DataSourceInstanceSettings, ScopedVars } from '@grafana/data';
import { setDataSourceSrv, setTemplateSrv } from '@grafana/runtime';
import { createSpanLinkFactory } from './createSpanLink';
describe('createSpanLinkFactory', () => {
beforeAll(() => {
config.featureToggles.traceToLogs = true;
});
afterAll(() => {
config.featureToggles.traceToLogs = false;
});
it('returns undefined if there is no loki data source', () => {
setDataSourceSrv({
getList() {
return [];
},
} as any);
it('returns undefined if there is no data source uid', () => {
const splitOpenFn = jest.fn();
const createLink = createSpanLinkFactory(splitOpenFn);
expect(createLink).not.toBeDefined();
});
it('creates correct link', () => {
describe('should return link', () => {
beforeAll(() => {
setDataSourceSrv({
getList() {
return [
{
name: 'loki1',
uid: 'lokiUid',
meta: {
id: 'loki',
},
} as DataSourceInstanceSettings,
];
},
getInstanceSettings(uid: string): DataSourceInstanceSettings | undefined {
if (uid === 'lokiUid') {
return {
uid: 'loki1',
name: 'loki1',
} as any;
}
return undefined;
},
} as any);
@ -50,13 +25,21 @@ describe('createSpanLinkFactory', () => {
return target!;
},
} as any);
});
it('with default keys when tags not configured', () => {
const splitOpenFn = jest.fn();
const createLink = createSpanLinkFactory(splitOpenFn);
const createLink = createSpanLinkFactory(splitOpenFn, { datasourceUid: 'lokiUid' });
expect(createLink).toBeDefined();
const linkDef = createLink!({
startTime: new Date('2020-10-14T01:00:00Z').valueOf() * 1000,
duration: 1000 * 1000,
tags: [
{
key: 'host',
value: 'host',
},
],
process: {
tags: [
{
@ -79,4 +62,72 @@ describe('createSpanLinkFactory', () => {
`/explore?left={"range":{"from":"20201014T000000","to":"20201014T010006"},"datasource":"loki1","queries":[{"expr":"{cluster=\\"cluster1\\", hostname=\\"hostname1\\"}","refId":""}]}`
);
});
it('with tags that passed in and without tags that are not in the span', () => {
const splitOpenFn = jest.fn();
const createLink = createSpanLinkFactory(splitOpenFn, { datasourceUid: 'lokiUid', tags: ['ip', 'newTag'] });
expect(createLink).toBeDefined();
const linkDef = createLink!({
startTime: new Date('2020-10-14T01:00:00Z').valueOf() * 1000,
duration: 1000 * 1000,
tags: [
{
key: 'host',
value: 'host',
},
],
process: {
tags: [
{
key: 'hostname',
value: 'hostname1',
},
{
key: 'ip',
value: '192.168.0.1',
},
],
} as any,
} as any);
expect(linkDef.href).toBe(
`/explore?left={"range":{"from":"20201014T000000","to":"20201014T010006"},"datasource":"loki1","queries":[{"expr":"{ip=\\"192.168.0.1\\"}","refId":""}]}`
);
});
it('from tags and process tags as well', () => {
const splitOpenFn = jest.fn();
const createLink = createSpanLinkFactory(splitOpenFn, {
datasourceUid: 'lokiUid',
tags: ['ip', 'host'],
});
expect(createLink).toBeDefined();
const linkDef = createLink!({
startTime: new Date('2020-10-14T01:00:00Z').valueOf() * 1000,
duration: 1000 * 1000,
tags: [
{
key: 'host',
value: 'host',
},
],
process: {
tags: [
{
key: 'hostname',
value: 'hostname1',
},
{
key: 'ip',
value: '192.168.0.1',
},
],
} as any,
} as any);
expect(linkDef.href).toBe(
`/explore?left={"range":{"from":"20201014T000000","to":"20201014T010006"},"datasource":"loki1","queries":[{"expr":"{ip=\\"192.168.0.1\\", host=\\"host\\"}","refId":""}]}`
);
});
});
});

View File

@ -1,23 +1,28 @@
import React from 'react';
import { config, getDataSourceSrv, getTemplateSrv } from '@grafana/runtime';
import { DataLink, dateTime, Field, mapInternalLinkToExplore, TimeRange, TraceSpan } from '@grafana/data';
import { LokiQuery } from '../../../plugins/datasource/loki/types';
import { getTemplateSrv } from '@grafana/runtime';
import { Icon } from '@grafana/ui';
import { TraceToLogsOptions } from 'app/core/components/TraceToLogsSettings';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import React from 'react';
import { LokiQuery } from '../../../plugins/datasource/loki/types';
/**
* This is a factory for the link creator. It returns the function mainly so it can return undefined in which case
* the trace view won't create any links and to capture the datasource and split function making it easier to memoize
* with useMemo.
*/
export function createSpanLinkFactory(splitOpenFn: (options: { datasourceUid: string; query: any }) => void) {
if (!config.featureToggles.traceToLogs) {
export function createSpanLinkFactory(
splitOpenFn: (options: { datasourceUid: string; query: any }) => void,
traceToLogsOptions?: TraceToLogsOptions
) {
// We should return if dataSourceUid is undefined otherwise getInstanceSettings would return testDataSource.
if (!traceToLogsOptions?.datasourceUid) {
return undefined;
}
// Right now just hardcoded for first loki DS we can find
const lokiDs = getDataSourceSrv().getList({ pluginId: 'loki' })[0];
const dataSourceSettings = getDatasourceSrv().getInstanceSettings(traceToLogsOptions.datasourceUid);
if (!lokiDs) {
if (!dataSourceSettings) {
return undefined;
}
@ -28,13 +33,13 @@ export function createSpanLinkFactory(splitOpenFn: (options: { datasourceUid: st
// it manually here instead of leaving it for the data source to supply the config.
const dataLink: DataLink<LokiQuery> = {
title: lokiDs.name,
title: dataSourceSettings.name,
url: '',
internal: {
datasourceUid: lokiDs.uid,
datasourceName: lokiDs.name,
datasourceUid: dataSourceSettings.uid,
datasourceName: dataSourceSettings.name,
query: {
expr: getLokiQueryFromSpan(span),
expr: getLokiQueryFromSpan(span, traceToLogsOptions.tags),
refId: '',
},
},
@ -59,13 +64,14 @@ export function createSpanLinkFactory(splitOpenFn: (options: { datasourceUid: st
}
/**
* Right now this is just hardcoded and later will probably be part of some user configuration.
* Default keys to use when there are no configured tags.
*/
const allowedKeys = ['cluster', 'hostname', 'namespace', 'pod'];
const defaultKeys = ['cluster', 'hostname', 'namespace', 'pod'];
function getLokiQueryFromSpan(span: TraceSpan): string {
const tags = span.process.tags.reduce((acc, tag) => {
if (allowedKeys.includes(tag.key)) {
function getLokiQueryFromSpan(span: TraceSpan, keys?: string[]): string {
const keysToCheck = keys?.length ? keys : defaultKeys;
const tags = [...span.process.tags, ...span.tags].reduce((acc, tag) => {
if (keysToCheck.includes(tag.key)) {
acc.push(`${tag.key}="${tag.value}"`);
}
return acc;

View File

@ -1,6 +1,7 @@
import React from 'react';
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
import { DataSourceHttpSettings } from '@grafana/ui';
import { TraceToLogsSettings } from 'app/core/components/TraceToLogsSettings';
import React from 'react';
export type Props = DataSourcePluginOptionsEditorProps;
@ -8,11 +9,13 @@ export const ConfigEditor: React.FC<Props> = ({ options, onOptionsChange }) => {
return (
<>
<DataSourceHttpSettings
defaultUrl={'http://localhost:16686'}
defaultUrl="http://localhost:16686"
dataSourceConfig={options}
showAccessOptions={true}
onChange={onOptionsChange}
/>
<TraceToLogsSettings options={options} onOptionsChange={onOptionsChange} />
</>
);
};

View File

@ -1,16 +1,21 @@
import React from 'react';
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
import { DataSourceHttpSettings } from '@grafana/ui';
import { TraceToLogsSettings } from 'app/core/components/TraceToLogsSettings';
import React from 'react';
export type Props = DataSourcePluginOptionsEditorProps;
export const ConfigEditor: React.FC<Props> = ({ options, onOptionsChange }) => {
return (
<>
<DataSourceHttpSettings
defaultUrl="http://localhost:16686"
dataSourceConfig={options}
showAccessOptions={false}
onChange={onOptionsChange}
/>
<TraceToLogsSettings options={options} onOptionsChange={onOptionsChange} />
</>
);
};

View File

@ -1,16 +1,21 @@
import React from 'react';
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
import { DataSourceHttpSettings } from '@grafana/ui';
import { TraceToLogsSettings } from 'app/core/components/TraceToLogsSettings';
import React from 'react';
export type Props = DataSourcePluginOptionsEditorProps;
export const ConfigEditor: React.FC<Props> = ({ options, onOptionsChange }) => {
return (
<>
<DataSourceHttpSettings
defaultUrl={'http://localhost:9411'}
defaultUrl="http://localhost:9411"
dataSourceConfig={options}
showAccessOptions={true}
onChange={onOptionsChange}
/>
<TraceToLogsSettings options={options} onOptionsChange={onOptionsChange} />
</>
);
};