Hi all,
I have a strange problem parsing a JSON-ish file.
We log in a JSON format where a multiline string can be added in a Message field.
TLDR;
Filebeat doesn't send the last two }} of the file for some reason.
Sourcefile:
{ "@timestamp":"2018-07-06T18:32:59.0864644+02:00", "Level":"Error", "Event": { "Context": "Default", "Message":"Error while executing the Task: Unable to connect to the remote server, StackTrace:    at blabablablablablabablablablablabablablablablabablablabla
   at blabablablabla()
   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla
   at blabablablablablabablablablablabablablablablabablablablablabablablabla
   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla
   at blabablablablablabablablablablabablablablablabablablablablabablablabla"}}
{ "@timestamp":"2018-07-06T19:32:59.0864644+02:00", "Level":"Error", "Event": { "Context": "Default", "Message":"Error while executing the Task: Unable to connect to the remote server, StackTrace:    at blabablablablablabablablablablabablablablablabablablabla
   at blabablablabla()
   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla
   at blabablablablablabablablablablabablablablablabablablablablabablablabla
   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla
   at blabablablablablabablablablablabablablablablabablablablablabablablabla"}}
When I parse this with Filebeat with the following config:
filebeat.inputs:
- type: log
  paths:
  - C:\Logs\*.jlog
  #exclude_files: ['.*SbrRequestServerService.*'] #This should not exist in the log dir.
  fields_under_root: true
  multiline.pattern: '^{'
  multiline.negate: true
  multiline.match: after
output:
  logstash:
    hosts: ["localhost:3542"]
And parse it in Logstash like so:
filter { 
   if [type] == "jlog" {
        mutate { 
            gsub => ["message", "\n", ""] 
        }
        json {
            source => "message"
        }          
    }
}
I see that the last logline is missing it's }} in the message field.
The parsing fails for that one.
[2018-07-13T06:34:38,086][WARN ][logstash.filters.json    ] Error parsing json {:source=>"message", :raw=>"{ \"@timestamp\":\"2018-07-06T19:32:59.0864644+02:00\", \"Level\":\"Error\", \"Event\": { \"Context\": \"Default\", \"Message\":\"Error while executing the Task: Unable to connect to the remote server, StackTrace:    at blabablablablablabablablablablabablablablablabablablabla   at blabablablabla()   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla", :exception=>#<LogStash::Json::ParserError: Unexpected end-of-input in VALUE_STRING
 at [Source: (byte[])"{ "@timestamp":"2018-07-06T19:32:59.0864644+02:00", "Level":"Error", "Event": { "Context": "Default", "Message":"Error while executing the Task: Unable to connect to the remote server, StackTrace:
at blabablablablablabablablablablabablablablablabablablabla   at blabablablabla()   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablaba"[truncated 79 bytes]; line: 1, column: 1159]>}
{
  "@version" => "1",
      "type" => "jlog",
   "message" => "{ \"@timestamp\":\"2018-07-06T18:32:59.0864644+02:00\", \"Level\":\"Error\", \"Event\": { \"Context\": \"Default\", \"Message\":\"Error while executing the Task: Unable to connect to the remote server, StackTrace:    at blabablablablablabablablablablabablablablablabablablabla   at blabablablabla()   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablabla**bla\"}}**",
"prospector" => {
    "type" => "log"
},
      "host" => {
    "name" => "LT-3T2S1G2"
},
     "Event" => {
    "Context" => "Default",
    "Message" => "Error while executing the Task: Unable to connect to the remote server, StackTrace:    at blabablablablablabablablablablabablablablablabablablabla   at blabablablabla()   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablablabla"
},
    "source" => "C:\\Logs\\0e44c70a-1740-49d7-ab12-6492bbe78251_2018-07-06_1864_Default.jlog",
     "input" => {
    "type" => "log"
},
      "beat" => {},
     "Level" => "Error",
"@timestamp" => 2018-07-06T16:32:59.086Z,
      "tags" => []
}
{
  "@version" => "1",
      "type" => "jlog",
   "message" => "{ \"@timestamp\":\"2018-07-06T19:32:59.0864644+02:00\", \"Level\":\"Error\", \"Event\": { \"Context\": \"Default\", \"Message\":\"Error while executing the Task: Unable to connect to the remote server, StackTrace:    at blabablablablablabablablablablabablablablablabablablabla   at blabablablabla()   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablablabla   at blabablablablablabablablablablabablablablablabablablablablabablablablablabablablablablababla**blabla"**,
"prospector" => {
    "type" => "log"
},
      "host" => {
    "name" => "LT-3T2S1G2"
},
     "input" => {
    "type" => "log"
},
    "source" => "C:\\Logs\\0e44c70a-1740-49d7-ab12-6492bbe78251_2018-07-06_1864_Default.jlog",
      "beat" => {},
"@timestamp" => 2018-07-13T06:34:26.280Z,
      "tags" => [
    [0] "_jsonparsefailure"
]
}
When I add a newline after the last line, the parsing succeeds.
filebeat version 6.3.1 (amd64), libbeat 6.3.1 [ed42bb85e72ae58cc09748dc1825159713e0ffd4 built 2018-06-29 21:09:04 +0000 UTC]
BTW:
Th reason we do this is so that we are able to read Message field with newline chars. Is there a better way to parse this?
Best regards,
Sander
