Loki: Allow regex in label derived field (#96609)

* Loki: Allow regex in `label` derived field

* add docs

* change to caution
This commit is contained in:
Sven Grossmann 2024-11-19 20:01:56 +01:00 committed by GitHub
parent 8527f986db
commit 51efde972b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 35 additions and 6 deletions

View File

@ -114,9 +114,13 @@ Each derived field consists of the following:
- **Type** - Defines the type of the derived field. It can be either:
- **Regex**: A regular expression to parse a part of the log message and capture it as the value of the new field. Can contain only one capture group.
{{% admonition type="caution" %}}
Using complex regular expressions in either type can impact browser performance when processing large volumes of logs. Consider using simpler patterns when possible.
{{% /admonition %}}
- **Label**: A label from the selected log line. This can be any type of label - indexed, parsed or structured metadata. The label's value will be used as the value of the derived field.
- **Regex**: A regular expression to parse a part of the log message and capture it as the value of the new field. Can contain only one capture group.
- **Label**: A label from the selected log line. This can be any type of label - indexed, parsed or structured metadata. When using this type, the input will match as a regular expression against label keys, allowing you to match variations like `traceid` and `trace_id` with a single regex pattern like `trace[_]?id`. The value of the matched label will be used as the value of the derived field.
- **URL/query** Sets the full link URL if the link is external, or a query for the target data source if the link is internal. You can interpolate the value from the field with the `${__value.raw}` macro.

View File

@ -192,4 +192,28 @@ describe('getDerivedFields', () => {
title: '',
});
});
it('matches label keys using regex when matcherType is label', () => {
const df = createDataFrame({
fields: [
{ name: 'labels', values: [{ traceId: 'abc' }, { traceID: 'xyz' }] },
{ name: 'line', values: ['log1', 'log2'] },
],
});
const newFields = getDerivedFields(df, [
{
matcherRegex: 'traceI(d|D)',
name: 'traceIdFromLabel',
url: 'http://localhost/${__value.raw}',
matcherType: 'label',
},
]);
expect(newFields.length).toBe(1);
const traceId = newFields.find((f) => f.name === 'traceIdFromLabel');
expect(traceId!.values).toEqual(['abc', 'xyz']);
expect(traceId!.config.links![0]).toEqual({
url: 'http://localhost/${__value.raw}',
title: '',
});
});
});

View File

@ -30,10 +30,11 @@ export function getDerivedFields(dataFrame: DataFrame, derivedFieldConfigs: Deri
if (derivedFieldsGrouped[field.name][0].matcherType === 'label' && labelFields) {
const label = labelFields.values[i];
if (label) {
// Find the key that matches both, the `matcherRegex` and the label key
const intersectingKey = Object.keys(label).find(
(key) => derivedFieldsGrouped[field.name][0].matcherRegex === key
);
// Find the key that matches the regex pattern in `matcherRegex`
const intersectingKey = Object.keys(label).find((key) => {
const regex = new RegExp(derivedFieldsGrouped[field.name][0].matcherRegex);
return regex.test(key);
});
if (intersectingKey) {
field.values.push(label[intersectingKey]);