1

I have been trying to pass logs from a windows application which are already formatted in JSON to logstash via NXlog.

When I have NXLOG send the file to Logstash, I get blasted with errors in the logstash.log:

:message=>"An error occurred. Closing connection",
:client=>"10.xxx.xxx.147:61047",
:exception=>#<IndexError: string not matched>

Full text of error:

{:timestamp=>"2015-04-25T15:15:37.084000-0900", :message=>"An error occurred. Closing connection", :client=>"10.xxx.xxx.147:61047", :exception=>#<IndexError: string not matched>, :backtrace=>["org/jruby/RubyString.java:3910:in `[]='", "/opt/logstash/lib/logstash/event.rb:62:in `initialize'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-codec-json_lines-0.1.6/lib/logstash/codecs/json_lines.rb:37:in `decode'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-codec-line-0.1.5/lib/logstash/codecs/line.rb:36:in `decode'", "org/jruby/RubyArray.java:1613:in `each'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-codec-line-0.1.5/lib/logstash/codecs/line.rb:35:in `decode'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-codec-json_lines-0.1.6/lib/logstash/codecs/json_lines.rb:35:in `decode'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-input-tcp-0.1.3/lib/logstash/inputs/tcp.rb:116:in `handle_socket'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-input-tcp-0.1.3/lib/logstash/inputs/tcp.rb:145:in `client_thread'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-input-tcp-0.1.3/lib/logstash/inputs/tcp.rb:143:in `client_thread'"], :level=>:error}
{:timestamp=>"2015-04-25T15:15:38.097000-0900", :message=>"JSON parse failure. Falling back to plain-text", :error=>#<LogStash::Json::ParserError: Unexpected end-of-input: expected close marker for OBJECT (from [Source: [B@26f64966; line: 1, column: 2])
 at [Source: [B@26f64966; line: 2, column: 5]>, :data=>"  {\r\n", :level=>:info}

Here is my NXLOG configuration:

## Please set the ROOT to the folder your nxlog was installed into,
## otherwise it will not start.

define ROOT C:\Program Files (x86)\nxlog

Moduledir %ROOT%\modules
CacheDir %ROOT%\data
Pidfile %ROOT%\data\nxlog.pid
SpoolDir %ROOT%\data
LogFile %ROOT%\data\nxlog.log

<Extension json>
    Module      xm_json
</Extension>

# Nxlog internal logs
<Input internal>
    Module im_internal
    Exec $EventReceivedTime = integer($EventReceivedTime) / 1000000; to_json();
</Input>


# Windows Event Log
<Input eventlog>
    Module im_msvistalog
    Exec $EventReceivedTime = integer($EventReceivedTime) / 1000000; to_json();
</Input>

#Server Logs
<Input Selected_Directory>
    Module      im_file
    File        'E:\\ELK\\logs\\*.json'
    SavePos     False
</Input>

#EventLog Out
<Output out>
   Module om_tcp
   Host 10.xxx.xxx.127
   Port 3515
</Output>

#<output perf_out>
#   Module om_tcp
#   Host 10.xxx.xxx.127
#   Port 3517
#</Output>

#JSON Out
<Output out2>
   Module om_tcp
   Host 10.xxx.xxx.127
   Port 3516
</Output> 

<Route 1>
    Path internal, eventlog => out
</Route>

<Route 2>
    Path    Selected_Directory => out2
</Route>

LogStash conf:

input {
        tcp {
            type   => "eventlog"
            port   => 3515
            codec => json_lines
        }
        tcp {
            type   => "log"
            port   => 3516
            codec => json
        }
    }

output {
    elasticsearch {
        cluster => "MyElkCluster"
        host => "127.0.0.1"
    }
}

Example of application's JSON file format:

[
 {
   "timestamp":"19:54:01.117_0005",
   "type":"N",
   "calllevel":0,
   "thread":772,
   "topic":"ExmpleTopic",
   "level":61,
   "file":"//blah/blah/blah.cpp",
   "function":"functiontext",
   "line":312,
   "message":"Example Message Text",
   "attributes":
    {
      "ThreadName":"1234"
    }
 },
 {
   "timestamp":"20:07:54.038_0691",
   "type":"N",
   "calllevel":0,
   "thread":2324,
   "topic":"ExampleTopic",
   "level":61,
   "file":"//blah/blah/blah.cpp",
   "function":"ExampleFunction",
   "line":2962,
   "message":"Example Message Text",
   "attributes":
    {
      "ThreadName":"1234"
    }
 }
]

I have two additional questions aside from the obvious "help me figure out this error"

  1. What is the difference between json_lines and json when it comes to logstash input? It was my understanding that json_lines was for streaming text, and json implied that I would send the entire file at one time.
  2. Do I need to add "exec to_json();" to my nxlog input named 'selected_directory'?
Noobixide
  • 126
  • 1
  • 13

2 Answers2

0

I would suggest trying the tcp input, forget about defining the codec in your input, it's generally a bad idea I have found:

input {
  tcp {
    type   => "eventlog"
    port   => 3515
  }
}
filter {
  multiline {
    pattern => "^\s"
    what => "previous"
  }
  json {
    "source" => "message"
  }
}

output {
  elasticsearch {
    cluster => "MyElkCluster"
    host => "127.0.0.1"
  }
}

So in this config, it will accept the traffic on the tcp port defined, not setting a codec, then pass the input to a multiline filter, which will look for lines which start with whitespace, and if it finds any it will join them to the previous line. That new line created by muliline will then be passed to the json filter, which should be able to parse the entry.

Rumbles
  • 915
  • 1
  • 12
  • 27
0

I was also getting an error when using the json_lines codec that said:

IndexError: string not matched

and solved it by making sure the JSON string I was generating did not contain any newline characters (ie: "\n") except for immediately following the JSON object, as a delimiter.