Commit a3c99f48 by David Committed by GitHub

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
parent e9bcee30
......@@ -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', () => {
......
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 => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment