logstash-codec-json_stream 0.0.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +3 -0
- data/README.md +1 -1
- data/lib/logstash/codecs/json_stream.rb +23 -49
- data/logstash-codec-json_stream.gemspec +1 -1
- data/spec/codecs/json_stream_spec.rb +91 -0
- metadata +18 -16
- data/spec/codecs/json_lines_spec.rb +0 -237
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b844cfe3444a066af5ab9b7c0da943da2822cdd490c4b5c9bee8c2889c95cb3c
|
4
|
+
data.tar.gz: a40e7766d69b01e601fdf4231b013c65c1db10e8e824b1ab2ff9fafa25dab5b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd984ba16e049cfedd692ad99f76462acc2ff493b359a8e3a09b8530af0cb1fcec49ef00d2823a7b5fe2221a37536b237275b89514a2fcc3da64173c47ba7636
|
7
|
+
data.tar.gz: 75252622493230be43d863a66e99a7e3fbb1f219d0f1bf8571c4f6686fe780825b1b5eaa497de6b45516a04bf143b928c3f1168fed623f2dce272d7bbf9e3fc3
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Logstash Plugin
|
2
2
|
|
3
|
-
[![Travis Build Status](https://travis-ci.org/
|
3
|
+
[![Travis Build Status](https://travis-ci.org/cherweg/logstash-codec-json_stream.svg?branch=master)](https://travis-ci.org/cherweg/logstash-codec-json_stream)
|
4
4
|
|
5
5
|
This is a plugin for [Logstash](https://github.com/elastic/logstash).
|
6
6
|
|
@@ -1,20 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/codecs/base"
|
3
3
|
require "logstash/util/charset"
|
4
|
-
require "logstash/util/buftok"
|
5
4
|
require "logstash/json"
|
6
5
|
|
6
|
+
|
7
7
|
# This codec will decode streamed JSON that is not delimited.
|
8
8
|
# Encoding will emit a single JSON string ending in a `@delimiter`
|
9
9
|
|
10
10
|
class LogStash::Codecs::JSONStream < LogStash::Codecs::Base
|
11
|
+
|
11
12
|
config_name "json_stream"
|
12
13
|
|
13
14
|
config :charset, :validate => ::Encoding.name_list, :default => "UTF-8"
|
14
15
|
|
15
|
-
# Change the delimiter that separates lines
|
16
|
-
config :delimiter, :validate => :string, :default => "\n"
|
17
|
-
|
18
16
|
public
|
19
17
|
|
20
18
|
def register
|
@@ -22,33 +20,25 @@ class LogStash::Codecs::JSONStream < LogStash::Codecs::Base
|
|
22
20
|
@converter.logger = @logger
|
23
21
|
end
|
24
22
|
|
25
|
-
def decode(
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
acc.tap do |result|
|
43
|
-
result[:counter] += 1 if char == '{'
|
44
|
-
end
|
45
|
-
end
|
23
|
+
def decode(concatenated_json, &block)
|
24
|
+
decode_unsafe(concatenated_json, &block)
|
25
|
+
rescue LogStash::Json::ParserError => e
|
26
|
+
@logger.error("JSON parse error for json stream / concatenated json, original data now in message field", :error => e, :data => concatenated_json)
|
27
|
+
yield LogStash::Event.new("message" => concatenated_json, "tags" => ["_jsonparsefailure"])
|
28
|
+
rescue StandardError => e
|
29
|
+
# This should NEVER happen. But hubris has been the cause of many pipeline breaking things
|
30
|
+
# If something bad should happen we just don't want to crash logstash here.
|
31
|
+
@logger.error(
|
32
|
+
"An unexpected error occurred parsing JSON data",
|
33
|
+
:data => concatenated_json,
|
34
|
+
:message => e.message,
|
35
|
+
:class => e.class.name,
|
36
|
+
:backtrace => e.backtrace
|
37
|
+
)
|
46
38
|
end
|
47
39
|
|
48
40
|
def encode(event)
|
49
|
-
|
50
|
-
# outputs emitted one per line, and whitespace is OK in json.
|
51
|
-
@on_event.call(event, "#{event.to_json}#{@delimiter}")
|
41
|
+
@logger.error("Encoding is not supported by 'concatenated_json' plugin yet")
|
52
42
|
end
|
53
43
|
|
54
44
|
def flush(&block)
|
@@ -56,26 +46,10 @@ class LogStash::Codecs::JSONStream < LogStash::Codecs::Base
|
|
56
46
|
end
|
57
47
|
|
58
48
|
private
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
@logger.warn("JSON parse error, original data now in message field", :error => e, :data => json)
|
65
|
-
yield LogStash::Event.new("message" => json, "tags" => ["_jsonparsefailure"])
|
66
|
-
end
|
67
|
-
|
68
|
-
# legacy_parse uses the LogStash::Json class to deserialize json
|
69
|
-
def legacy_parse(json, &block)
|
70
|
-
# ignore empty/blank lines which LogStash::Json#load returns as nil
|
71
|
-
o = LogStash::Json.load(json)
|
72
|
-
yield(LogStash::Event.new(o)) if o
|
73
|
-
rescue LogStash::Json::ParserError => e
|
74
|
-
@logger.warn("JSON parse error, original data now in message field", :error => e, :data => json)
|
75
|
-
yield LogStash::Event.new("message" => json, "tags" => ["_jsonparsefailure"])
|
49
|
+
def decode_unsafe(concatenated_json)
|
50
|
+
array_json = @converter.convert("[#{concatenated_json.gsub('}{', '},{')}]")
|
51
|
+
LogStash::Json.load(array_json).each do |decoded_event|
|
52
|
+
yield(LogStash::Event.new(decoded_event))
|
53
|
+
end
|
76
54
|
end
|
77
|
-
|
78
|
-
# keep compatibility with all v2.x distributions. only in 2.3 will the Event#from_json method be introduced
|
79
|
-
# and we need to keep compatibility for all v2 releases.
|
80
|
-
alias_method :parse, LogStash::Event.respond_to?(:from_json) ? :from_json_parse : :legacy_parse
|
81
55
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-codec-json_stream'
|
4
|
-
s.version = '0.0
|
4
|
+
s.version = '1.0.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Reads and writes non JSON Streams"
|
7
7
|
s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/devutils/rspec/spec_helper"
|
3
|
+
require "logstash/codecs/json_stream"
|
4
|
+
require "logstash/event"
|
5
|
+
require "logstash/json"
|
6
|
+
require "insist"
|
7
|
+
|
8
|
+
describe LogStash::Codecs::JSONStream do
|
9
|
+
|
10
|
+
class LogStash::Codecs::JSONStream
|
11
|
+
public :decode_unsafe # use method without error logging for better visibility of errors
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:codec_options) { {} }
|
15
|
+
|
16
|
+
context "default parser choice" do
|
17
|
+
subject do
|
18
|
+
LogStash::Codecs::JSONStream.new(codec_options)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should read multiple events" do
|
22
|
+
events = events_from_string(<<-EOS
|
23
|
+
{"messageType": "CONTROL_MESSAGE", "message": "foo"}
|
24
|
+
{"messageType": "DATA_MESSAGE", "logGroup": "testing", "logEvents": [
|
25
|
+
{"id": "4711", "@timestamp": "2018-06-18T13:36:25.484+00:00", "message": "{\\"tasks\\": \\"READING\\"}"},
|
26
|
+
{"id": "1848", "@timestamp": "1989-11-09T23:59:25.484+02:00", "message": "{\\"tasks\\": \\"WRITING\\"}"}
|
27
|
+
]}
|
28
|
+
EOS
|
29
|
+
)
|
30
|
+
insist { events.size } == 2
|
31
|
+
|
32
|
+
control_event = events[0]
|
33
|
+
data_event = events[1]
|
34
|
+
|
35
|
+
insist { control_event.is_a? LogStash::Event }
|
36
|
+
insist { control_event.get("messageType") } == "CONTROL_MESSAGE"
|
37
|
+
insist { control_event.get("message") } == "foo"
|
38
|
+
|
39
|
+
insist { data_event.is_a? LogStash::Event }
|
40
|
+
insist { data_event.get("messageType") } == "DATA_MESSAGE"
|
41
|
+
insist { data_event.get("logGroup") } == "testing"
|
42
|
+
insist { data_event.get("logEvents").size } == 2
|
43
|
+
|
44
|
+
insist { data_event.get("logEvents")[0]['id'] } == '4711'
|
45
|
+
insist { data_event.get("logEvents")[0]['@timestamp'] } == '2018-06-18T13:36:25.484+00:00'
|
46
|
+
insist { data_event.get("logEvents")[0]['message'] } == '{"tasks": "READING"}'
|
47
|
+
|
48
|
+
insist { data_event.get("logEvents")[1]['id'] } == '1848'
|
49
|
+
insist { data_event.get("logEvents")[1]['@timestamp'] } == '1989-11-09T23:59:25.484+02:00'
|
50
|
+
insist { data_event.get("logEvents")[1]['message'] } == '{"tasks": "WRITING"}'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should read multiple events from data" do
|
54
|
+
events = events_from_file('log-stream.valid-line-formatted')
|
55
|
+
insist { events.size } == 5
|
56
|
+
|
57
|
+
events.each do |event|
|
58
|
+
insist { event.is_a? LogStash::Event }
|
59
|
+
insist { event.get("logGroup") } == "test-core"
|
60
|
+
insist { event.get("messageType") } == "DATA_MESSAGE"
|
61
|
+
insist { event.get("logEvents").size } != 0
|
62
|
+
event.get("logEvents").each do |event|
|
63
|
+
insist { event["id"] } != nil
|
64
|
+
insist { event["message"] } != nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should not fail with stacktrace" do
|
70
|
+
events = events_from_file('log-stream.minimal-failure-formatted')
|
71
|
+
insist { events.size } == 1
|
72
|
+
|
73
|
+
insist { events[0].is_a? LogStash::Event }
|
74
|
+
insist { events[0].get("logEvents").size } == 1
|
75
|
+
insist { events[0].get("logEvents")[0]['message'] =~ /Failed at: $\{springMacroRequestContext.getMessag\.\.\./ }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
def events_from_file fixture_logfile_name
|
81
|
+
data = IO.read(File.join(File.dirname(__FILE__), "../../fixtures/#{fixture_logfile_name}"))
|
82
|
+
events_from_string data
|
83
|
+
end
|
84
|
+
|
85
|
+
def events_from_string data
|
86
|
+
events = []
|
87
|
+
data_without_formatting = data.gsub(/(\n|\s{2,})/, '')
|
88
|
+
subject.decode_unsafe(data_without_formatting) { |event| events << event }
|
89
|
+
events
|
90
|
+
end
|
91
|
+
end
|
metadata
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-codec-json_stream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Herweg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
|
-
- -
|
16
|
+
- - ">="
|
17
17
|
- !ruby/object:Gem::Version
|
18
18
|
version: '1.60'
|
19
|
-
- - <=
|
19
|
+
- - "<="
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: '2.99'
|
22
22
|
name: logstash-core-plugin-api
|
@@ -24,16 +24,16 @@ dependencies:
|
|
24
24
|
type: :runtime
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '1.60'
|
30
|
-
- - <=
|
30
|
+
- - "<="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2.99'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
35
35
|
requirements:
|
36
|
-
- -
|
36
|
+
- - ">="
|
37
37
|
- !ruby/object:Gem::Version
|
38
38
|
version: 2.1.0
|
39
39
|
name: logstash-codec-line
|
@@ -41,13 +41,13 @@ dependencies:
|
|
41
41
|
type: :runtime
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- -
|
44
|
+
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 2.1.0
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
requirements:
|
50
|
-
- -
|
50
|
+
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '0'
|
53
53
|
name: logstash-devutils
|
@@ -55,10 +55,12 @@ dependencies:
|
|
55
55
|
type: :development
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- -
|
58
|
+
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0'
|
61
|
-
description: This gem is a Logstash plugin required to be installed on top of the
|
61
|
+
description: This gem is a Logstash plugin required to be installed on top of the
|
62
|
+
Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
|
63
|
+
gem is not a stand-alone program
|
62
64
|
email: christian.herweg@gmail.com
|
63
65
|
executables: []
|
64
66
|
extensions: []
|
@@ -73,7 +75,7 @@ files:
|
|
73
75
|
- docs/index.asciidoc
|
74
76
|
- lib/logstash/codecs/json_stream.rb
|
75
77
|
- logstash-codec-json_stream.gemspec
|
76
|
-
- spec/codecs/
|
78
|
+
- spec/codecs/json_stream_spec.rb
|
77
79
|
homepage: https://github.com/cherweg/logstash-codec-json_stream
|
78
80
|
licenses:
|
79
81
|
- Apache License (2.0)
|
@@ -86,19 +88,19 @@ require_paths:
|
|
86
88
|
- lib
|
87
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
88
90
|
requirements:
|
89
|
-
- -
|
91
|
+
- - ">="
|
90
92
|
- !ruby/object:Gem::Version
|
91
93
|
version: '0'
|
92
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
95
|
requirements:
|
94
|
-
- -
|
96
|
+
- - ">="
|
95
97
|
- !ruby/object:Gem::Version
|
96
98
|
version: '0'
|
97
99
|
requirements: []
|
98
100
|
rubyforge_project:
|
99
|
-
rubygems_version: 2.
|
101
|
+
rubygems_version: 2.6.13
|
100
102
|
signing_key:
|
101
103
|
specification_version: 4
|
102
104
|
summary: Reads and writes non JSON Streams
|
103
105
|
test_files:
|
104
|
-
- spec/codecs/
|
106
|
+
- spec/codecs/json_stream_spec.rb
|
@@ -1,237 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require "logstash/devutils/rspec/spec_helper"
|
3
|
-
require "logstash/codecs/json_lines"
|
4
|
-
require "logstash/event"
|
5
|
-
require "logstash/json"
|
6
|
-
require "insist"
|
7
|
-
|
8
|
-
describe LogStash::Codecs::JSONLines do
|
9
|
-
|
10
|
-
let(:codec_options) { {} }
|
11
|
-
|
12
|
-
shared_examples :codec do
|
13
|
-
|
14
|
-
context "#decode" do
|
15
|
-
it "should return an event from json data" do
|
16
|
-
data = {"foo" => "bar", "baz" => {"bah" => ["a","b","c"]}}
|
17
|
-
subject.decode(LogStash::Json.dump(data) + "\n") do |event|
|
18
|
-
insist { event.is_a? LogStash::Event }
|
19
|
-
insist { event.get("foo") } == data["foo"]
|
20
|
-
insist { event.get("baz") } == data["baz"]
|
21
|
-
insist { event.get("bah") } == data["bah"]
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should return an event from json data when a newline is recieved" do
|
26
|
-
data = {"foo" => "bar", "baz" => {"bah" => ["a","b","c"]}}
|
27
|
-
subject.decode(LogStash::Json.dump(data)) do |event|
|
28
|
-
insist {false}
|
29
|
-
end
|
30
|
-
subject.decode("\n") do |event|
|
31
|
-
insist { event.is_a? LogStash::Event }
|
32
|
-
insist { event.get("foo") } == data["foo"]
|
33
|
-
insist { event.get("baz") } == data["baz"]
|
34
|
-
insist { event.get("bah") } == data["bah"]
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context "when using custom delimiter" do
|
39
|
-
let(:delimiter) { "|" }
|
40
|
-
let(:line) { "{\"hey\":1}|{\"hey\":2}|{\"hey\":3}|" }
|
41
|
-
let(:codec_options) { { "delimiter" => delimiter } }
|
42
|
-
|
43
|
-
it "should decode multiple lines separated by the delimiter" do
|
44
|
-
result = []
|
45
|
-
subject.decode(line) { |event| result << event }
|
46
|
-
expect(result.size).to eq(3)
|
47
|
-
expect(result[0].get("hey")).to eq(1)
|
48
|
-
expect(result[1].get("hey")).to eq(2)
|
49
|
-
expect(result[2].get("hey")).to eq(3)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
context "processing plain text" do
|
54
|
-
it "falls back to plain text" do
|
55
|
-
decoded = false
|
56
|
-
subject.decode("something that isn't json\n") do |event|
|
57
|
-
decoded = true
|
58
|
-
insist { event.is_a?(LogStash::Event) }
|
59
|
-
insist { event.get("message") } == "something that isn't json"
|
60
|
-
insist { event.get("tags") }.include?("_jsonparsefailure")
|
61
|
-
end
|
62
|
-
insist { decoded } == true
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context "processing weird binary blobs" do
|
67
|
-
it "falls back to plain text and doesn't crash (LOGSTASH-1595)" do
|
68
|
-
decoded = false
|
69
|
-
blob = (128..255).to_a.pack("C*").force_encoding("ASCII-8BIT")
|
70
|
-
subject.decode(blob)
|
71
|
-
subject.decode("\n") do |event|
|
72
|
-
decoded = true
|
73
|
-
insist { event.is_a?(LogStash::Event) }
|
74
|
-
insist { event.get("message").encoding.to_s } == "UTF-8"
|
75
|
-
end
|
76
|
-
insist { decoded } == true
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
context "when json could not be parsed" do
|
81
|
-
let(:message) { "random_message\n" }
|
82
|
-
|
83
|
-
it "add the failure tag" do
|
84
|
-
subject.decode(message) do |event|
|
85
|
-
expect(event).to include "tags"
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
it "uses an array to store the tags" do
|
90
|
-
subject.decode(message) do |event|
|
91
|
-
expect(event.get('tags')).to be_a Array
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
it "add a json parser failure tag" do
|
96
|
-
subject.decode(message) do |event|
|
97
|
-
expect(event.get('tags')).to include "_jsonparsefailure"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
context "blank lines" do
|
103
|
-
let(:collector) { Array.new }
|
104
|
-
|
105
|
-
it "should ignore bare blanks" do
|
106
|
-
subject.decode("\n\n") do |event|
|
107
|
-
collector.push(event)
|
108
|
-
end
|
109
|
-
expect(collector.size).to eq(0)
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should ignore in between blank lines" do
|
113
|
-
subject.decode("\n{\"a\":1}\n\n{\"b\":2}\n\n") do |event|
|
114
|
-
collector.push(event)
|
115
|
-
end
|
116
|
-
expect(collector.size).to eq(2)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
context "#encode" do
|
123
|
-
let(:data) { { LogStash::Event::TIMESTAMP => "2015-12-07T11:37:00.000Z", "foo" => "bar", "baz" => {"bah" => ["a","b","c"]}} }
|
124
|
-
let(:event) { LogStash::Event.new(data) }
|
125
|
-
|
126
|
-
it "should return json data" do
|
127
|
-
got_event = false
|
128
|
-
subject.on_event do |e, d|
|
129
|
-
insist { d } == "#{LogStash::Event.new(data).to_json}\n"
|
130
|
-
insist { LogStash::Json.load(d)["foo"] } == data["foo"]
|
131
|
-
insist { LogStash::Json.load(d)["baz"] } == data["baz"]
|
132
|
-
insist { LogStash::Json.load(d)["bah"] } == data["bah"]
|
133
|
-
got_event = true
|
134
|
-
end
|
135
|
-
subject.encode(event)
|
136
|
-
insist { got_event }
|
137
|
-
end
|
138
|
-
|
139
|
-
context "when using custom delimiter" do
|
140
|
-
let(:delimiter) { "|" }
|
141
|
-
let(:codec_options) { { "delimiter" => delimiter } }
|
142
|
-
|
143
|
-
it "should decode multiple lines separated by the delimiter" do
|
144
|
-
subject.on_event do |e, d|
|
145
|
-
insist { d } == "#{LogStash::Event.new(data).to_json}#{delimiter}"
|
146
|
-
end
|
147
|
-
subject.encode(event)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
context 'reading from a simulated multiline json file without last newline' do
|
153
|
-
let(:input) do
|
154
|
-
%{{"field": "value1"}
|
155
|
-
{"field": "value2"}}
|
156
|
-
end
|
157
|
-
|
158
|
-
let(:collector) { Array.new }
|
159
|
-
|
160
|
-
it 'should generate one event' do
|
161
|
-
subject.decode(input) do |event|
|
162
|
-
collector.push(event)
|
163
|
-
end
|
164
|
-
expect(collector.size).to eq(1)
|
165
|
-
expect(collector.first.get('field')).to eq('value1')
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
context 'reading from a simulated multiline json file with last newline' do
|
170
|
-
let(:input) do
|
171
|
-
%{{"field": "value1"}
|
172
|
-
{"field": "value2"}
|
173
|
-
}
|
174
|
-
end
|
175
|
-
|
176
|
-
let(:collector) { Array.new }
|
177
|
-
|
178
|
-
it 'should generate two events' do
|
179
|
-
subject.decode(input) do |event|
|
180
|
-
collector.push(event)
|
181
|
-
end
|
182
|
-
expect(collector.size).to eq(2)
|
183
|
-
expect(collector.first.get('field')).to eq('value1')
|
184
|
-
expect(collector.last.get('field')).to eq('value2')
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
end
|
189
|
-
|
190
|
-
context "forcing legacy parsing" do
|
191
|
-
it_behaves_like :codec do
|
192
|
-
subject do
|
193
|
-
# register method is called in the constructor
|
194
|
-
LogStash::Codecs::JSONLines.new(codec_options)
|
195
|
-
end
|
196
|
-
|
197
|
-
before(:each) do
|
198
|
-
# stub codec parse method to force use of the legacy parser.
|
199
|
-
# this is very implementation specific but I am not sure how
|
200
|
-
# this can be tested otherwise.
|
201
|
-
allow(subject).to receive(:parse) do |line, &block|
|
202
|
-
subject.send(:legacy_parse, line, &block)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
context "default parser choice" do
|
209
|
-
# here we cannot force the use of the Event#from_json since if this test is run in the
|
210
|
-
# legacy context (no Java Event) it will fail but if in the new context, it will be picked up.
|
211
|
-
it_behaves_like :codec do
|
212
|
-
subject do
|
213
|
-
# register method is called in the constructor
|
214
|
-
LogStash::Codecs::JSONLines.new(codec_options)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
context "flush" do
|
219
|
-
subject do
|
220
|
-
LogStash::Codecs::JSONLines.new(codec_options)
|
221
|
-
end
|
222
|
-
|
223
|
-
let(:input) { "{\"foo\":\"bar\"}" }
|
224
|
-
|
225
|
-
it "should flush buffered data'" do
|
226
|
-
result = []
|
227
|
-
subject.decode(input) { |e| result << e }
|
228
|
-
expect(result.size).to eq(0)
|
229
|
-
|
230
|
-
subject.flush { |e| result << e }
|
231
|
-
expect(result.size).to eq(1)
|
232
|
-
|
233
|
-
expect(result[0].get("foo")).to eq("bar")
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|