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.
- checksums.yaml +4 -4
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash/agent.rb +1 -1
- data/lib/logstash/api/commands/default_metadata.rb +1 -1
- data/lib/logstash/api/commands/hot_threads_reporter.rb +4 -7
- data/lib/logstash/api/commands/node.rb +5 -4
- data/lib/logstash/api/commands/stats.rb +8 -3
- data/lib/logstash/api/modules/base.rb +5 -0
- data/lib/logstash/api/modules/node.rb +1 -2
- data/lib/logstash/api/modules/node_stats.rb +1 -2
- data/lib/logstash/codecs/base.rb +29 -1
- data/lib/logstash/config/mixin.rb +1 -1
- data/lib/logstash/environment.rb +5 -5
- data/lib/logstash/filter_delegator.rb +4 -5
- data/lib/logstash/instrument/periodic_poller/jvm.rb +43 -10
- data/lib/logstash/output_delegator.rb +33 -168
- data/lib/logstash/output_delegator_strategies/legacy.rb +29 -0
- data/lib/logstash/output_delegator_strategies/shared.rb +20 -0
- data/lib/logstash/output_delegator_strategies/single.rb +23 -0
- data/lib/logstash/output_delegator_strategy_registry.rb +36 -0
- data/lib/logstash/outputs/base.rb +39 -26
- data/lib/logstash/patches/clamp.rb +6 -0
- data/lib/logstash/pipeline.rb +42 -14
- data/lib/logstash/pipeline_reporter.rb +2 -8
- data/lib/logstash/plugin.rb +6 -10
- data/lib/logstash/runner.rb +12 -9
- data/lib/logstash/settings.rb +124 -21
- data/lib/logstash/util/wrapped_synchronous_queue.rb +17 -1
- data/lib/logstash/version.rb +1 -1
- data/lib/logstash/webserver.rb +44 -33
- data/locales/en.yml +5 -1
- data/logstash-core.gemspec +2 -2
- data/spec/api/lib/api/node_spec.rb +62 -10
- data/spec/api/lib/api/node_stats_spec.rb +16 -3
- data/spec/api/lib/api/support/resource_dsl_methods.rb +11 -1
- data/spec/api/spec_helper.rb +1 -1
- data/spec/conditionals_spec.rb +12 -1
- data/spec/logstash/agent_spec.rb +3 -0
- data/spec/logstash/codecs/base_spec.rb +74 -0
- data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +37 -10
- data/spec/logstash/output_delegator_spec.rb +64 -89
- data/spec/logstash/outputs/base_spec.rb +91 -15
- data/spec/logstash/pipeline_reporter_spec.rb +1 -6
- data/spec/logstash/pipeline_spec.rb +20 -22
- data/spec/logstash/plugin_spec.rb +3 -3
- data/spec/logstash/runner_spec.rb +86 -3
- data/spec/logstash/settings/integer_spec.rb +20 -0
- data/spec/logstash/settings/numeric_spec.rb +28 -0
- data/spec/logstash/settings/port_range_spec.rb +93 -0
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +6 -0
- data/spec/logstash/webserver_spec.rb +95 -0
- 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::
|
48
|
+
expect(payload["http_address"]).to eql("#{Socket.gethostname}:#{::LogStash::WebServer::DEFAULT_PORTS.first}")
|
39
49
|
end
|
40
50
|
end
|
41
51
|
|
data/spec/api/spec_helper.rb
CHANGED
@@ -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::
|
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
|
data/spec/conditionals_spec.rb
CHANGED
@@ -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
|
-
|
49
|
+
dummynull { }
|
39
50
|
}
|
40
51
|
}
|
41
52
|
CONFIG
|
data/spec/logstash/agent_spec.rb
CHANGED
@@ -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
|
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(:
|
8
|
+
let(:plugin_args) { {"id" => "foo", "arg1" => "val1"} }
|
9
9
|
|
10
|
-
subject { described_class.new(logger, out_klass,
|
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
|
-
|
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.
|
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
|
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
|
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
|
67
|
-
|
68
|
-
|
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
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
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
|