logstash-core 5.0.0.alpha5.snapshot1-java → 5.0.0.alpha6.snapshot1-java

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.

Potentially problematic release.


This version of logstash-core might be problematic. Click here for more details.

Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/lib/logstash-core/version.rb +1 -1
  3. data/lib/logstash/agent.rb +1 -1
  4. data/lib/logstash/api/commands/default_metadata.rb +1 -1
  5. data/lib/logstash/api/commands/hot_threads_reporter.rb +4 -7
  6. data/lib/logstash/api/commands/node.rb +5 -4
  7. data/lib/logstash/api/commands/stats.rb +8 -3
  8. data/lib/logstash/api/modules/base.rb +5 -0
  9. data/lib/logstash/api/modules/node.rb +1 -2
  10. data/lib/logstash/api/modules/node_stats.rb +1 -2
  11. data/lib/logstash/codecs/base.rb +29 -1
  12. data/lib/logstash/config/mixin.rb +1 -1
  13. data/lib/logstash/environment.rb +5 -5
  14. data/lib/logstash/filter_delegator.rb +4 -5
  15. data/lib/logstash/instrument/periodic_poller/jvm.rb +43 -10
  16. data/lib/logstash/output_delegator.rb +33 -168
  17. data/lib/logstash/output_delegator_strategies/legacy.rb +29 -0
  18. data/lib/logstash/output_delegator_strategies/shared.rb +20 -0
  19. data/lib/logstash/output_delegator_strategies/single.rb +23 -0
  20. data/lib/logstash/output_delegator_strategy_registry.rb +36 -0
  21. data/lib/logstash/outputs/base.rb +39 -26
  22. data/lib/logstash/patches/clamp.rb +6 -0
  23. data/lib/logstash/pipeline.rb +42 -14
  24. data/lib/logstash/pipeline_reporter.rb +2 -8
  25. data/lib/logstash/plugin.rb +6 -10
  26. data/lib/logstash/runner.rb +12 -9
  27. data/lib/logstash/settings.rb +124 -21
  28. data/lib/logstash/util/wrapped_synchronous_queue.rb +17 -1
  29. data/lib/logstash/version.rb +1 -1
  30. data/lib/logstash/webserver.rb +44 -33
  31. data/locales/en.yml +5 -1
  32. data/logstash-core.gemspec +2 -2
  33. data/spec/api/lib/api/node_spec.rb +62 -10
  34. data/spec/api/lib/api/node_stats_spec.rb +16 -3
  35. data/spec/api/lib/api/support/resource_dsl_methods.rb +11 -1
  36. data/spec/api/spec_helper.rb +1 -1
  37. data/spec/conditionals_spec.rb +12 -1
  38. data/spec/logstash/agent_spec.rb +3 -0
  39. data/spec/logstash/codecs/base_spec.rb +74 -0
  40. data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +37 -10
  41. data/spec/logstash/output_delegator_spec.rb +64 -89
  42. data/spec/logstash/outputs/base_spec.rb +91 -15
  43. data/spec/logstash/pipeline_reporter_spec.rb +1 -6
  44. data/spec/logstash/pipeline_spec.rb +20 -22
  45. data/spec/logstash/plugin_spec.rb +3 -3
  46. data/spec/logstash/runner_spec.rb +86 -3
  47. data/spec/logstash/settings/integer_spec.rb +20 -0
  48. data/spec/logstash/settings/numeric_spec.rb +28 -0
  49. data/spec/logstash/settings/port_range_spec.rb +93 -0
  50. data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +6 -0
  51. data/spec/logstash/webserver_spec.rb +95 -0
  52. metadata +20 -6
@@ -16,6 +16,18 @@ describe LogStash::Api::Modules::NodeStats do
16
16
  "count"=>Numeric,
17
17
  "peak_count"=>Numeric
18
18
  },
19
+ "gc" => {
20
+ "collectors" => {
21
+ "young" => {
22
+ "collection_count" => Numeric,
23
+ "collection_time_in_millis" => Numeric
24
+ },
25
+ "old" => {
26
+ "collection_count" => Numeric,
27
+ "collection_time_in_millis" => Numeric
28
+ }
29
+ }
30
+ },
19
31
  "mem" => {
20
32
  "heap_used_in_bytes" => Numeric,
21
33
  "heap_used_percent" => Numeric,
@@ -59,12 +71,13 @@ describe LogStash::Api::Modules::NodeStats do
59
71
  },
60
72
  "pipeline" => {
61
73
  "events" => {
74
+ "duration_in_millis" => Numeric,
62
75
  "in" => Numeric,
63
76
  "filtered" => Numeric,
64
77
  "out" => Numeric
65
- }
66
- }
78
+ }
79
+ }
67
80
  }
68
-
81
+
69
82
  test_api_and_resources(root_structure)
70
83
  end
@@ -1,3 +1,13 @@
1
+ # Ruby doesn't have common class for boolean,
2
+ # And to simplify the ResourceDSLMethods check it make sense to have it.
3
+ module Boolean; end
4
+ class TrueClass
5
+ include Boolean
6
+ end
7
+ class FalseClass
8
+ include Boolean
9
+ end
10
+
1
11
  module ResourceDSLMethods
2
12
  # Convert a nested hash to a mapping of key paths to expected classes
3
13
  def hash_to_mapping(h, path=[], mapping={})
@@ -35,7 +45,7 @@ module ResourceDSLMethods
35
45
  end
36
46
 
37
47
  it "should include the http address" do
38
- expect(payload["http_address"]).to eql("#{Socket.gethostname}:#{::LogStash::WebServer::DEFAULT_PORT}")
48
+ expect(payload["http_address"]).to eql("#{Socket.gethostname}:#{::LogStash::WebServer::DEFAULT_PORTS.first}")
39
49
  end
40
50
  end
41
51
 
@@ -19,7 +19,7 @@ end
19
19
  module LogStash
20
20
  class DummyAgent < Agent
21
21
  def start_webserver
22
- @webserver = Struct.new(:address).new("#{Socket.gethostname}:#{::LogStash::WebServer::DEFAULT_PORT}")
22
+ @webserver = Struct.new(:address).new("#{Socket.gethostname}:#{::LogStash::WebServer::DEFAULT_PORTS.first}")
23
23
  end
24
24
  def stop_webserver; end
25
25
  end
@@ -25,6 +25,17 @@ end
25
25
  describe "conditionals in output" do
26
26
  extend ConditionalFanciness
27
27
 
28
+ class DummyNullOutput < LogStash::Outputs::Base
29
+ def register
30
+ end
31
+ def multi_receive(events)
32
+ end
33
+ end
34
+
35
+ before do
36
+ LogStash::Registry.instance.register("logstash/outputs/dummynull", DummyNullOutput)
37
+ end
38
+
28
39
  describe "simple" do
29
40
  config <<-CONFIG
30
41
  input {
@@ -35,7 +46,7 @@ describe "conditionals in output" do
35
46
  }
36
47
  output {
37
48
  if [foo] == "bar" {
38
- stdout { }
49
+ dummynull { }
39
50
  }
40
51
  }
41
52
  CONFIG
@@ -392,7 +392,10 @@ describe LogStash::Agent do
392
392
 
393
393
  it "resets the metric collector" do
394
394
  # We know that the store has more events coming in.
395
+ i = 0
395
396
  while dummy_output.events.size <= new_config_generator_counter
397
+ i += 1
398
+ raise "Waiting too long!" if i > 20
396
399
  sleep(0.1)
397
400
  end
398
401
 
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ DATA_DOUBLE = "data".freeze
5
+
6
+ # use a dummy NOOP output to test Outputs::Base
7
+ class LogStash::Codecs::NOOPAsync < LogStash::Codecs::Base
8
+ attr_reader :last_result
9
+ config_name "noop_async"
10
+
11
+ def encode(event)
12
+ @last_result = @on_event.call(event, DATA_DOUBLE)
13
+ end
14
+ end
15
+
16
+ class LogStash::Codecs::NOOPSync < LogStash::Codecs::Base
17
+ attr_reader :last_result
18
+ config_name "noop_sync"
19
+
20
+ def encode_sync(event)
21
+ DATA_DOUBLE
22
+ end
23
+ end
24
+
25
+ class LogStash::Codecs::NOOPMulti < LogStash::Codecs::Base
26
+ attr_reader :last_result
27
+ config_name "noop_multi"
28
+
29
+ def encode_sync(event)
30
+ DATA_DOUBLE
31
+ end
32
+ end
33
+
34
+ describe LogStash::Codecs::Base do
35
+ let(:params) { {} }
36
+ subject(:instance) { klass.new(params.dup) }
37
+ let(:event) { double("event") }
38
+ let(:encoded_data) { DATA_DOUBLE }
39
+ let(:encoded_tuple) { [event, encoded_data] }
40
+
41
+ describe "encoding" do
42
+ shared_examples "encoder types" do |codec_class|
43
+ let(:klass) { codec_class }
44
+
45
+ describe "#{codec_class}" do
46
+ describe "multi_encode" do
47
+ it "should return an array of [event,data] tuples" do
48
+ expect(instance.multi_encode([event,event])).to eq([encoded_tuple, encoded_tuple])
49
+ end
50
+ end
51
+
52
+ describe "#encode" do
53
+ before do
54
+ @result = nil
55
+ instance.on_event do |event, data|
56
+ @result = [event, data]
57
+ end
58
+ instance.encode(event)
59
+ end
60
+
61
+ it "should yield the correct result" do
62
+ expect(@result).to eq(encoded_tuple)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ include_examples("encoder types", LogStash::Codecs::NOOPAsync)
69
+ include_examples("encoder types", LogStash::Codecs::NOOPSync)
70
+ include_examples("encoder types", LogStash::Codecs::NOOPMulti)
71
+ end
72
+ end
73
+
74
+
@@ -3,18 +3,41 @@ require "spec_helper"
3
3
  require "logstash/instrument/periodic_poller/jvm"
4
4
  require "logstash/instrument/collector"
5
5
 
6
+ describe LogStash::Instrument::PeriodicPoller::JVM::GarbageCollectorName do
7
+ subject { LogStash::Instrument::PeriodicPoller::JVM::GarbageCollectorName }
8
+
9
+ context "when the gc is of young type" do
10
+ LogStash::Instrument::PeriodicPoller::JVM::GarbageCollectorName::YOUNG_GC_NAMES.each do |name|
11
+ it "returns young for #{name}" do
12
+ expect(subject.get(name)).to eq(:young)
13
+ end
14
+ end
15
+ end
16
+
17
+ context "when the gc is of old type" do
18
+ LogStash::Instrument::PeriodicPoller::JVM::GarbageCollectorName::OLD_GC_NAMES.each do |name|
19
+ it "returns old for #{name}" do
20
+ expect(subject.get(name)).to eq(:old)
21
+ end
22
+ end
23
+ end
24
+
25
+ it "returns `nil` when we dont know the gc name" do
26
+ expect(subject.get("UNKNOWN GC")).to be_nil
27
+ end
28
+ end
29
+
6
30
  describe LogStash::Instrument::PeriodicPoller::JVM do
7
31
  let(:metric) { LogStash::Instrument::Metric.new(LogStash::Instrument::Collector.new) }
8
32
  let(:options) { {} }
9
33
  subject(:jvm) { described_class.new(metric, options) }
10
-
34
+
11
35
  it "should initialize cleanly" do
12
36
  expect { jvm }.not_to raise_error
13
37
  end
14
38
 
15
39
  describe "collections" do
16
40
  subject(:collection) { jvm.collect }
17
-
18
41
  it "should run cleanly" do
19
42
  expect { collection }.not_to raise_error
20
43
  end
@@ -22,21 +45,25 @@ describe LogStash::Instrument::PeriodicPoller::JVM do
22
45
  describe "metrics" do
23
46
  before(:each) { jvm.collect }
24
47
  let(:snapshot_store) { metric.collector.snapshot_metric.metric_store }
25
- subject(:jvm_metrics) { snapshot_store.get_shallow(:jvm, :process) }
48
+ subject(:jvm_metrics) { snapshot_store.get_shallow(:jvm) }
26
49
 
27
50
  # Make looking up metric paths easy when given varargs of keys
28
51
  # e.g. mval(:parent, :child)
29
52
  def mval(*metric_path)
30
53
  metric_path.reduce(jvm_metrics) {|acc,k| acc[k]}.value
31
- end
54
+ end
32
55
 
33
56
  [
34
- :max_file_descriptors,
35
- :open_file_descriptors,
36
- :peak_open_file_descriptors,
37
- [:mem, :total_virtual_in_bytes],
38
- [:cpu, :total_in_millis],
39
- [:cpu, :percent]
57
+ [:process, :max_file_descriptors],
58
+ [:process, :open_file_descriptors],
59
+ [:process, :peak_open_file_descriptors],
60
+ [:process, :mem, :total_virtual_in_bytes],
61
+ [:process, :cpu, :total_in_millis],
62
+ [:process, :cpu, :percent],
63
+ [:gc, :collectors, :young, :collection_count],
64
+ [:gc, :collectors, :young, :collection_time_in_millis],
65
+ [:gc, :collectors, :old, :collection_count],
66
+ [:gc, :collectors, :old, :collection_time_in_millis]
40
67
  ].each do |path|
41
68
  path = Array(path)
42
69
  it "should have a value for #{path} that is Numeric" do
@@ -5,26 +5,26 @@ require 'spec_helper'
5
5
  describe LogStash::OutputDelegator do
6
6
  let(:logger) { double("logger") }
7
7
  let(:events) { 7.times.map { LogStash::Event.new }}
8
- let(:default_worker_count) { 1 }
8
+ let(:plugin_args) { {"id" => "foo", "arg1" => "val1"} }
9
9
 
10
- subject { described_class.new(logger, out_klass, default_worker_count, LogStash::Instrument::NullMetric.new) }
10
+ subject { described_class.new(logger, out_klass, LogStash::Instrument::NullMetric.new, ::LogStash::OutputDelegatorStrategyRegistry.instance, plugin_args) }
11
11
 
12
12
  context "with a plain output plugin" do
13
13
  let(:out_klass) { double("output klass") }
14
14
  let(:out_inst) { double("output instance") }
15
-
15
+ let(:concurrency) { :single }
16
16
 
17
17
  before(:each) do
18
18
  allow(out_klass).to receive(:new).with(any_args).and_return(out_inst)
19
- allow(out_klass).to receive(:threadsafe?).and_return(false)
20
- allow(out_klass).to receive(:workers_not_supported?).and_return(false)
21
19
  allow(out_klass).to receive(:name).and_return("example")
20
+ allow(out_klass).to receive(:concurrency).with(any_args).and_return concurrency
22
21
  allow(out_klass).to receive(:config_name)
23
22
  allow(out_inst).to receive(:register)
24
23
  allow(out_inst).to receive(:multi_receive)
25
24
  allow(out_inst).to receive(:metric=).with(any_args)
26
25
  allow(out_inst).to receive(:id).and_return("a-simple-plugin")
27
- allow(out_inst).to receive(:plugin_unique_name).and_return("hello-123")
26
+
27
+ allow(subject.metric_events).to receive(:increment).with(any_args)
28
28
  allow(logger).to receive(:debug).with(any_args)
29
29
  end
30
30
 
@@ -43,109 +43,84 @@ describe LogStash::OutputDelegator do
43
43
  end
44
44
 
45
45
  it "should increment the number of events received" do
46
- expect(subject.events_received).to eql(events.length)
46
+ expect(subject.metric_events).to have_received(:increment).with(:in, events.length)
47
+ expect(subject.metric_events).to have_received(:increment).with(:out, events.length)
47
48
  end
48
49
  end
49
50
 
50
-
51
51
  describe "closing" do
52
52
  before do
53
53
  subject.register
54
54
  end
55
55
 
56
- it "should register all workers on register" do
56
+ it "should register the output plugin instance on register" do
57
57
  expect(out_inst).to have_received(:register)
58
58
  end
59
59
 
60
- it "should close all workers when closing" do
60
+ it "should close the output plugin instance when closing" do
61
61
  expect(out_inst).to receive(:do_close)
62
62
  subject.do_close
63
63
  end
64
64
  end
65
65
 
66
- describe "concurrency and worker support" do
67
- before do
68
- allow(out_inst).to receive(:id).and_return("a-simple-plugin")
69
- allow(out_inst).to receive(:metric=).with(any_args)
70
- allow(out_klass).to receive(:workers_not_supported?).and_return(false)
71
- end
72
-
73
- describe "non-threadsafe outputs that allow workers" do
74
- let(:default_worker_count) { 3 }
75
-
76
- before do
77
- allow(out_klass).to receive(:threadsafe?).and_return(false)
78
- subject.register
79
- end
80
-
81
- it "should instantiate multiple workers" do
82
- expect(subject.workers.length).to eql(default_worker_count)
83
- end
84
-
85
- it "should send received events to the worker" do
86
- expect(out_inst).to receive(:multi_receive).with(events)
87
- subject.multi_receive(events)
88
- end
66
+ describe "concurrency strategies" do
67
+ it "should have :single as the default" do
68
+ expect(subject.concurrency).to eq :single
89
69
  end
90
70
 
91
- describe "threadsafe outputs" do
92
- before do
93
- allow(out_klass).to receive(:threadsafe?).and_return(true)
94
- subject.register
95
- end
96
-
97
- it "should return true when threadsafe? is invoked" do
98
- expect(subject.threadsafe?).to eql(true)
99
- end
100
-
101
- it "should define a threadsafe_worker" do
102
- expect(subject.send(:threadsafe_worker)).to eql(out_inst)
103
- end
104
-
105
- it "should utilize threadsafe_multi_receive" do
106
- expect(subject.send(:threadsafe_worker)).to receive(:multi_receive).with(events)
107
- subject.multi_receive(events)
108
- end
109
-
110
- it "should not utilize the worker queue" do
111
- expect(subject.send(:worker_queue)).to be_nil
112
- end
113
-
114
- it "should send received events to the worker" do
115
- expect(out_inst).to receive(:multi_receive).with(events)
116
- subject.multi_receive(events)
117
- end
118
-
119
- it "should close all workers when closing" do
120
- expect(out_inst).to receive(:do_close)
121
- subject.do_close
71
+ [
72
+ [:shared, ::LogStash::OutputDelegatorStrategies::Shared],
73
+ [:single, ::LogStash::OutputDelegatorStrategies::Single],
74
+ [:legacy, ::LogStash::OutputDelegatorStrategies::Legacy],
75
+ ].each do |strategy_concurrency,klass|
76
+ context "with strategy #{strategy_concurrency}" do
77
+ let(:concurrency) { strategy_concurrency }
78
+
79
+ it "should find the correct concurrency type for the output" do
80
+ expect(subject.concurrency).to eq(strategy_concurrency)
81
+ end
82
+
83
+ it "should find the correct Strategy class for the worker" do
84
+ expect(subject.strategy).to be_a(klass)
85
+ end
86
+
87
+ it "should set the correct parameters on the instance" do
88
+ expect(out_klass).to have_received(:new).with(plugin_args)
89
+ end
90
+
91
+ [[:register], [:do_close], [:multi_receive, [[]] ] ].each do |method, args|
92
+ context "strategy objects" do
93
+ before do
94
+ allow(subject.strategy).to receive(method)
95
+ end
96
+
97
+ it "should delegate #{method} to the strategy" do
98
+ subject.send(method, *args)
99
+ if args
100
+ expect(subject.strategy).to have_received(method).with(*args)
101
+ else
102
+ expect(subject.strategy).to have_received(method).with(no_args)
103
+ end
104
+ end
105
+ end
106
+
107
+ context "strategy output instances" do
108
+ before do
109
+ allow(out_inst).to receive(method)
110
+ end
111
+
112
+ it "should delegate #{method} to the strategy" do
113
+ subject.send(method, *args)
114
+ if args
115
+ expect(out_inst).to have_received(method).with(*args)
116
+ else
117
+ expect(out_inst).to have_received(method).with(no_args)
118
+ end
119
+ end
120
+ end
121
+ end
122
122
  end
123
123
  end
124
124
  end
125
125
  end
126
-
127
- # This may seem suspiciously similar to the class in outputs/base_spec
128
- # but, in fact, we need a whole new class because using this even once
129
- # will immutably modify the base class
130
- class LogStash::Outputs::NOOPDelLegacyNoWorkers < ::LogStash::Outputs::Base
131
- LEGACY_WORKERS_NOT_SUPPORTED_REASON = "legacy reason"
132
-
133
- def register
134
- workers_not_supported(LEGACY_WORKERS_NOT_SUPPORTED_REASON)
135
- end
136
- end
137
-
138
- describe "legacy output workers_not_supported" do
139
- let(:default_worker_count) { 2 }
140
- let(:out_klass) { LogStash::Outputs::NOOPDelLegacyNoWorkers }
141
-
142
- before(:each) do
143
- allow(logger).to receive(:debug).with(any_args)
144
- end
145
-
146
- it "should only setup one worker" do
147
- subject.register
148
- expect(subject.worker_count).to eql(1)
149
- end
150
- end
151
126
  end