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
pull/21421/head
David 5 years ago committed by GitHub
parent e9bcee30fa
commit a3c99f4871
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      packages/grafana-data/src/utils/logs.test.ts
  2. 6
      packages/grafana-data/src/utils/logs.ts

@ -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…
Cancel
Save