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 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