Explore: Support custom display label for derived fields buttons for Loki datasource (#37273)

This commit is contained in:
Connor Lindsey 2021-07-29 12:42:20 -06:00 committed by GitHub
parent aa904a5a04
commit c4c28a5b63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 66 additions and 31 deletions

View File

@ -16,7 +16,7 @@ visualize logs or metrics stored in Elasticsearch. You can also annotate your gr
1. Open the side menu by clicking the Grafana icon in the top header.
1. In the side menu under the `Dashboards` link you should find a link named `Data Sources`.
1. Click the `+ Add data source` button in the top header.
1. Select *Elasticsearch* from the *Type* dropdown.
1. Select **Elasticsearch** from the **Type** dropdown.
> **Note:** If you're not seeing the `Data Sources` link in your side menu it means that your current user does not have the `Admin` role for the current organization.
@ -104,6 +104,7 @@ Data links create a link from a specified field that can be accessed in logs vie
Each data link configuration consists of:
- **Field -** Name of the field used by the data link.
- **URL/query -** If the link is external, then enter the full link URL. If the link is internal link, then this input serves as query for the target data source. In both cases, you can interpolate the value from the field with `${__value.raw }` macro.
- **URL Label -** (Optional) Set a custom display label for the link. The link label defaults to the full external URL or name of the linked internal data source and is overridden by this setting.
- **Internal link -** Select if the link is internal or external. In case of internal link, a data source selector allows you to select the target data source. Only tracing data sources are supported.
## Metric Query editor

View File

@ -33,13 +33,14 @@ The Derived Fields configuration allows you to:
- Add fields parsed from the log message.
- Add a link that uses the value of the field.
You can use this functionality to link to your tracing backend directly from your logs, or link to a user profile page if a userId is present in the log line. These links appear in the [log details]({{< relref "../explore/logs-integration/#labels-and-detected-fields" >}}).
For example, you can use this functionality to link to your tracing backend directly from your logs, or link to a user profile page if a userId is present in the log line. These links appear in the [log details]({{< relref "../explore/logs-integration/#labels-and-detected-fields" >}}).
Each derived field consists of:
- **Name -** Shown in the log details as a label.
- **Regex -** A Regex pattern that runs on the log message and captures part of it as the value of the new field. Can only contain a single capture group.
- **URL/query -** If the link is external, then enter the full link URL. If the link is internal link, then this input serves as query for the target data source. In both cases, you can interpolate the value from the field with `${__value.raw }` macro.
- **URL Label -** (Optional) Set a custom display label for the link. The link label defaults to the full external URL or name of the linked internal data source and is overridden by this setting.
- **Internal link -** Select if the link is internal or external. In case of internal link, a data source selector allows you to select the target data source. Only tracing data sources are supported.
You can use a debug section to see what your fields extract and how the URL is interpolated. Click **Show example log message** to show the text area where you can enter a log message.

View File

@ -21,6 +21,12 @@ const getStyles = stylesFactory(() => ({
display: flex;
align-items: baseline;
`,
urlField: css`
flex: 1;
`,
urlDisplayLabelField: css`
flex: 1;
`,
}));
type Props = {
@ -83,9 +89,16 @@ export const DataLink = (props: Props) => {
suggestions={suggestions}
/>
}
className={css`
width: 100%;
`}
className={styles.urlField}
/>
<FormField
className={styles.urlDisplayLabelField}
inputWidth={null}
label="URL Label"
type="text"
value={value.urlDisplayLabel}
onChange={handleChange('urlDisplayLabel')}
tooltip={'Use to override the button label.'}
/>
</div>

View File

@ -3,6 +3,7 @@ import { Observable, of, throwError } from 'rxjs';
import {
ArrayVector,
CoreApp,
DataLink,
DataQueryRequest,
DataSourceInstanceSettings,
DataSourcePluginMeta,
@ -255,14 +256,16 @@ describe('ElasticDatasource', function (this: any) {
{
field: 'host',
url: 'http://localhost:3000/${__value.raw}',
urlDisplayLabel: 'Custom Label',
},
],
});
expect(response.data.length).toBe(1);
const links = response.data[0].fields.find((field: Field) => field.name === 'host').config.links;
const links: DataLink[] = response.data[0].fields.find((field: Field) => field.name === 'host').config.links;
expect(links.length).toBe(1);
expect(links[0].url).toBe('http://localhost:3000/${__value.raw}');
expect(links[0].title).toBe('Custom Label');
});
});

View File

@ -896,7 +896,7 @@ export function enhanceDataFrame(dataFrame: DataFrame, dataLinks: DataLinkConfig
const dsSettings = dataSourceSrv.getInstanceSettings(dataLinkConfig.datasourceUid);
link = {
title: '',
title: dataLinkConfig.urlDisplayLabel || '',
url: '',
internal: {
query: { query: dataLinkConfig.url },
@ -906,7 +906,7 @@ export function enhanceDataFrame(dataFrame: DataFrame, dataLinks: DataLinkConfig
};
} else {
link = {
title: '',
title: dataLinkConfig.urlDisplayLabel || '',
url: dataLinkConfig.url,
};
}

View File

@ -75,5 +75,6 @@ export interface ElasticsearchQuery extends DataQuery {
export type DataLinkConfig = {
field: string;
url: string;
urlDisplayLabel?: string;
datasourceUid?: string;
};

View File

@ -19,6 +19,12 @@ const getStyles = stylesFactory(() => ({
regexField: css`
flex: 3;
`,
urlField: css`
flex: 1;
`,
urlDisplayLabelField: css`
flex: 1;
`,
}));
type Props = {
@ -89,26 +95,34 @@ export const DerivedField = (props: Props) => {
/>
</div>
<FormField
label={showInternalLink ? 'Query' : 'URL'}
labelWidth={5}
inputEl={
<DataLinkInput
placeholder={showInternalLink ? '${__value.raw}' : 'http://example.com/${__value.raw}'}
value={value.url || ''}
onChange={(newValue) =>
onChange({
...value,
url: newValue,
})
}
suggestions={suggestions}
/>
}
className={css`
width: 100%;
`}
/>
<div className={styles.row}>
<FormField
label={showInternalLink ? 'Query' : 'URL'}
inputEl={
<DataLinkInput
placeholder={showInternalLink ? '${__value.raw}' : 'http://example.com/${__value.raw}'}
value={value.url || ''}
onChange={(newValue) =>
onChange({
...value,
url: newValue,
})
}
suggestions={suggestions}
/>
}
className={styles.urlField}
/>
<FormField
className={styles.urlDisplayLabelField}
inputWidth={null}
label="URL Label"
type="text"
value={value.urlDisplayLabel}
onChange={handleChange('urlDisplayLabel')}
tooltip={'Use to override the button label when this derived field is found in a log.'}
/>
</div>
<div className={styles.row}>
<Switch

View File

@ -260,6 +260,7 @@ describe('enhanceDataFrame', () => {
name: 'trace2',
url: 'test',
datasourceUid: 'uid2',
urlDisplayLabel: 'Custom Label',
},
],
});
@ -279,7 +280,7 @@ describe('enhanceDataFrame', () => {
url: '',
});
expect(fc.getFieldByName('trace2')!.config.links![1]).toEqual({
title: '',
title: 'Custom Label',
internal: { datasourceName: 'Loki1', datasourceUid: 'uid2', query: { query: 'test' } },
url: '',
});

View File

@ -427,7 +427,7 @@ function fieldFromDerivedFieldConfig(derivedFieldConfigs: DerivedFieldConfig[]):
acc.push({
// Will be filled out later
title: '',
title: derivedFieldConfig.urlDisplayLabel || '',
url: '',
// This is hardcoded for Jaeger or Zipkin not way right now to specify datasource specific query object
internal: {
@ -439,7 +439,7 @@ function fieldFromDerivedFieldConfig(derivedFieldConfigs: DerivedFieldConfig[]):
} else if (derivedFieldConfig.url) {
acc.push({
// We do not know what title to give here so we count on presentation layer to create a title from metadata.
title: '',
title: derivedFieldConfig.urlDisplayLabel || '',
// This is hardcoded for Jaeger or Zipkin not way right now to specify datasource specific query object
url: derivedFieldConfig.url,
});

View File

@ -112,6 +112,7 @@ export type DerivedFieldConfig = {
matcherRegex: string;
name: string;
url?: string;
urlDisplayLabel?: string;
datasourceUid?: string;
};