logstash-input-beats 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: df4aadb42d40ce79081da88eb7519460e82cd37f
4
- data.tar.gz: 5239753151ef027acb05146920ba553c0101ce21
3
+ metadata.gz: 41c0bf7e7993d390543fd95c3c16ee3847d03862
4
+ data.tar.gz: d91cf9c2a4931d1290825e3a13bfc73d2ac8b2a3
5
5
  SHA512:
6
- metadata.gz: 350918e94dc2ba03d0b9c57abab07902fb8b7ca45354213932db23f0c7477b91f89813ba83d5dcbce1c8f01406976608b50b0a286a1c573ec0e6a28b55a8c45f
7
- data.tar.gz: 6c3f2ad8a8fec46786012b8df87f9c89e4500b5d675fb21bd9cf917f87bb53e44ef6bf9b95694dfb236622beb57adfd4b354317a280e049e7c65d72f4bbab5cb
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
- start_buffer_broker(output_queue)
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
- @lumberjack.close
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
- return event
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
- return decoded
150
+ block.call(decoded)
146
151
  end
147
152
  end
148
- return nil
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
- event = create_event(map, identity_stream)
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(output_queue)
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.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.1"
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
 
@@ -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
- event = beats.create_event(event_map, identity_stream)
94
- expect(event["foo"]).to eq("bar")
95
- expect(event["[@metadata][hidden]"]).to eq("secret")
96
- expect(event["tags"]).to include("bonjour")
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
- event = beats.create_event(event_map, identity_stream)
105
- expect(event["foo"]).to eq("bar")
106
- expect(event["[@metadata][hidden]"]).to eq("secret")
107
- expect(event["tags"]).to include("bonjour")
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 "retuns nil" do
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 be_nil
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.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-17 00:00:00.000000000 Z
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.1
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.1
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
- - spec/spec_helper.rb
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.1.9
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