logstash-core 5.0.0.alpha5.snapshot1-java → 5.0.0.alpha6.snapshot1-java
Sign up to get free protection for your applications and to get access to all the features.
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
|