logstash-input-beats 2.2.5 → 2.2.7

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: fff429c1372d2d1a71ae92cadf753d421b009d46
4
- data.tar.gz: 2f84e5dc8bc9ff6c79a0d7cb0485b2a2ee5fb07e
3
+ metadata.gz: 0c9f5e238355c46a4cf8de5a79ab788941bfd524
4
+ data.tar.gz: c40c248be28f9c7a28764761340dd0d926f6cdb6
5
5
  SHA512:
6
- metadata.gz: 5018ac549a816be327dab8590b918db01c6a3453c3aead991c8cbe63af9cbb47cf7a8d5445dbe8d425647db9c753ffb14f55877b3c031566c300d2448a3370d7
7
- data.tar.gz: ce32435856bc68e86dd6df0355c4fab9d10dd7237ee11f99782fb9b905b90a4e3a6aa6a7b9b1c0b940f2d8754ece577f303b523d98752fe0c08bf3e58c0d7e87
6
+ metadata.gz: 12996169fca9958102f280cb5d532cb17717f940ac62f4d7deaa19a851b875817e8da5432fd0fec5733971b7de9de4d2b2fec498bb9f8f281bbb7d54b6a056bb
7
+ data.tar.gz: 1a3a6d86aaf2f30a63524d98664b1abdce873e03e1dca0b180c2650314f19f6229730cbcfa4902d3eb8b0a2b14e1b43c8c04c3133399dee6921ab64a46fecbec
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ # 2.2.7
2
+ - More robust test when using a random port #60
3
+ - Fix LSF integration tests #52
4
+ # 2.2.6
5
+ - Do not use the identity map if we don't explicitly use the `multiline` codec
1
6
  # 2.2.5
2
7
  - Fix failing tests introduce by the `ssl_key_passphrase` changes.
3
8
  - Added an integration test for the `ssl_key_passphrase`
@@ -5,6 +5,7 @@ require "logstash/timestamp"
5
5
  require "lumberjack/beats"
6
6
  require "lumberjack/beats/server"
7
7
  require "logstash/codecs/identity_map_codec"
8
+ require "logstash/codecs/multiline"
8
9
  require "logstash/inputs/beats_support/circuit_breaker"
9
10
  require "logstash/inputs/beats_support/codec_callback_listener"
10
11
  require "logstash/inputs/beats_support/connection_handler"
@@ -127,8 +128,13 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
127
128
  :exceptions => [InsertingToQueueTakeTooLong])
128
129
 
129
130
  # wrap the configured codec to support identity stream
130
- # from the producers
131
- @codec = LogStash::Codecs::IdentityMapCodec.new(@codec)
131
+ # from the producers if running with the multiline codec.
132
+ #
133
+ # If they dont need an identity map, codec are stateless and can be reused
134
+ # accross multiples connections.
135
+ if need_identity_map?
136
+ @codec = LogStash::Codecs::IdentityMapCodec.new(@codec)
137
+ end
132
138
 
133
139
  # Keep a list of active connections so we can flush their codec on shutdown
134
140
 
@@ -256,4 +262,8 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
256
262
  end
257
263
  end
258
264
  end
265
+
266
+ def need_identity_map?
267
+ @codec.kind_of?(LogStash::Codecs::Multiline)
268
+ end
259
269
  end # class LogStash::Inputs::Beats
@@ -11,7 +11,7 @@ module LogStash::Inputs::BeatsSupport
11
11
  event["@timestamp"] = ts unless ts.nil?
12
12
  hash.each { |k, v| event[k] = v }
13
13
  super(event)
14
- event.tag("beats_input_codec_#{@input.codec.base_codec.class.config_name}_applied")
14
+ event.tag("beats_input_codec_#{codec_name}_applied")
15
15
  event
16
16
  end
17
17
 
@@ -31,6 +31,14 @@ module LogStash::Inputs::BeatsSupport
31
31
  @input.send(:decorate, event)
32
32
  end
33
33
 
34
+ def codec_name
35
+ @codec_name ||= if @input.codec.respond_to?(:base_codec)
36
+ @input.codec.base_codec.class.config
37
+ else
38
+ @input.codec.class.config_name
39
+ end
40
+ end
41
+
34
42
  def transform(event)
35
43
  copy_beat_hostname(event)
36
44
  decorate(event)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "logstash-input-beats"
3
- s.version = '2.2.5'
3
+ s.version = '2.2.7'
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"
@@ -16,6 +16,30 @@ describe LogStash::Inputs::Beats do
16
16
  let(:config) { { "port" => 0, "ssl_certificate" => certificate.ssl_cert, "ssl_key" => certificate.ssl_key, "type" => "example", "tags" => "beats"} }
17
17
 
18
18
  context "#register" do
19
+ context "identity map" do
20
+ subject(:plugin) { LogStash::Inputs::Beats.new(config) }
21
+ before { plugin.register }
22
+
23
+ context "when using the multiline codec" do
24
+ let(:codec) { LogStash::Codecs::Multiline.new("pattern" => '^2015',
25
+ "what" => "previous",
26
+ "negate" => true) }
27
+ let(:config) { super.merge({ "codec" => codec }) }
28
+
29
+ it "wraps the codec with the identity_map" do
30
+ expect(plugin.codec).to be_kind_of(LogStash::Codecs::IdentityMapCodec)
31
+ end
32
+ end
33
+
34
+ context "when using non buffered codecs" do
35
+ let(:config) { super.merge({ "codec" => "json" }) }
36
+
37
+ it "doesnt wrap the codec with the identity map" do
38
+ expect(plugin.codec).to be_kind_of(LogStash::Codecs::JSON)
39
+ end
40
+ end
41
+ end
42
+
19
43
  it "raise no exception" do
20
44
  plugin = LogStash::Inputs::Beats.new(config)
21
45
  expect { plugin.register }.not_to raise_error
@@ -10,7 +10,7 @@ require "spec_helper"
10
10
 
11
11
  LSF_BINARY = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "vendor", "logstash-forwarder", "logstash-forwarder"))
12
12
 
13
- xdescribe "Logstash-Forwarder", :integration => true do
13
+ describe "Logstash-Forwarder", :integration => true do
14
14
  include ClientProcessHelpers
15
15
 
16
16
  before :all do
@@ -61,6 +61,7 @@ xdescribe "Logstash-Forwarder", :integration => true do
61
61
 
62
62
  context "Plain TCP" do
63
63
  include ClientProcessHelpers
64
+
64
65
  let(:certificate_authorities) { "" }
65
66
 
66
67
  it "should not send any events" do
@@ -85,13 +86,12 @@ xdescribe "Logstash-Forwarder", :integration => true do
85
86
  let(:certificate_authorities) { certificate_file }
86
87
 
87
88
  context "self signed certificate" do
88
- include_examples "send events" do
89
- end
89
+ include_examples "send events"
90
90
  end
91
91
 
92
92
  context "invalid CA on the client" do
93
93
  let(:invalid_data) { Flores::PKI.generate }
94
- let(:certificate_authorities) { invalid_data.first }
94
+ let(:certificate_authorities) { f = Stud::Temporary.file; f.close; f.path }
95
95
 
96
96
  it "should not send any events" do
97
97
  expect(queue.size).to eq(0), @execution_output
@@ -30,8 +30,8 @@ describe "A client" do
30
30
  p.close
31
31
  p.path
32
32
  end
33
- let(:port) { Flores::Random.integer(1024..65335) }
34
- let(:tcp_port) { port + 1 }
33
+ let(:port) { Flores::Random.port }
34
+ let(:tcp_port) { Flores::Random.port }
35
35
  let(:host) { "127.0.0.1" }
36
36
  let(:queue) { [] }
37
37
  let(:config_ssl) do
@@ -11,7 +11,7 @@ require "zlib"
11
11
 
12
12
  describe Lumberjack::Beats::Client do
13
13
  describe Lumberjack::Beats::Socket do
14
- let(:port) { 5000 }
14
+ let(:port) { Flores::Random.port }
15
15
 
16
16
  subject(:socket) { Lumberjack::Beats::Socket.new(:port => port, :ssl_certificate => "" ) }
17
17
 
@@ -5,7 +5,7 @@ require "flores/random"
5
5
 
6
6
  describe "Connnection" do
7
7
  let(:ip) { "192.168.1.2" }
8
- let(:port) { 4444 }
8
+ let(:port) { Flores::Random.port }
9
9
  let(:server) { double("server", :closed? => false) }
10
10
  let(:socket) { double("socket", :closed? => false) }
11
11
  let(:connection) { Lumberjack::Beats::Connection.new(socket, server) }
@@ -4,6 +4,7 @@ require "lumberjack/beats/server"
4
4
  require "flores/random"
5
5
  require "flores/pki"
6
6
  require "spec_helper"
7
+ require_relative "../../support/flores_extensions"
7
8
 
8
9
  Thread.abort_on_exception = true
9
10
 
@@ -11,8 +12,8 @@ describe "Server" do
11
12
  let(:certificate) { Flores::PKI.generate }
12
13
  let(:certificate_file_crt) { "certificate.crt" }
13
14
  let(:certificate_file_key) { "certificate.key" }
14
- let(:port) { Flores::Random.integer(1024..65335) }
15
- let(:tcp_port) { port + 1 }
15
+ let(:port) { Flores::Random.port }
16
+ let(:tcp_port) { Flores::Random.port }
16
17
  let(:host) { "127.0.0.1" }
17
18
  let(:queue) { [] }
18
19
 
@@ -10,6 +10,12 @@ module ClientProcessHelpers
10
10
  @process.io.stdout = @process.io.stderr = @client_out
11
11
  ChildProcess.posix_spawn = true
12
12
  @process.start
13
+
14
+ sleep(0.1)
15
+ @client_out.rewind
16
+
17
+ # can be used to helper debugging when a test fails
18
+ @execution_output = @client_out.read
13
19
  end
14
20
 
15
21
  def stop_client
@@ -18,10 +24,5 @@ module ClientProcessHelpers
18
24
  rescue ChildProcess::TimeoutError
19
25
  @process.stop
20
26
  end
21
-
22
- @client_out.rewind
23
-
24
- # can be used to helper debugging when a test fails
25
- @execution_output = @client_out.read
26
27
  end
27
28
  end
@@ -1,6 +1,46 @@
1
1
  # encoding: utf-8
2
2
  require "flores/pki"
3
+ require "flores/random"
4
+
3
5
  module Flores
6
+ module Random
7
+ DEFAULT_PORT_RANGE = 1024..65535
8
+ DEFAULT_PORT_CHECK_TIMEOUT = 1
9
+ DEFAULT_MAXIMUM_PORT_FIND_TRY = 15
10
+
11
+ class << self
12
+ def port(range = DEFAULT_PORT_RANGE)
13
+ try = 0
14
+ while try < DEFAULT_MAXIMUM_PORT_FIND_TRY
15
+ candidate = integer(range)
16
+
17
+ if port_available?(candidate)
18
+ break
19
+ else
20
+ try += 1
21
+ end
22
+ end
23
+
24
+ raise "Flores.random_port: Cannot find an available port, tried #{DEFAULT_MAXIMUM_PORT_FIND_TRY} times, range was: #{range}" if try == DEFAULT_MAXIMUM_PORT_FIND_TRY
25
+
26
+ candidate
27
+ end
28
+
29
+ def port_available?(port)
30
+ begin
31
+ server = TCPServer.new(port)
32
+ available = true
33
+ rescue # Assume that any errors can do this
34
+ available = false
35
+ ensure
36
+ server.close if server
37
+ end
38
+
39
+ return available
40
+ end
41
+ end
42
+ end
43
+
4
44
  module PKI
5
45
  DEFAULT_CERTIFICATE_OPTIONS = {
6
46
  :duration => Flores::Random.number(100..2000),
@@ -3,7 +3,7 @@ require "flores/random"
3
3
 
4
4
  shared_examples "send events" do
5
5
  it "successfully send the events" do
6
- expect(queue.size).to eq(number_of_events), "Expected: #{number_of_events} got: #{queue.size}, execution output:\n #{@execution_output}"
6
+ wait(15).for { queue.size }.to eq(number_of_events), "Expected: #{number_of_events} got: #{queue.size}, execution output:\n #{@execution_output}"
7
7
  expect(queue.collect { |e| e["message"] }).to eq(events)
8
8
  end
9
9
  end
@@ -16,11 +16,11 @@ end
16
16
 
17
17
  shared_context "beats configuration" do
18
18
  # common
19
- let(:port) { Flores::Random.integer(1024..65335) }
19
+ let(:port) { Flores::Random.port }
20
20
  let(:host) { "localhost" }
21
21
 
22
22
  let(:queue) { [] }
23
- let(:log_file) { write_to_tmp_file(events.join("\n") + "\n") } # make sure we end of line
23
+ let_tmp_file(:log_file) { events.join("\n") + "\n" } # make sure we end of line
24
24
  let(:number_of_events) { 5 }
25
25
  let(:event) { "Hello world" }
26
26
  let(:events) do
@@ -44,7 +44,11 @@ shared_context "beats configuration" do
44
44
  beats.register
45
45
 
46
46
  @server = Thread.new do
47
- beats.run(queue)
47
+ begin
48
+ beats.run(queue)
49
+ rescue
50
+ retry unless beats.stop?
51
+ end
48
52
  end
49
53
  @server.abort_on_exception = true
50
54
 
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.2.5
4
+ version: 2.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-29 00:00:00.000000000 Z
11
+ date: 2016-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement