logstash-codec-multiline 3.1.1 → 3.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/logstash/codecs/identity_map_codec.rb +13 -6
- data/logstash-codec-multiline.gemspec +1 -1
- data/spec/codecs/identity_map_codec_spec.rb +76 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e46243c32a2f87ede3a266ee117dd89086a5a48454813d8979fe04a25454692
|
4
|
+
data.tar.gz: fedc22e883fd7e842a4de3f8cf599268c57f7b1d7de06a40a5d5fb27cd86febb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: faa8892c245b03438c1cd63f5812b8e5c80c145b55fd437e8eb3ab82baf4bb94f23754d720c40016fc8bfecf23a6eae7cbb1c1ab4e0a34f5a5a4e37efe1d8fec
|
7
|
+
data.tar.gz: 415515b5dc715d12df012febfc9a91cf986d8c05fd73f975bc284807bbd034e436168a6d624299bc53aea5417bae4d391f10b97b32a07b0b43be7ac197de8a7a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
## 3.1.2
|
2
|
+
- Fix: periodic runner fails to stop and prevent pipeline shutdown [#72](https://github.com/logstash-plugins/logstash-codec-multiline/pull/72)
|
3
|
+
|
1
4
|
## 3.1.1
|
2
5
|
- Fix: avoid reusing per-identity codec instances for differing identities. Removes a very minor optimization so that stateful codecs like CSV can work reliably [#70](https://github.com/logstash-plugins/logstash-codec-multiline/pull/70)
|
3
6
|
|
@@ -42,15 +42,20 @@ module LogStash module Codecs class IdentityMapCodec
|
|
42
42
|
def initialize(listener, interval, method_symbol)
|
43
43
|
@listener, @interval = listener, interval
|
44
44
|
@method_symbol = method_symbol
|
45
|
-
@running = Concurrent::AtomicBoolean.new(
|
45
|
+
@running = Concurrent::AtomicBoolean.new(true)
|
46
46
|
end
|
47
47
|
|
48
|
+
# The goal of periodic runner is to have a single thread to do clean up / auto flush
|
49
|
+
# This method is expected to access by a single thread,
|
50
|
+
# otherwise, multiple Thread.start could create more than one periodic runner
|
48
51
|
def start
|
49
|
-
return self
|
50
|
-
|
52
|
+
return self unless running?
|
53
|
+
return self if running? && !@thread.nil?
|
54
|
+
|
51
55
|
@thread = Thread.start do
|
52
56
|
class_name = @listener.class.name.split('::').last # IdentityMapCodec
|
53
57
|
LogStash::Util.set_thread_name("#{class_name}##{@method_symbol}")
|
58
|
+
@listener.logger.debug("Start periodic runner")
|
54
59
|
|
55
60
|
while running? do
|
56
61
|
sleep @interval
|
@@ -67,9 +72,11 @@ module LogStash module Codecs class IdentityMapCodec
|
|
67
72
|
end
|
68
73
|
|
69
74
|
def stop
|
70
|
-
return
|
75
|
+
return unless running?
|
76
|
+
|
77
|
+
@listener.logger.debug("Stop periodic runner")
|
71
78
|
@running.make_false
|
72
|
-
while @thread
|
79
|
+
while @thread&.alive?
|
73
80
|
begin
|
74
81
|
@thread.wakeup
|
75
82
|
rescue ThreadError
|
@@ -313,7 +320,7 @@ module LogStash module Codecs class IdentityMapCodec
|
|
313
320
|
def record_codec_usage(identity)
|
314
321
|
check_map_limits
|
315
322
|
# only start the cleaner if streams are in use
|
316
|
-
# continuous calls to start are OK
|
323
|
+
# continuous calls to start are OK if this codec method is accessed by a single thread
|
317
324
|
cleaner.start
|
318
325
|
auto_flusher.start
|
319
326
|
compo = find_codec_value(identity)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-codec-multiline'
|
4
|
-
s.version = '3.1.
|
4
|
+
s.version = '3.1.2'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Merges multiline messages into a single event"
|
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/logstash-plugin install gemname. This gem is not a stand-alone program"
|
@@ -299,3 +299,79 @@ describe LogStash::Codecs::IdentityMapCodec do
|
|
299
299
|
end
|
300
300
|
end
|
301
301
|
end
|
302
|
+
|
303
|
+
describe LogStash::Codecs::IdentityMapCodec::PeriodicRunner do
|
304
|
+
let(:listener) do
|
305
|
+
double('Listener', logger: double('Logger').as_null_object,
|
306
|
+
some_method: double('method_symbol').as_null_object)
|
307
|
+
end
|
308
|
+
let(:interval) { 1 }
|
309
|
+
let(:method_symbol) { :some_method }
|
310
|
+
subject(:runner) { described_class.new(listener, interval, method_symbol) }
|
311
|
+
|
312
|
+
before(:all) do
|
313
|
+
Thread.abort_on_exception = true
|
314
|
+
end
|
315
|
+
|
316
|
+
describe "normal shutdown" do
|
317
|
+
it "starts first and stops successfully" do
|
318
|
+
start_thread = Thread.start do
|
319
|
+
runner.start
|
320
|
+
end
|
321
|
+
|
322
|
+
stop_thread = Thread.start do
|
323
|
+
sleep(1)
|
324
|
+
runner.stop
|
325
|
+
end
|
326
|
+
|
327
|
+
start_thread.join
|
328
|
+
stop_thread.join
|
329
|
+
|
330
|
+
expect(runner.instance_variable_get('@listener')).to be_nil
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
describe "race condition" do
|
335
|
+
let(:atomic_bool) { Concurrent::AtomicBoolean.new(true) }
|
336
|
+
let(:running) { double('AtomicBooleanStub') }
|
337
|
+
|
338
|
+
before do
|
339
|
+
allow(running).to receive(:make_true) do
|
340
|
+
atomic_bool.make_true
|
341
|
+
end
|
342
|
+
|
343
|
+
allow(running).to receive(:make_false) do
|
344
|
+
atomic_bool.make_false
|
345
|
+
sleep(2)
|
346
|
+
end
|
347
|
+
|
348
|
+
allow(running).to receive(:true?) do
|
349
|
+
atomic_bool.true?
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
before :each do
|
354
|
+
runner.instance_variable_set('@running', running)
|
355
|
+
end
|
356
|
+
|
357
|
+
it "starts several times and stops successfully" do
|
358
|
+
start_thread = Thread.start do
|
359
|
+
5.times do
|
360
|
+
runner.start
|
361
|
+
sleep(1)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
stop_thread = Thread.start do
|
366
|
+
sleep(1) # give time to runner start
|
367
|
+
runner.stop
|
368
|
+
end
|
369
|
+
|
370
|
+
start_thread.join
|
371
|
+
stop_thread.join
|
372
|
+
|
373
|
+
expect(runner.instance_variable_get('@listener')).to be_nil
|
374
|
+
expect(runner.instance_variable_get('@thread').alive?).to be_falsey
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-codec-multiline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
173
|
- !ruby/object:Gem::Version
|
174
174
|
version: '0'
|
175
175
|
requirements: []
|
176
|
-
rubygems_version: 3.
|
176
|
+
rubygems_version: 3.2.33
|
177
177
|
signing_key:
|
178
178
|
specification_version: 4
|
179
179
|
summary: Merges multiline messages into a single event
|