mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Logs: Fix parsing for logfmt fields that have parens (#21407)
* Logs: Fix parsing for logfmt fields that have parens - added `()`, `[]`, and `{}` to be allowed in logfmt field names * Fix matcher
This commit is contained in:
parent
e9bcee30fa
commit
a3c99f4871
@ -98,21 +98,25 @@ describe('LogsParsers', () => {
|
||||
test('should return parsed fields', () => {
|
||||
expect(
|
||||
parser.getFields(
|
||||
'foo=bar baz="42 + 1" msg="[resolver] received A record \\"127.0.0.1\\" for \\"localhost.\\" from udp:192.168.65.1"'
|
||||
'foo=bar baz="42 + 1" msg="[resolver] received A record \\"127.0.0.1\\" for \\"localhost.\\" from udp:192.168.65.1" time(ms)=50 label{foo}=bar'
|
||||
)
|
||||
).toEqual([
|
||||
'foo=bar',
|
||||
'baz="42 + 1"',
|
||||
'msg="[resolver] received A record \\"127.0.0.1\\" for \\"localhost.\\" from udp:192.168.65.1"',
|
||||
'time(ms)=50',
|
||||
'label{foo}=bar',
|
||||
]);
|
||||
});
|
||||
|
||||
test('should return label for field', () => {
|
||||
expect(parser.getLabelFromField('foo=bar')).toBe('foo');
|
||||
expect(parser.getLabelFromField('time(ms)=50')).toBe('time(ms)');
|
||||
});
|
||||
|
||||
test('should return value for field', () => {
|
||||
expect(parser.getValueFromField('foo=bar')).toBe('bar');
|
||||
expect(parser.getValueFromField('time(ms)=50')).toBe('50');
|
||||
expect(
|
||||
parser.getValueFromField(
|
||||
'msg="[resolver] received A record \\"127.0.0.1\\" for \\"localhost.\\" from udp:192.168.65.1"'
|
||||
@ -126,6 +130,13 @@ describe('LogsParsers', () => {
|
||||
expect(match).toBeDefined();
|
||||
expect(match![1]).toBe('bar');
|
||||
});
|
||||
|
||||
test('should build a valid complex value matcher', () => {
|
||||
const matcher = parser.buildMatcher('time(ms)');
|
||||
const match = 'time(ms)=50'.match(matcher);
|
||||
expect(match).toBeDefined();
|
||||
expect(match![1]).toBe('50');
|
||||
});
|
||||
});
|
||||
|
||||
describe('JSON', () => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { countBy, chain } from 'lodash';
|
||||
import { countBy, chain, escapeRegExp } from 'lodash';
|
||||
|
||||
import { LogLevel, LogRowModel, LogLabelStatsModel, LogsParser } from '../types/logs';
|
||||
import { DataFrame, FieldType } from '../types/index';
|
||||
@ -8,7 +8,7 @@ import { ArrayVector } from '../vector/ArrayVector';
|
||||
// first a label from start of the string or first white space, then any word chars until "="
|
||||
// second either an empty quotes, or anything that starts with quote and ends with unescaped quote,
|
||||
// or any non whitespace chars that do not start with qoute
|
||||
const LOGFMT_REGEXP = /(?:^|\s)(\w+)=(""|(?:".*?[^\\]"|[^"\s]\S*))/;
|
||||
const LOGFMT_REGEXP = /(?:^|\s)([\w\(\)\[\]\{\}]+)=(""|(?:".*?[^\\]"|[^"\s]\S*))/;
|
||||
|
||||
/**
|
||||
* Returns the log level of a log line.
|
||||
@ -85,7 +85,7 @@ export const LogsParsers: { [name: string]: LogsParser } = {
|
||||
},
|
||||
|
||||
logfmt: {
|
||||
buildMatcher: label => new RegExp(`(?:^|\\s)${label}=("[^"]*"|\\S+)`),
|
||||
buildMatcher: label => new RegExp(`(?:^|\\s)${escapeRegExp(label)}=("[^"]*"|\\S+)`),
|
||||
getFields: line => {
|
||||
const fields: string[] = [];
|
||||
line.replace(new RegExp(LOGFMT_REGEXP, 'g'), substring => {
|
||||
|
Loading…
Reference in New Issue
Block a user