Skip to content

Commit 0dd2ab9

Browse files
func25valyala
andauthored
app/vlinsert/loki: parse JSON message with trailing whitespace/newlines (#1045)
Signed-off-by: Aliaksandr Valialkin <valyala@victoriametrics.com> Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
1 parent fd9d5e4 commit 0dd2ab9

3 files changed

Lines changed: 36 additions & 5 deletions

File tree

app/vlinsert/loki/loki_json.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,20 +182,44 @@ func parseJSONRequest(data []byte, lmp insertutil.LogMessageProcessor, msgFields
182182
}
183183

184184
func addMsgField(fs *logstorage.Fields, msgParser *logstorage.JSONParser, msg string, preserveKeys []string) bool {
185-
if msgParser == nil || len(msg) < 2 || msg[0] != '{' || msg[len(msg)-1] != '}' {
185+
if msgParser == nil || len(msg) < 2 || msg[0] != '{' {
186186
fs.Add("_msg", msg)
187187
return false
188188
}
189-
if msgParser != nil && len(msg) >= 2 && msg[0] == '{' && msg[len(msg)-1] == '}' {
190-
if err := msgParser.ParseLogMessage(bytesutil.ToUnsafeBytes(msg), preserveKeys); err == nil {
191-
fs.Fields = append(fs.Fields, msgParser.Fields...)
192-
return true
189+
190+
// Trailing whitespace in the JSON message shouldn't break automatic JSON parsing.
191+
//
192+
// See https://github.com/VictoriaMetrics/VictoriaLogs/issues/1044
193+
msgTrimmed := msg
194+
if msg[len(msg)-1] != '}' {
195+
msgTrimmed = trimTrailingJSONWhitespace(msg)
196+
if len(msgTrimmed) < 2 || msgTrimmed[len(msgTrimmed)-1] != '}' {
197+
fs.Add("_msg", msg)
198+
return false
193199
}
194200
}
201+
202+
if err := msgParser.ParseLogMessage(bytesutil.ToUnsafeBytes(msgTrimmed), preserveKeys); err == nil {
203+
fs.Fields = append(fs.Fields, msgParser.Fields...)
204+
return true
205+
}
195206
fs.Add("_msg", msg)
196207
return false
197208
}
198209

210+
func trimTrailingJSONWhitespace(s string) string {
211+
i := len(s)
212+
for i > 0 {
213+
switch s[i-1] {
214+
case ' ', '\n', '\r', '\t':
215+
i--
216+
default:
217+
return s[:i]
218+
}
219+
}
220+
return ""
221+
}
222+
199223
func parseLokiTimestamp(s string) (int64, error) {
200224
if s == "" {
201225
// Special case - an empty timestamp must be substituted with the current time by the caller.

app/vlinsert/loki/loki_json_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,10 @@ func TestParseJSONRequest_ParseMessage(t *testing.T) {
198198
}
199199
]
200200
}`, []string{"a", "trace_id"}, []string{"x"}, []int64{1577836800000000001}, `{"x":"y","_msg":"111","parent_id":"abc","x":"{\"a\":123}"}`)
201+
202+
// with trailing whitespace in the JSON message
203+
f(`{"streams":[{"stream":{"foo":"bar2"},"values":[["1577836800000000001","{\"bar\":\"baz\",\"_msg\":\"I am parsed\"}\n"]]}]}`,
204+
nil, nil, []int64{1577836800000000001}, `{"foo":"bar2","bar":"baz","_msg":"I am parsed"}`)
205+
f(`{"streams":[{"stream":{"foo":"bar2"},"values":[["1577836800000000001","{\"bar\":\"baz\",\"_msg\":\"I am parsed\"}\r\n\t "]]}]}`,
206+
nil, nil, []int64{1577836800000000001}, `{"foo":"bar2","bar":"baz","_msg":"I am parsed"}`)
201207
}

docs/victorialogs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ according to the following docs:
3030
* FEATURE: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): add support for toggling line comments with `Ctrl/Cmd + /`. See [#1030](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1030).
3131

3232
* BUGFIX: [`/select/logsql/hits` endpoint](https://docs.victoriametrics.com/victorialogs/querying/#querying-hits-stats): properly apply `offset` arg. Previously it resulted in incorrect calculations for the returned timestamps.
33+
* BUGFIX: [Loki data ingestion](https://docs.victoriametrics.com/victorialogs/data-ingestion/promtail/): properly parse JSON-encoded log fields inside Loki log message if it ends with whitespace chars such as `\n`. See [#1044](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1044).
3334
* BUGFIX: [dashboard/single-node](https://grafana.com/grafana/dashboards/22084): include `internalinsert` (`/internal/insert`) in `Logs ingestion rate` panels, so they work for data ingested via `vlagent` configured with `-remoteWrite.url=.../internal/insert`. See [#1053](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1053).
3435
* BUGFIX: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): fix autocomplete insertion to prevent overwriting remaining input and preserve newline characters. See [#917](https://github.com/VictoriaMetrics/VictoriaLogs/issues/917).
3536
* BUGFIX: [web UI](https://docs.victoriametrics.com/victorialogs/querying/#web-ui): fix unexpected query expression reset to the previous value when clicking on "Hide chart" button. See [#1063](https://github.com/VictoriaMetrics/VictoriaLogs/issues/1063).

0 commit comments

Comments
 (0)