logstash-codec-json_stream 0.0.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
[](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
|