logstash-input-lumberjack 2.0.4 → 2.0.5

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: 0a025fb8e90f7ef8cff219175a2a73291c282cad
4
- data.tar.gz: 5377ffc16b90af44b33130735f6607f268e05c8f
3
+ metadata.gz: a42b36942f3d863258583d875580d5386940e590
4
+ data.tar.gz: 1e0eb3341743ce7d86663ec74eebfe5c2f839318
5
5
  SHA512:
6
- metadata.gz: 491440a3ae82f0a6f13f57e580cbc4d8cdd9b9898fd8bc45486f30569422a62ede36d003501fa124ae5c94d57db57f95c01f3b75bd97aa906a84d2284cc9e8ac
7
- data.tar.gz: af441b88b8ad828f51fe57c262cd6191cefb1c5111da8ea0d2901d40329dcbdb7d4f2eac3a45e26e57ed3f46c1937aaadbe9bf71d80c14ac251e89c603bfca38
6
+ metadata.gz: ce1c18afd1ebbddf7dbc8d4fc698c6d6c87eed0fed2f1b9364756b942569bf6d96e2f8382e6b89a135f77e4c675e74056247eaa3f31152c39617ba0878dde4fb
7
+ data.tar.gz: f26e84688ae7c19ae9f5c20fa3e2427e9a11c63cc32589657c9d7b2f83c0ea54b6147603e620f825a726244562ac311f15a3bc7c9f2b4afdcd9b2263ccf38d47
@@ -1,3 +1,6 @@
1
+ ## 2.0.5
2
+ - Add support for `stream_identity` to make the lumberjack input able to do disambiguation of file when using the multiline codec #53
3
+
1
4
  ## 2.0.4
2
5
  - Update `ruby-lumberjack` dependency to 0.0.26
3
6
 
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Logstash Plugin
2
2
 
3
+ [![Build
4
+ Status](http://build-eu-00.elastic.co/view/LS%20Plugins/view/LS%20Inputs/job/logstash-plugin-input-lumberjack-unit/badge/icon)](http://build-eu-00.elastic.co/view/LS%20Plugins/view/LS%20Inputs/job/logstash-plugin-input-lumberjack-unit/)
5
+
3
6
  This is a plugin for [Logstash](https://github.com/elastic/logstash).
4
7
 
5
8
  It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require "logstash/inputs/base"
3
3
  require "logstash/namespace"
4
+ require "logstash/codecs/identity_map_codec"
4
5
 
5
6
  # Receive events using the lumberjack protocol.
6
7
  #
@@ -63,31 +64,28 @@ class LogStash::Inputs::Lumberjack < LogStash::Inputs::Base
63
64
  @circuit_breaker = LogStash::CircuitBreaker.new("Lumberjack input",
64
65
  :exceptions => [LogStash::SizedQueueTimeout::TimeoutError])
65
66
 
67
+ @codec = LogStash::Codecs::IdentityMapCodec.new(@codec)
66
68
  end # def register
67
69
 
68
70
  def run(output_queue)
69
- start_buffer_broker(output_queue)
71
+ @output_queue = output_queue
72
+ start_buffer_broker
70
73
 
74
+ @codec.eviction_block(method(:flush_event))
75
+
76
+ # Accepting new events coming from LSF
71
77
  while !stop? do
72
- # Wrappingu the accept call into a CircuitBreaker
78
+ # Wrapping the accept call into a CircuitBreaker
73
79
  if @circuit_breaker.closed?
74
80
  connection = @lumberjack.accept # call that creates a new connection
75
81
  next if connection.nil? # if the connection is nil the connection was close.
76
- invoke(connection, @codec.clone) do |_codec, line, fields|
82
+ invoke(connection) do |event|
77
83
  if stop?
78
84
  connection.close
79
85
  break
80
86
  end
81
87
 
82
- _codec.decode(line) do |event|
83
- begin
84
- decorate(event)
85
- fields.each { |k,v| event[k] = v; v.force_encoding(Encoding::UTF_8) }
86
- @circuit_breaker.execute { @buffered_queue.push(event, @congestion_threshold) }
87
- rescue => e
88
- raise e
89
- end
90
- end
88
+ @circuit_breaker.execute { @buffered_queue.push(event, @congestion_threshold) }
91
89
  end
92
90
  else
93
91
  @logger.warn("Lumberjack input: the pipeline is blocked, temporary refusing new connection.")
@@ -99,16 +97,52 @@ class LogStash::Inputs::Lumberjack < LogStash::Inputs::Base
99
97
  public
100
98
  def stop
101
99
  @lumberjack.close
100
+ @codec.flush { |event| flush_event(event) }
101
+ end
102
+
103
+ # I have created this method to make testing a lot easier,
104
+ # mocking multiples levels of block is unfriendly especially with
105
+ # connection based block.
106
+ public
107
+ def create_event(fields, &block)
108
+ line = fields.delete("line")
109
+
110
+ @codec.decode(line, identity(fields)) do |event|
111
+ decorate(event)
112
+ fields.each { |k,v| event[k] = v; v.force_encoding(Encoding::UTF_8) }
113
+ block.call(event)
114
+ end
115
+ end
116
+
117
+ private
118
+ # It use the host and the file as the differentiator,
119
+ # if anything is provided it should fallback to an empty string.
120
+ def identity(fields)
121
+ [fields["host"], fields["file"]].compact.join("-")
122
+ end
123
+ # There is a problem with the way the codecs work for this specific input,
124
+ # when the data is decoded there is no way to attach metadata with the decoded line.
125
+ # If you look at the block used by `@codec.decode` it reference the fields variable
126
+ # which is available when the proc is created, the problem is that variable with the data is
127
+ # not available at eviction time or when we force a flush on the codec before
128
+ # shutting down the input.
129
+ #
130
+ # Not defining the method will make logstash lose data, so Its still better to force a flush
131
+ #
132
+ # See this issue https://github.com/elastic/logstash/issues/4289 for more discussion
133
+ def flush_event(event)
134
+ decorate(event)
135
+ @output_queue << event
102
136
  end
103
137
 
104
138
  private
105
- def invoke(connection, codec, &block)
139
+ def invoke(connection, &block)
106
140
  @threadpool.post do
107
141
  begin
108
142
  # If any errors occur in from the events the connection should be closed in the
109
143
  # library ensure block and the exception will be handled here
110
144
  connection.run do |fields|
111
- block.call(codec, fields.delete("line"), fields)
145
+ create_event(fields, &block)
112
146
  end
113
147
 
114
148
  # When too many errors happen inside the circuit breaker it will throw
@@ -125,10 +159,10 @@ class LogStash::Inputs::Lumberjack < LogStash::Inputs::Base
125
159
  end
126
160
  end
127
161
 
128
- def start_buffer_broker(output_queue)
162
+ def start_buffer_broker
129
163
  @threadpool.post do
130
164
  while !stop?
131
- output_queue << @buffered_queue.pop_no_timeout
165
+ @output_queue << @buffered_queue.pop_no_timeout
132
166
  end
133
167
  end
134
168
  end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-input-lumberjack'
4
- s.version = '2.0.4'
4
+ s.version = '2.0.5'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Receive events using the lumberjack protocol."
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/plugin install gemname. This gem is not a stand-alone program"
@@ -23,11 +23,11 @@ Gem::Specification.new do |s|
23
23
  s.add_runtime_dependency "logstash-core", ">= 2.0.0.beta2", "< 3.0.0"
24
24
 
25
25
  s.add_runtime_dependency 'logstash-codec-plain'
26
- s.add_runtime_dependency 'jls-lumberjack', ['>=0.0.26']
26
+ s.add_runtime_dependency 'jls-lumberjack', '~> 0.0.26'
27
27
  s.add_runtime_dependency "concurrent-ruby"
28
+ s.add_runtime_dependency 'logstash-codec-multiline', "~> 2.0.4"
28
29
 
29
30
  s.add_development_dependency 'logstash-devutils'
30
- s.add_development_dependency 'logstash-codec-multiline'
31
31
  s.add_development_dependency "flores"
32
32
  s.add_development_dependency "stud"
33
33
  end
@@ -6,14 +6,18 @@ require "logstash/codecs/plain"
6
6
  require "logstash/codecs/multiline"
7
7
  require "logstash/event"
8
8
  require "lumberjack/client"
9
+ require "lumberjack/server"
9
10
 
10
11
  Thread.abort_on_exception = true
11
12
  describe LogStash::Inputs::Lumberjack do
12
13
  let(:connection) { double("connection") }
13
14
  let(:certificate) { LogStashTest.certificate }
14
- let(:port) { LogStashTest.random_port }
15
- let(:queue) { Queue.new }
16
- let(:config) { { "port" => 0, "ssl_certificate" => certificate.ssl_cert, "ssl_key" => certificate.ssl_key, "type" => "example", "tags" => "lumberjack" } }
15
+ let(:queue) { [] }
16
+ let(:config) { { "port" => 0,
17
+ "ssl_certificate" => certificate.ssl_cert,
18
+ "ssl_key" => certificate.ssl_key,
19
+ "type" => "example",
20
+ "tags" => "lumberjack" } }
17
21
 
18
22
  subject(:lumberjack) { LogStash::Inputs::Lumberjack.new(config) }
19
23
 
@@ -25,25 +29,49 @@ describe LogStash::Inputs::Lumberjack do
25
29
  end
26
30
 
27
31
  describe "#processing of events" do
28
- let(:lines) { {"line" => "one\ntwo\n two.2\nthree\n", "tags" => ["syslog"]} }
29
-
30
- before do
31
- allow(connection).to receive(:run).and_yield(lines)
32
- lumberjack.register
33
- expect_any_instance_of(Lumberjack::Server).to receive(:accept).and_return(connection)
34
- end
32
+ context "multiline" do
33
+ let(:codec) { LogStash::Codecs::Multiline.new("pattern" => '^2015',
34
+ "what" => "previous",
35
+ "negate" => true) }
36
+ let(:config) { super.merge({ "codec" => codec }) }
37
+ let(:events_map) do
38
+ [
39
+ { "host" => "machineA", "file" => "/var/log/line", "line" => "2015-11-10 10:14:38,907 line 1" },
40
+ { "host" => "machineA", "file" => "/var/log/other", "line" => "2015-11-10 10:14:38,907 xline 1" },
41
+ { "host" => "machineA", "file" => "/var/log/line", "line" => "line 1.1" },
42
+ { "host" => "machineA", "file" => "/var/log/other", "line" => "xline 1.1" },
43
+ { "host" => "machineA", "file" => "/var/log/line", "line" => "2015-11-10 10:16:38,907 line 2" },
44
+ { "host" => "machineA", "file" => "/var/log/other", "line" => "2015-11-10 10:16:38,907 xline 2" },
45
+ { "host" => "machineA", "file" => "/var/log/line", "line" => "line 2.1" },
46
+ { "host" => "machineA", "file" => "/var/log/other", "line" => "xline 2.1" },
47
+ { "host" => "machineA", "file" => "/var/log/line", "line" => "line 2.2" },
48
+ { "host" => "machineA", "file" => "/var/log/other", "line" => "xline 2.2" },
49
+ { "host" => "machineA", "file" => "/var/log/line", "line" => "line 2.3" },
50
+ { "host" => "machineA", "file" => "/var/log/other", "line" => "xline 2.3" },
51
+ { "host" => "machineA", "file" => "/var/log/line", "line" => "2015-11-10 10:18:38,907 line 3" },
52
+ { "host" => "machineA", "file" => "/var/log/other", "line" => "2015-11-10 10:18:38,907 xline 3" }
53
+ ]
54
+ end
35
55
 
36
- context "#codecs" do
37
- let(:config) do
38
- { "port" => port, "ssl_certificate" => certificate.ssl_cert, "ssl_key" => certificate.ssl_key,
39
- "type" => "example", "codec" => codec }
56
+ before do
57
+ lumberjack.register
58
+ Thread.new { lumberjack.run(queue) }
40
59
  end
41
60
 
42
- let(:codec) { LogStash::Codecs::Multiline.new("pattern" => '\n', "what" => "previous") }
43
- it "clone the codec per connection" do
44
- expect(lumberjack.codec).to receive(:clone).once
45
- expect(lumberjack).to receive(:invoke) { break }
46
- lumberjack.run(queue)
61
+ it "should correctly merge multiple events" do
62
+ # This test, cannot currently work without explicitely call a flush
63
+ # the flush is never timebased, if no new data is coming in we wont flush the buffer
64
+ # https://github.com/logstash-plugins/logstash-codec-multiline/issues/11
65
+ events_map.each { |e| lumberjack.create_event(e) { |e| queue << e } }
66
+ lumberjack.stop
67
+
68
+ expect(queue.size).to eq(6)
69
+ expect(queue.collect { |e| e["message"] }).to include("2015-11-10 10:14:38,907 line 1\nline 1.1",
70
+ "2015-11-10 10:14:38,907 xline 1\nxline 1.1",
71
+ "2015-11-10 10:16:38,907 line 2\nline 2.1\nline 2.2\nline 2.3",
72
+ "2015-11-10 10:16:38,907 xline 2\nxline 2.1\nxline 2.2\nxline 2.3",
73
+ "2015-11-10 10:18:38,907 line 3",
74
+ "2015-11-10 10:18:38,907 xline 3")
47
75
  end
48
76
  end
49
77
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-lumberjack
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-19 00:00:00.000000000 Z
11
+ date: 2015-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logstash-core
@@ -48,12 +48,12 @@ dependencies:
48
48
  name: jls-lumberjack
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - '>='
51
+ - - ~>
52
52
  - !ruby/object:Gem::Version
53
53
  version: 0.0.26
54
54
  requirement: !ruby/object:Gem::Requirement
55
55
  requirements:
56
- - - '>='
56
+ - - ~>
57
57
  - !ruby/object:Gem::Version
58
58
  version: 0.0.26
59
59
  prerelease: false
@@ -73,21 +73,21 @@ dependencies:
73
73
  prerelease: false
74
74
  type: :runtime
75
75
  - !ruby/object:Gem::Dependency
76
- name: logstash-devutils
76
+ name: logstash-codec-multiline
77
77
  version_requirements: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - '>='
79
+ - - ~>
80
80
  - !ruby/object:Gem::Version
81
- version: '0'
81
+ version: 2.0.4
82
82
  requirement: !ruby/object:Gem::Requirement
83
83
  requirements:
84
- - - '>='
84
+ - - ~>
85
85
  - !ruby/object:Gem::Version
86
- version: '0'
86
+ version: 2.0.4
87
87
  prerelease: false
88
- type: :development
88
+ type: :runtime
89
89
  - !ruby/object:Gem::Dependency
90
- name: logstash-codec-multiline
90
+ name: logstash-devutils
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - '>='
@@ -134,21 +134,21 @@ executables: []
134
134
  extensions: []
135
135
  extra_rdoc_files: []
136
136
  files:
137
+ - CHANGELOG.md
138
+ - CONTRIBUTORS
139
+ - Gemfile
140
+ - LICENSE
141
+ - NOTICE.TXT
142
+ - README.md
137
143
  - lib/logstash/circuit_breaker.rb
138
- - lib/logstash/sized_queue_timeout.rb
139
144
  - lib/logstash/inputs/lumberjack.rb
140
- - spec/spec_helper.rb
145
+ - lib/logstash/sized_queue_timeout.rb
146
+ - logstash-input-lumberjack.gemspec
141
147
  - spec/inputs/lumberjack_spec.rb
142
148
  - spec/logstash/circuit_breaker_spec.rb
143
149
  - spec/logstash/size_queue_timeout_spec.rb
150
+ - spec/spec_helper.rb
144
151
  - spec/support/logstash_test.rb
145
- - logstash-input-lumberjack.gemspec
146
- - README.md
147
- - CHANGELOG.md
148
- - CONTRIBUTORS
149
- - Gemfile
150
- - LICENSE
151
- - NOTICE.TXT
152
152
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
153
153
  licenses:
154
154
  - Apache License (2.0)
@@ -171,13 +171,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
171
  version: '0'
172
172
  requirements: []
173
173
  rubyforge_project:
174
- rubygems_version: 2.1.9
174
+ rubygems_version: 2.4.8
175
175
  signing_key:
176
176
  specification_version: 4
177
177
  summary: Receive events using the lumberjack protocol.
178
178
  test_files:
179
- - spec/spec_helper.rb
180
179
  - spec/inputs/lumberjack_spec.rb
181
180
  - spec/logstash/circuit_breaker_spec.rb
182
181
  - spec/logstash/size_queue_timeout_spec.rb
182
+ - spec/spec_helper.rb
183
183
  - spec/support/logstash_test.rb