diff --git a/pkg/logql/log/parser.go b/pkg/logql/log/parser.go index 9a5ae1395069c..4893999016878 100644 --- a/pkg/logql/log/parser.go +++ b/pkg/logql/log/parser.go @@ -617,6 +617,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 3e5de0f709418..7acebbe849afb 100644 --- a/pkg/logql/log/parser_test.go +++ b/pkg/logql/log/parser_test.go @@ -494,13 +494,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)