From 08b1a9080b03bc041471f1ef72c4e3d7c6aea4f4 Mon Sep 17 00:00:00 2001 From: Vladyslav Diachenko <82767850+vlad-diachenko@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:39:27 +0300 Subject: [PATCH] fix(logql): updated JSONExpressionParser not to unescape extracted values if it is JSON object. (#14499) Signed-off-by: Vladyslav Diachenko --- pkg/logql/log/parser.go | 2 ++ pkg/logql/log/parser_test.go | 30 ++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/pkg/logql/log/parser.go b/pkg/logql/log/parser.go index c8e65061ba41..50d973eb8b7d 100644 --- a/pkg/logql/log/parser.go +++ b/pkg/logql/log/parser.go @@ -625,6 +625,8 @@ func (j *JSONExpressionParser) Process(_ int64, line []byte, lbs *LabelsBuilder) switch typ { case jsonparser.Null: lbs.Set(ParsedLabel, key, "") + case jsonparser.Object: + lbs.Set(ParsedLabel, key, string(data)) default: lbs.Set(ParsedLabel, key, unescapeJSONString(data)) } diff --git a/pkg/logql/log/parser_test.go b/pkg/logql/log/parser_test.go index 5ac57b9ef054..5ac3a8750363 100644 --- a/pkg/logql/log/parser_test.go +++ b/pkg/logql/log/parser_test.go @@ -542,13 +542,35 @@ func TestJSONExpressionParser(t *testing.T) { ), NoParserHints(), }, + { + "nested object with escaped value", + []byte(`{"app":{"name":"great \"loki\""}`), + []LabelExtractionExpr{ + NewLabelExtractionExpr("app", `app`), + }, + labels.FromStrings("foo", "bar"), + labels.FromStrings("foo", "bar", + "app", `{"name":"great \"loki\""}`, + ), + NoParserHints(), + }, + { + "field with escaped value inside the json string", + []byte(`{"app":"{\"name\":\"great \\\"loki\\\"\"}"}`), + []LabelExtractionExpr{ + NewLabelExtractionExpr("app", `app`), + }, + labels.FromStrings("foo", "bar"), + labels.FromStrings("foo", "bar", + "app", `{"name":"great \"loki\""}`, + ), + NoParserHints(), + }, } for _, tt := range tests { - j, err := NewJSONExpressionParser(tt.expressions) - if err != nil { - t.Fatalf("cannot create JSON expression parser: %s", err.Error()) - } t.Run(tt.name, func(t *testing.T) { + j, err := NewJSONExpressionParser(tt.expressions) + require.NoError(t, err, "cannot create JSON expression parser") b := NewBaseLabelsBuilderWithGrouping(nil, tt.hints, false, false).ForLabels(tt.lbs, tt.lbs.Hash()) b.Reset() _, _ = j.Process(0, tt.line, b)