diff --git a/docs/sources/datasources/elasticsearch.md b/docs/sources/datasources/elasticsearch.md index 356d3dfc850..2d4aa2ead4f 100644 --- a/docs/sources/datasources/elasticsearch.md +++ b/docs/sources/datasources/elasticsearch.md @@ -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 diff --git a/docs/sources/datasources/loki.md b/docs/sources/datasources/loki.md index d9167829151..42de0f5b35d 100644 --- a/docs/sources/datasources/loki.md +++ b/docs/sources/datasources/loki.md @@ -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. diff --git a/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx b/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx index cacb0361596..cbd29a74d3b 100644 --- a/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx +++ b/public/app/plugins/datasource/elasticsearch/configuration/DataLink.tsx @@ -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} + /> + diff --git a/public/app/plugins/datasource/elasticsearch/datasource.test.ts b/public/app/plugins/datasource/elasticsearch/datasource.test.ts index c109c5505d7..153dcdbe773 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.test.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.test.ts @@ -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'); }); }); diff --git a/public/app/plugins/datasource/elasticsearch/datasource.ts b/public/app/plugins/datasource/elasticsearch/datasource.ts index 51be789c091..03fd28cec11 100644 --- a/public/app/plugins/datasource/elasticsearch/datasource.ts +++ b/public/app/plugins/datasource/elasticsearch/datasource.ts @@ -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, }; } diff --git a/public/app/plugins/datasource/elasticsearch/types.ts b/public/app/plugins/datasource/elasticsearch/types.ts index 57903a05057..067fcfcd2d5 100644 --- a/public/app/plugins/datasource/elasticsearch/types.ts +++ b/public/app/plugins/datasource/elasticsearch/types.ts @@ -75,5 +75,6 @@ export interface ElasticsearchQuery extends DataQuery { export type DataLinkConfig = { field: string; url: string; + urlDisplayLabel?: string; datasourceUid?: string; }; diff --git a/public/app/plugins/datasource/loki/configuration/DerivedField.tsx b/public/app/plugins/datasource/loki/configuration/DerivedField.tsx index 64c96074c3c..b09642036f4 100644 --- a/public/app/plugins/datasource/loki/configuration/DerivedField.tsx +++ b/public/app/plugins/datasource/loki/configuration/DerivedField.tsx @@ -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) => { /> - - onChange({ - ...value, - url: newValue, - }) - } - suggestions={suggestions} - /> - } - className={css` - width: 100%; - `} - /> +
+ + onChange({ + ...value, + url: newValue, + }) + } + suggestions={suggestions} + /> + } + className={styles.urlField} + /> + +
{ 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: '', }); diff --git a/public/app/plugins/datasource/loki/result_transformer.ts b/public/app/plugins/datasource/loki/result_transformer.ts index 503a77e5195..817ee1066d2 100644 --- a/public/app/plugins/datasource/loki/result_transformer.ts +++ b/public/app/plugins/datasource/loki/result_transformer.ts @@ -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, }); diff --git a/public/app/plugins/datasource/loki/types.ts b/public/app/plugins/datasource/loki/types.ts index 0b751fb73f5..ad5f705a006 100644 --- a/public/app/plugins/datasource/loki/types.ts +++ b/public/app/plugins/datasource/loki/types.ts @@ -112,6 +112,7 @@ export type DerivedFieldConfig = { matcherRegex: string; name: string; url?: string; + urlDisplayLabel?: string; datasourceUid?: string; };