logstash-input-beats 2.0.0 → 2.0.1
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 +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/logstash/inputs/beats.rb +23 -10
- data/logstash-input-beats.gemspec +3 -2
- data/spec/inputs/beats_spec.rb +93 -10
- metadata +36 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41c0bf7e7993d390543fd95c3c16ee3847d03862
|
4
|
+
data.tar.gz: d91cf9c2a4931d1290825e3a13bfc73d2ac8b2a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82d7afdf4d5067032c6ea26eff33c32e7ddac9cad88d432bbb275b6a9813aaf274a124a78d23fad5f91f40858591ffa211c921a2b71b8b848924c90a35614a94
|
7
|
+
data.tar.gz: 050af93c89cef0649ce6761ee21118c1f69335e63a506009c44232460986b75d8bfb96e7441d1baa5a3e2bf2517a9f53a4f59f98fef91fd27863604933650baa
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# 2.0.1
|
2
|
+
- Copy the `beat.hostname` field into the `host` field for better compatibility with the other Logstash plugins #28
|
3
|
+
- Correctly merge multiple line with the multiline codec ref: #24
|
1
4
|
# 2.0.0
|
2
5
|
- Add support for stream identity, the ID will be generated from beat.id+resource_id or beat.name + beat.source if not present #22 #13
|
3
6
|
The identity allow the multiline codec to correctly merge string from multiples files.
|
@@ -92,7 +92,8 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def run(output_queue)
|
95
|
-
|
95
|
+
@output_queue = output_queue
|
96
|
+
start_buffer_broker
|
96
97
|
|
97
98
|
while !stop? do
|
98
99
|
# Wrapping the accept call into a CircuitBreaker
|
@@ -123,29 +124,42 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
|
|
123
124
|
|
124
125
|
public
|
125
126
|
def stop
|
126
|
-
|
127
|
+
# we may have some stuff in the buffer
|
128
|
+
@codec.flush { |event| @output_queue << event }
|
129
|
+
@lumberjack.close rescue nil
|
127
130
|
end
|
128
131
|
|
129
132
|
public
|
130
|
-
def create_event(map, identity_stream)
|
133
|
+
def create_event(map, identity_stream, &block)
|
131
134
|
# Filebeats uses the `message` key and LSF `line`
|
132
135
|
target_field = target_field_for_codec ? map.delete(target_field_for_codec) : nil
|
133
136
|
|
134
137
|
if target_field.nil?
|
135
138
|
event = LogStash::Event.new(map)
|
139
|
+
copy_beat_hostname(event)
|
136
140
|
decorate(event)
|
137
|
-
|
141
|
+
block.call(event)
|
138
142
|
else
|
139
143
|
# All codecs expects to work on string
|
140
144
|
@codec.decode(target_field.to_s, identity_stream) do |decoded|
|
141
145
|
ts = coerce_ts(map.delete("@timestamp"))
|
142
146
|
decoded["@timestamp"] = ts unless ts.nil?
|
143
147
|
map.each { |k, v| decoded[k] = v }
|
148
|
+
copy_beat_hostname(decoded)
|
144
149
|
decorate(decoded)
|
145
|
-
|
150
|
+
block.call(decoded)
|
146
151
|
end
|
147
152
|
end
|
148
|
-
|
153
|
+
end
|
154
|
+
|
155
|
+
# Copies the beat.hostname field into the host field unless
|
156
|
+
# the host field is already defined
|
157
|
+
private
|
158
|
+
def copy_beat_hostname(event)
|
159
|
+
host = event["beat"] ? event["beat"]["hostname"] : nil
|
160
|
+
if host && event["host"].nil?
|
161
|
+
event["host"] = host
|
162
|
+
end
|
149
163
|
end
|
150
164
|
|
151
165
|
private
|
@@ -168,8 +182,7 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
|
|
168
182
|
# If any errors occur in from the events the connection should be closed in the
|
169
183
|
# library ensure block and the exception will be handled here
|
170
184
|
connection.run do |map, identity_stream|
|
171
|
-
|
172
|
-
block.call(event) unless event.nil?
|
185
|
+
create_event(map, identity_stream, &block)
|
173
186
|
end
|
174
187
|
|
175
188
|
# When too many errors happen inside the circuit breaker it will throw
|
@@ -192,10 +205,10 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
|
|
192
205
|
#
|
193
206
|
# We are using a proxy queue supporting blocking with a timeout and
|
194
207
|
# this thread take the element from one queue into another one.
|
195
|
-
def start_buffer_broker
|
208
|
+
def start_buffer_broker
|
196
209
|
@threadpool.post do
|
197
210
|
while !stop?
|
198
|
-
output_queue << @buffered_queue.pop_no_timeout
|
211
|
+
@output_queue << @buffered_queue.pop_no_timeout
|
199
212
|
end
|
200
213
|
end
|
201
214
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "logstash-input-beats"
|
3
|
-
s.version = "2.0.
|
3
|
+
s.version = "2.0.1"
|
4
4
|
s.licenses = ["Apache License (2.0)"]
|
5
5
|
s.summary = "Receive events using the lumberjack protocol."
|
6
6
|
s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_runtime_dependency "logstash-core", ">= 2.0.0", "< 3.0.0"
|
23
23
|
|
24
24
|
s.add_runtime_dependency "logstash-codec-plain"
|
25
|
-
s.add_runtime_dependency "concurrent-ruby", "0.9.
|
25
|
+
s.add_runtime_dependency "concurrent-ruby", "~> 0.9.2"
|
26
26
|
s.add_runtime_dependency "logstash-codec-multiline", "~> 2.0.3"
|
27
27
|
|
28
28
|
s.add_development_dependency "flores", "~>0.0.6"
|
@@ -31,5 +31,6 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.add_development_dependency "pry"
|
32
32
|
s.add_development_dependency "rspec-wait"
|
33
33
|
s.add_development_dependency "logstash-devutils", "~> 0.0.18"
|
34
|
+
s.add_development_dependency "logstash-codec-json"
|
34
35
|
end
|
35
36
|
|
data/spec/inputs/beats_spec.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative "../spec_helper"
|
|
3
3
|
require "stud/temporary"
|
4
4
|
require "logstash/inputs/beats"
|
5
5
|
require "logstash/codecs/plain"
|
6
|
+
require "logstash/codecs/json"
|
6
7
|
require "logstash/codecs/multiline"
|
7
8
|
require "logstash/event"
|
8
9
|
require "lumberjack/beats/client"
|
@@ -90,10 +91,11 @@ describe LogStash::Inputs::Beats do
|
|
90
91
|
|
91
92
|
context "without a `target_field` defined" do
|
92
93
|
it "decorates the event" do
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
beats.create_event(event_map, identity_stream) do |event|
|
95
|
+
expect(event["foo"]).to eq("bar")
|
96
|
+
expect(event["[@metadata][hidden]"]).to eq("secret")
|
97
|
+
expect(event["tags"]).to include("bonjour")
|
98
|
+
end
|
97
99
|
end
|
98
100
|
end
|
99
101
|
|
@@ -101,10 +103,11 @@ describe LogStash::Inputs::Beats do
|
|
101
103
|
let(:event_map) { super.merge({"message" => "with a field"}) }
|
102
104
|
|
103
105
|
it "decorates the event" do
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
106
|
+
beats.create_event(event_map, identity_stream) do |event|
|
107
|
+
expect(event["foo"]).to eq("bar")
|
108
|
+
expect(event["[@metadata][hidden]"]).to eq("secret")
|
109
|
+
expect(event["tags"]).to include("bonjour")
|
110
|
+
end
|
108
111
|
end
|
109
112
|
end
|
110
113
|
|
@@ -112,9 +115,89 @@ describe LogStash::Inputs::Beats do
|
|
112
115
|
let(:codec) { LogStash::Codecs::Multiline.new("pattern" => '^\s', "what" => "previous") }
|
113
116
|
let(:event_map) { {"message" => "hello?", "tags" => ["syslog"]} }
|
114
117
|
|
115
|
-
it "
|
118
|
+
it "returns nil" do
|
119
|
+
expect { |b| beats.create_event(event_map, identity_stream, &b) }.not_to yield_control
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "multiline" do
|
124
|
+
let(:codec) { LogStash::Codecs::Multiline.new("pattern" => '^2015', "what" => "previous", "negate" => true) }
|
125
|
+
let(:events_map) do
|
126
|
+
[
|
127
|
+
{ "beat" => { "id" => "main", "resource_id" => "md5"}, "message" => "2015-11-10 10:14:38,907 line 1" },
|
128
|
+
{ "beat" => { "id" => "main", "resource_id" => "md5"}, "message" => "line 1.1" },
|
129
|
+
{ "beat" => { "id" => "main", "resource_id" => "md5"}, "message" => "2015-11-10 10:16:38,907 line 2" },
|
130
|
+
{ "beat" => { "id" => "main", "resource_id" => "md5"}, "message" => "line 2.1" },
|
131
|
+
{ "beat" => { "id" => "main", "resource_id" => "md5"}, "message" => "line 2.2" },
|
132
|
+
{ "beat" => { "id" => "main", "resource_id" => "md5"}, "message" => "line 2.3" },
|
133
|
+
{ "beat" => { "id" => "main", "resource_id" => "md5"}, "message" => "2015-11-10 10:18:38,907 line 3" }
|
134
|
+
]
|
135
|
+
end
|
136
|
+
|
137
|
+
let(:queue) { [] }
|
138
|
+
before do
|
139
|
+
Thread.new { beats.run(queue) }
|
140
|
+
sleep(0.1)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should correctly merge multiple events" do
|
144
|
+
events_map.each { |map| beats.create_event(map, identity_stream) { |e| queue << e } }
|
145
|
+
# This cannot currently work without explicitely call a flush
|
146
|
+
# the flush is never timebased, if no new data is coming in we wont flush the buffer
|
147
|
+
# https://github.com/logstash-plugins/logstash-codec-multiline/issues/11
|
148
|
+
beats.stop
|
149
|
+
expect(queue.size).to eq(3)
|
150
|
+
|
151
|
+
expect(queue.collect { |e| e["message"] }).to include("2015-11-10 10:14:38,907 line 1\nline 1.1",
|
152
|
+
"2015-11-10 10:16:38,907 line 2\nline 2.1\nline 2.2\nline 2.3",
|
153
|
+
"2015-11-10 10:18:38,907 line 3")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context "with a beat.hostname field" do
|
158
|
+
let(:event_map) { {"message" => "hello", "beat" => {"hostname" => "linux01"} } }
|
159
|
+
|
160
|
+
it "copies it to the host field" do
|
161
|
+
event = beats.create_event(event_map, identity_stream)
|
162
|
+
expect(event["host"]).to eq("linux01")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "with a beat.hostname field but without the message" do
|
167
|
+
let(:event_map) { {"beat" => {"hostname" => "linux01"} } }
|
168
|
+
|
169
|
+
it "copies it to the host field" do
|
170
|
+
event = beats.create_event(event_map, identity_stream)
|
171
|
+
expect(event["host"]).to eq("linux01")
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context "without a beat.hostname field" do
|
176
|
+
let(:event_map) { {"message" => "hello", "beat" => {"name" => "linux01"} } }
|
177
|
+
|
178
|
+
it "should not add a host field" do
|
179
|
+
event = beats.create_event(event_map, identity_stream)
|
180
|
+
expect(event["beat"]["name"]).to eq("linux01")
|
181
|
+
expect(event["host"]).to be_nil
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "with a beat.hostname and host fields" do
|
186
|
+
let(:event_map) { {"message" => "hello", "host" => "linux02", "beat" => {"hostname" => "linux01"} } }
|
187
|
+
|
188
|
+
it "should not overwrite host" do
|
189
|
+
event = beats.create_event(event_map, identity_stream)
|
190
|
+
expect(event["host"]).to eq("linux02")
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context "with a host field in the message" do
|
195
|
+
let(:codec) { LogStash::Codecs::JSON.new }
|
196
|
+
let(:event_map) { {"message" => '{"host": "linux02"}', "beat" => {"hostname" => "linux01"} } }
|
197
|
+
|
198
|
+
it "should take the host from the JSON message" do
|
116
199
|
event = beats.create_event(event_map, identity_stream)
|
117
|
-
expect(event).to
|
200
|
+
expect(event["host"]).to eq("linux02")
|
118
201
|
end
|
119
202
|
end
|
120
203
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-beats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logstash-core
|
@@ -48,14 +48,14 @@ dependencies:
|
|
48
48
|
name: concurrent-ruby
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0.9.
|
53
|
+
version: 0.9.2
|
54
54
|
requirement: !ruby/object:Gem::Requirement
|
55
55
|
requirements:
|
56
|
-
- -
|
56
|
+
- - ~>
|
57
57
|
- !ruby/object:Gem::Version
|
58
|
-
version: 0.9.
|
58
|
+
version: 0.9.2
|
59
59
|
prerelease: false
|
60
60
|
type: :runtime
|
61
61
|
- !ruby/object:Gem::Dependency
|
@@ -156,37 +156,51 @@ dependencies:
|
|
156
156
|
version: 0.0.18
|
157
157
|
prerelease: false
|
158
158
|
type: :development
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: logstash-codec-json
|
161
|
+
version_requirements: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
requirement: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - '>='
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
prerelease: false
|
172
|
+
type: :development
|
159
173
|
description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
|
160
174
|
email: info@elastic.co
|
161
175
|
executables: []
|
162
176
|
extensions: []
|
163
177
|
extra_rdoc_files: []
|
164
178
|
files:
|
179
|
+
- CHANGELOG.md
|
180
|
+
- CONTRIBUTORS
|
181
|
+
- Gemfile
|
182
|
+
- LICENSE
|
183
|
+
- NOTICE.TXT
|
184
|
+
- PROTOCOL.md
|
185
|
+
- README.md
|
165
186
|
- lib/logstash/circuit_breaker.rb
|
166
|
-
- lib/logstash/sized_queue_timeout.rb
|
167
187
|
- lib/logstash/inputs/beats.rb
|
188
|
+
- lib/logstash/sized_queue_timeout.rb
|
168
189
|
- lib/lumberjack/beats.rb
|
169
190
|
- lib/lumberjack/beats/client.rb
|
170
191
|
- lib/lumberjack/beats/server.rb
|
171
|
-
-
|
172
|
-
- spec/integration_spec.rb
|
192
|
+
- logstash-input-beats.gemspec
|
173
193
|
- spec/inputs/beats_spec.rb
|
194
|
+
- spec/integration_spec.rb
|
174
195
|
- spec/logstash/circuit_breaker_spec.rb
|
175
196
|
- spec/logstash/size_queue_timeout_spec.rb
|
176
197
|
- spec/lumberjack/beats/acking_protocol_v1_spec.rb
|
177
198
|
- spec/lumberjack/beats/acking_protocol_v2_spec.rb
|
178
199
|
- spec/lumberjack/beats/client_spec.rb
|
179
|
-
- spec/lumberjack/beats/server_spec.rb
|
180
200
|
- spec/lumberjack/beats/connection_spec.rb
|
201
|
+
- spec/lumberjack/beats/server_spec.rb
|
202
|
+
- spec/spec_helper.rb
|
181
203
|
- spec/support/logstash_test.rb
|
182
|
-
- logstash-input-beats.gemspec
|
183
|
-
- PROTOCOL.md
|
184
|
-
- README.md
|
185
|
-
- CHANGELOG.md
|
186
|
-
- CONTRIBUTORS
|
187
|
-
- Gemfile
|
188
|
-
- LICENSE
|
189
|
-
- NOTICE.TXT
|
190
204
|
homepage: http://www.elastic.co/guide/en/logstash/current/index.html
|
191
205
|
licenses:
|
192
206
|
- Apache License (2.0)
|
@@ -209,19 +223,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
223
|
version: '0'
|
210
224
|
requirements: []
|
211
225
|
rubyforge_project:
|
212
|
-
rubygems_version: 2.
|
226
|
+
rubygems_version: 2.4.8
|
213
227
|
signing_key:
|
214
228
|
specification_version: 4
|
215
229
|
summary: Receive events using the lumberjack protocol.
|
216
230
|
test_files:
|
217
|
-
- spec/spec_helper.rb
|
218
|
-
- spec/integration_spec.rb
|
219
231
|
- spec/inputs/beats_spec.rb
|
232
|
+
- spec/integration_spec.rb
|
220
233
|
- spec/logstash/circuit_breaker_spec.rb
|
221
234
|
- spec/logstash/size_queue_timeout_spec.rb
|
222
235
|
- spec/lumberjack/beats/acking_protocol_v1_spec.rb
|
223
236
|
- spec/lumberjack/beats/acking_protocol_v2_spec.rb
|
224
237
|
- spec/lumberjack/beats/client_spec.rb
|
225
|
-
- spec/lumberjack/beats/server_spec.rb
|
226
238
|
- spec/lumberjack/beats/connection_spec.rb
|
239
|
+
- spec/lumberjack/beats/server_spec.rb
|
240
|
+
- spec/spec_helper.rb
|
227
241
|
- spec/support/logstash_test.rb
|