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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2579876a333e816be9826e4d9f0f02f67634a4e4370f90cbcde04465f9d18b2a
4
- data.tar.gz: 4c915fe445fe7b98e3ce584432a196951317d5b8fe2be41897e0234fd25868a1
3
+ metadata.gz: 3e46243c32a2f87ede3a266ee117dd89086a5a48454813d8979fe04a25454692
4
+ data.tar.gz: fedc22e883fd7e842a4de3f8cf599268c57f7b1d7de06a40a5d5fb27cd86febb
5
5
  SHA512:
6
- metadata.gz: 44f1bba5815ee431f52265a630628b41e5b0460a23d54fb1eccd3d21004f1fd441129434baf75616995d27ff28c2925d04510f83e36fd02d5af9e5a23dad3250
7
- data.tar.gz: 3770b8ed35551d6c21a88f037b0ed94417b7fad630f5e680afa1bb93ca481d985d593c29af77e8537b40eb85adec5e7e2743dcf293c64aa4056a510056b573df
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(false)
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 if running?
50
- @running.make_true
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 if !running?
75
+ return unless running?
76
+
77
+ @listener.logger.debug("Stop periodic runner")
71
78
  @running.make_false
72
- while @thread.alive?
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.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.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: 2021-09-28 00:00:00.000000000 Z
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.1.6
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