mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 08:05:43 -06:00
Explore: Support custom display label for derived fields buttons for Loki datasource (#37273)
This commit is contained in:
parent
aa904a5a04
commit
c4c28a5b63
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
@ -75,5 +75,6 @@ export interface ElasticsearchQuery extends DataQuery {
|
||||
export type DataLinkConfig = {
|
||||
field: string;
|
||||
url: string;
|
||||
urlDisplayLabel?: string;
|
||||
datasourceUid?: string;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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: '',
|
||||
});
|
||||
|
@ -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,
|
||||
});
|
||||
|
@ -112,6 +112,7 @@ export type DerivedFieldConfig = {
|
||||
matcherRegex: string;
|
||||
name: string;
|
||||
url?: string;
|
||||
urlDisplayLabel?: string;
|
||||
datasourceUid?: string;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user