logstash-core 2.4.1-java → 5.0.0.alpha1-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 +124 -411
- data/lib/logstash/api/init.ru +31 -0
- data/lib/logstash/api/lib/app.rb +40 -0
- data/lib/logstash/api/lib/app/command.rb +29 -0
- data/lib/logstash/api/lib/app/command_factory.rb +29 -0
- data/lib/logstash/api/lib/app/commands/stats/events_command.rb +13 -0
- data/lib/logstash/api/lib/app/commands/stats/hotthreads_command.rb +120 -0
- data/lib/logstash/api/lib/app/commands/stats/memory_command.rb +25 -0
- data/lib/logstash/api/lib/app/commands/system/basicinfo_command.rb +15 -0
- data/lib/logstash/api/lib/app/commands/system/plugins_command.rb +28 -0
- data/lib/logstash/api/lib/app/modules/node.rb +25 -0
- data/lib/logstash/api/lib/app/modules/node_stats.rb +51 -0
- data/lib/logstash/api/lib/app/modules/plugins.rb +15 -0
- data/lib/logstash/api/lib/app/modules/stats.rb +21 -0
- data/lib/logstash/api/lib/app/root.rb +13 -0
- data/lib/logstash/api/lib/app/service.rb +61 -0
- data/lib/logstash/api/lib/app/stats.rb +56 -0
- data/lib/logstash/api/lib/helpers/app_helpers.rb +23 -0
- data/lib/logstash/codecs/base.rb +1 -29
- data/lib/logstash/config/config_ast.rb +18 -31
- data/lib/logstash/config/loader.rb +3 -5
- data/lib/logstash/config/mixin.rb +25 -64
- data/lib/logstash/filter_delegator.rb +65 -0
- data/lib/logstash/inputs/base.rb +1 -1
- data/lib/logstash/inputs/metrics.rb +47 -0
- data/lib/logstash/instrument/collector.rb +109 -0
- data/lib/logstash/instrument/metric.rb +102 -0
- data/lib/logstash/instrument/metric_store.rb +228 -0
- data/lib/logstash/instrument/metric_type.rb +24 -0
- data/lib/logstash/instrument/metric_type/base.rb +35 -0
- data/lib/logstash/instrument/metric_type/counter.rb +29 -0
- data/lib/logstash/instrument/metric_type/gauge.rb +22 -0
- data/lib/logstash/instrument/metric_type/mean.rb +33 -0
- data/lib/logstash/instrument/namespaced_metric.rb +54 -0
- data/lib/logstash/instrument/null_metric.rb +4 -3
- data/lib/logstash/instrument/periodic_poller/base.rb +57 -0
- data/lib/logstash/instrument/periodic_poller/jvm.rb +92 -0
- data/lib/logstash/instrument/periodic_poller/os.rb +13 -0
- data/lib/logstash/instrument/periodic_poller/periodic_poller_observer.rb +19 -0
- data/lib/logstash/instrument/periodic_pollers.rb +26 -0
- data/lib/logstash/instrument/snapshot.rb +16 -0
- data/lib/logstash/json.rb +2 -3
- data/lib/logstash/namespace.rb +1 -0
- data/lib/logstash/output_delegator.rb +16 -3
- data/lib/logstash/outputs/base.rb +1 -32
- data/lib/logstash/pipeline.rb +67 -8
- data/lib/logstash/plugin.rb +57 -19
- data/lib/logstash/runner.rb +348 -84
- data/lib/logstash/util.rb +9 -0
- data/lib/logstash/util/duration_formatter.rb +15 -0
- data/lib/logstash/util/java_version.rb +2 -4
- data/lib/logstash/util/loggable.rb +29 -0
- data/lib/logstash/version.rb +1 -1
- data/lib/logstash/webserver.rb +98 -0
- data/locales/en.yml +42 -24
- data/logstash-core.gemspec +9 -6
- data/spec/api/lib/api/node_spec.rb +64 -0
- data/spec/api/lib/api/node_stats_spec.rb +68 -0
- data/spec/api/lib/api/plugins_spec.rb +57 -0
- data/spec/api/lib/api/root_spec.rb +20 -0
- data/spec/api/lib/api/stats_spec.rb +19 -0
- data/spec/api/lib/commands/events_spec.rb +17 -0
- data/spec/api/lib/commands/jvm_spec.rb +45 -0
- data/spec/api/spec_helper.rb +128 -0
- data/spec/logstash/agent_spec.rb +62 -169
- data/spec/logstash/config/config_ast_spec.rb +2 -47
- data/spec/logstash/config/mixin_spec.rb +0 -157
- data/spec/logstash/filter_delegator_spec.rb +143 -0
- data/spec/logstash/inputs/metrics_spec.rb +52 -0
- data/spec/logstash/instrument/collector_spec.rb +49 -0
- data/spec/logstash/instrument/metric_spec.rb +110 -0
- data/spec/logstash/instrument/metric_store_spec.rb +163 -0
- data/spec/logstash/instrument/metric_type/counter_spec.rb +40 -0
- data/spec/logstash/instrument/metric_type/gauge_spec.rb +40 -0
- data/spec/logstash/instrument/namespaced_metric_spec.rb +25 -0
- data/spec/logstash/instrument/null_metric_spec.rb +9 -51
- data/spec/logstash/json_spec.rb +14 -0
- data/spec/logstash/output_delegator_spec.rb +6 -3
- data/spec/logstash/outputs/base_spec.rb +0 -107
- data/spec/logstash/pipeline_spec.rb +204 -33
- data/spec/logstash/plugin_spec.rb +80 -15
- data/spec/logstash/runner_spec.rb +134 -38
- data/spec/logstash/shutdown_watcher_spec.rb +0 -1
- data/spec/logstash/util/duration_formatter_spec.rb +11 -0
- data/spec/logstash/util/java_version_spec.rb +10 -2
- data/spec/logstash/util_spec.rb +28 -0
- data/spec/support/matchers.rb +30 -0
- metadata +154 -20
- data/lib/logstash/logging/json.rb +0 -21
- data/lib/logstash/special_agent.rb +0 -8
- data/lib/logstash/util/safe_uri.rb +0 -50
- data/spec/logstash/codecs/base_spec.rb +0 -74
- data/spec/static/i18n_spec.rb +0 -25
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "../../spec_helper"
|
3
|
+
require "sinatra"
|
4
|
+
require "app/modules/plugins"
|
5
|
+
require "logstash/json"
|
6
|
+
|
7
|
+
describe LogStash::Api::Plugins do
|
8
|
+
|
9
|
+
include Rack::Test::Methods
|
10
|
+
|
11
|
+
def app()
|
12
|
+
described_class
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:all) do
|
16
|
+
get "/"
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:payload) { LogStash::Json.load(last_response.body) }
|
20
|
+
|
21
|
+
it "respond to plugins resource" do
|
22
|
+
expect(last_response).to be_ok
|
23
|
+
end
|
24
|
+
|
25
|
+
it "return valid json content type" do
|
26
|
+
expect(last_response.content_type).to eq("application/json")
|
27
|
+
end
|
28
|
+
|
29
|
+
context "#schema" do
|
30
|
+
it "return the expected schema" do
|
31
|
+
expect(payload.keys).to include("plugins", "total")
|
32
|
+
payload["plugins"].each do |plugin|
|
33
|
+
expect(plugin.keys).to include("name", "version")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "#values" do
|
39
|
+
|
40
|
+
it "return totals of plugins" do
|
41
|
+
expect(payload["total"]).to eq(payload["plugins"].count)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "return a list of available plugins" do
|
45
|
+
payload["plugins"].each do |plugin|
|
46
|
+
expect(plugin).to be_available?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it "return non empty version values" do
|
51
|
+
payload["plugins"].each do |plugin|
|
52
|
+
expect(plugin["version"]).not_to be_empty
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "../../spec_helper"
|
3
|
+
require "sinatra"
|
4
|
+
require "app/root"
|
5
|
+
require "logstash/json"
|
6
|
+
|
7
|
+
describe LogStash::Api::Root do
|
8
|
+
|
9
|
+
include Rack::Test::Methods
|
10
|
+
|
11
|
+
def app()
|
12
|
+
described_class
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should respond to root resource" do
|
16
|
+
do_request { get "/" }
|
17
|
+
expect(last_response).to be_ok
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "../../spec_helper"
|
3
|
+
require "sinatra"
|
4
|
+
require "app/modules/stats"
|
5
|
+
|
6
|
+
describe LogStash::Api::Stats do
|
7
|
+
|
8
|
+
include Rack::Test::Methods
|
9
|
+
|
10
|
+
def app()
|
11
|
+
described_class
|
12
|
+
end
|
13
|
+
|
14
|
+
it "respond to the jvm resource" do
|
15
|
+
do_request { get "/jvm" }
|
16
|
+
expect(last_response).to be_ok
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "../../spec_helper"
|
3
|
+
require "app/commands/stats/events_command"
|
4
|
+
|
5
|
+
describe LogStash::Api::StatsEventsCommand do
|
6
|
+
|
7
|
+
context "#schema" do
|
8
|
+
|
9
|
+
let(:report) do
|
10
|
+
do_request { subject.run }
|
11
|
+
end
|
12
|
+
|
13
|
+
it "return events information" do
|
14
|
+
expect(report).to include("in", "filtered", "out")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative "../../spec_helper"
|
3
|
+
require "app/commands/stats/hotthreads_command"
|
4
|
+
require "app/commands/stats/memory_command"
|
5
|
+
|
6
|
+
describe "JVM stats" do
|
7
|
+
|
8
|
+
describe LogStash::Api::HotThreadsCommand do
|
9
|
+
|
10
|
+
let(:report) do
|
11
|
+
do_request { subject.run }
|
12
|
+
end
|
13
|
+
|
14
|
+
context "#schema" do
|
15
|
+
it "return hot threads information" do
|
16
|
+
report = do_request { subject.run }
|
17
|
+
expect(report.to_s).not_to be_empty
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe LogStash::Api::JvmMemoryCommand do
|
24
|
+
|
25
|
+
context "#schema" do
|
26
|
+
|
27
|
+
let(:report) do
|
28
|
+
do_request { subject.run }
|
29
|
+
end
|
30
|
+
|
31
|
+
it "return hot threads information" do
|
32
|
+
expect(report).not_to be_empty
|
33
|
+
end
|
34
|
+
|
35
|
+
it "return heap information" do
|
36
|
+
expect(report.keys).to include(:heap_used_in_bytes)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "return non heap information" do
|
40
|
+
expect(report.keys).to include(:non_heap_used_in_bytes)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
API_ROOT = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib", "logstash", "api"))
|
3
|
+
|
4
|
+
require "logstash/devutils/rspec/spec_helper"
|
5
|
+
|
6
|
+
require 'rack/test'
|
7
|
+
require 'rspec'
|
8
|
+
require "json"
|
9
|
+
|
10
|
+
ENV['RACK_ENV'] = 'test'
|
11
|
+
|
12
|
+
Rack::Builder.parse_file(File.join(API_ROOT, 'init.ru'))
|
13
|
+
|
14
|
+
def read_fixture(name)
|
15
|
+
path = File.join(File.dirname(__FILE__), "fixtures", name)
|
16
|
+
File.read(path)
|
17
|
+
end
|
18
|
+
|
19
|
+
module LogStash
|
20
|
+
class DummyAgent < Agent
|
21
|
+
def fetch_config(settings)
|
22
|
+
"input { generator {count => 0} } output { }"
|
23
|
+
end
|
24
|
+
|
25
|
+
def start_webserver; end
|
26
|
+
def stop_webserver; end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Class used to wrap and manage the execution of an agent for test,
|
32
|
+
# this helps a lot in order to have a more integrated test for the
|
33
|
+
# web api, could be also used for other use cases if generalized enought
|
34
|
+
##
|
35
|
+
class LogStashRunner
|
36
|
+
|
37
|
+
attr_reader :config_str, :agent, :pipeline_settings
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
args = [
|
41
|
+
:logger => Cabin::Channel.get(LogStash),
|
42
|
+
:auto_reload => false,
|
43
|
+
:collect_metric => true,
|
44
|
+
:debug => false,
|
45
|
+
:node_name => "test_agent",
|
46
|
+
:web_api_http_port => rand(9600..9700)
|
47
|
+
]
|
48
|
+
|
49
|
+
@config_str = "input { generator {count => 0} } output { }"
|
50
|
+
@agent = LogStash::DummyAgent.new(*args)
|
51
|
+
@pipeline_settings ||= { :pipeline_id => "main",
|
52
|
+
:config_str => config_str,
|
53
|
+
:pipeline_batch_size => 1,
|
54
|
+
:flush_interval => 1,
|
55
|
+
:pipeline_workers => 1 }
|
56
|
+
end
|
57
|
+
|
58
|
+
def start
|
59
|
+
agent.register_pipeline("main", pipeline_settings)
|
60
|
+
@runner = Thread.new(agent) do |_agent|
|
61
|
+
_agent.execute
|
62
|
+
end
|
63
|
+
wait_until_snapshot_received
|
64
|
+
end
|
65
|
+
|
66
|
+
def stop
|
67
|
+
agent.shutdown
|
68
|
+
Thread.kill(@runner)
|
69
|
+
sleep 0.1 while !@runner.stop?
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def wait_until_snapshot_received
|
75
|
+
while !LogStash::Api::Service.instance.started? do
|
76
|
+
sleep 0.5
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
##
|
83
|
+
# Method used to wrap up a request in between of a running
|
84
|
+
# pipeline, this makes the hole execution model easier and
|
85
|
+
# more contained as some threads might go wild.
|
86
|
+
##
|
87
|
+
def do_request(&block)
|
88
|
+
runner = LogStashRunner.new
|
89
|
+
runner.start
|
90
|
+
ret_val = block.call
|
91
|
+
runner.stop
|
92
|
+
ret_val
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Helper module that setups necessary mocks when doing the requests,
|
97
|
+
# this could be just included in the test and the runner will be
|
98
|
+
# started managed for all tests.
|
99
|
+
##
|
100
|
+
module LogStash; module RSpec; module RunnerConfig
|
101
|
+
def self.included(klass)
|
102
|
+
klass.before(:all) do
|
103
|
+
LogStashRunner.instance.start
|
104
|
+
end
|
105
|
+
|
106
|
+
klass.before(:each) do
|
107
|
+
runner = LogStashRunner.instance
|
108
|
+
allow(LogStash::Instrument::Collector.instance).to receive(:agent).and_return(runner.agent)
|
109
|
+
end
|
110
|
+
|
111
|
+
klass.after(:all) do
|
112
|
+
LogStashRunner.instance.stop
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end; end; end
|
116
|
+
|
117
|
+
require 'rspec/expectations'
|
118
|
+
|
119
|
+
RSpec::Matchers.define :be_available? do
|
120
|
+
match do |plugin|
|
121
|
+
begin
|
122
|
+
Gem::Specification.find_by_name(plugin["name"])
|
123
|
+
true
|
124
|
+
rescue
|
125
|
+
false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/spec/logstash/agent_spec.rb
CHANGED
@@ -1,26 +1,20 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'spec_helper'
|
3
3
|
require 'stud/temporary'
|
4
|
-
require 'stud/task'
|
5
4
|
|
6
5
|
describe LogStash::Agent do
|
7
6
|
|
8
7
|
let(:logger) { double("logger") }
|
9
|
-
let(:agent_args) {
|
10
|
-
subject { LogStash::Agent.new(
|
8
|
+
let(:agent_args) { { :logger => logger } }
|
9
|
+
subject { LogStash::Agent.new(agent_args) }
|
11
10
|
|
12
11
|
before :each do
|
13
|
-
[:
|
12
|
+
[:info, :warn, :error, :fatal, :debug].each do |level|
|
14
13
|
allow(logger).to receive(level)
|
15
14
|
end
|
16
15
|
[:info?, :warn?, :error?, :fatal?, :debug?].each do |level|
|
17
16
|
allow(logger).to receive(level)
|
18
17
|
end
|
19
|
-
allow(logger).to receive(:level=)
|
20
|
-
allow(logger).to receive(:subscribe)
|
21
|
-
subject.parse(agent_args)
|
22
|
-
subject.instance_variable_set("@reload_interval", 0.01)
|
23
|
-
subject.instance_variable_set("@logger", logger)
|
24
18
|
end
|
25
19
|
|
26
20
|
describe "register_pipeline" do
|
@@ -31,6 +25,12 @@ describe LogStash::Agent do
|
|
31
25
|
:pipeline_workers => 4
|
32
26
|
} }
|
33
27
|
|
28
|
+
let(:agent_args) { {
|
29
|
+
:logger => logger,
|
30
|
+
:auto_reload => false,
|
31
|
+
:reload_interval => 0.01
|
32
|
+
} }
|
33
|
+
|
34
34
|
it "should delegate settings to new pipeline" do
|
35
35
|
expect(LogStash::Pipeline).to receive(:new).with(settings[:config_string], hash_including(settings))
|
36
36
|
subject.register_pipeline(pipeline_id, settings)
|
@@ -42,7 +42,9 @@ describe LogStash::Agent do
|
|
42
42
|
let(:config_file) { Stud::Temporary.pathname }
|
43
43
|
|
44
44
|
before :each do
|
45
|
-
|
45
|
+
allow(subject).to receive(:start_webserver).and_return(false)
|
46
|
+
allow(subject).to receive(:stop_webserver).and_return(false)
|
47
|
+
File.open(config_file, "w") { |f| f.puts sample_config }
|
46
48
|
end
|
47
49
|
|
48
50
|
after :each do
|
@@ -50,7 +52,7 @@ describe LogStash::Agent do
|
|
50
52
|
end
|
51
53
|
|
52
54
|
context "when auto_reload is false" do
|
53
|
-
let(:agent_args) {
|
55
|
+
let(:agent_args) { { :logger => logger, :auto_reload => false } }
|
54
56
|
let(:pipeline_id) { "main" }
|
55
57
|
let(:pipeline_settings) { { :config_path => config_file } }
|
56
58
|
|
@@ -68,7 +70,6 @@ describe LogStash::Agent do
|
|
68
70
|
it "should not reload_state!" do
|
69
71
|
expect(subject).to_not receive(:reload_state!)
|
70
72
|
t = Thread.new { subject.execute }
|
71
|
-
sleep 0.01 until subject.running_pipelines? && subject.pipelines.values.first.ready?
|
72
73
|
sleep 0.1
|
73
74
|
Stud.stop!(t)
|
74
75
|
t.join
|
@@ -109,7 +110,7 @@ describe LogStash::Agent do
|
|
109
110
|
end
|
110
111
|
|
111
112
|
context "when auto_reload is true" do
|
112
|
-
let(:agent_args) {
|
113
|
+
let(:agent_args) { { :logger => logger, :auto_reload => true, :reload_interval => 0.01 } }
|
113
114
|
let(:pipeline_id) { "main" }
|
114
115
|
let(:pipeline_settings) { { :config_path => config_file } }
|
115
116
|
|
@@ -119,10 +120,10 @@ describe LogStash::Agent do
|
|
119
120
|
|
120
121
|
context "if state is clean" do
|
121
122
|
it "should periodically reload_state" do
|
123
|
+
allow(subject).to receive(:clean_state?).and_return(false)
|
122
124
|
expect(subject).to receive(:reload_state!).at_least(3).times
|
123
|
-
t = Thread.new
|
124
|
-
sleep 0.01 until
|
125
|
-
# now that the pipeline has started, give time for reload_state! to happen a few times
|
125
|
+
t = Thread.new { subject.execute }
|
126
|
+
sleep 0.01 until subject.running_pipelines? && subject.pipelines.values.first.ready?
|
126
127
|
sleep 0.1
|
127
128
|
Stud.stop!(t)
|
128
129
|
t.join
|
@@ -190,6 +191,44 @@ describe LogStash::Agent do
|
|
190
191
|
end
|
191
192
|
end
|
192
193
|
|
194
|
+
describe "Environment Variables In Configs" do
|
195
|
+
let(:agent_args) { {
|
196
|
+
:logger => logger,
|
197
|
+
:auto_reload => false,
|
198
|
+
:reload_interval => 0.01
|
199
|
+
} }
|
200
|
+
let(:pipeline_id) { "main" }
|
201
|
+
let(:pipeline_config) { "input { generator { message => '${FOO}-bar' } } filter { } output { }" }
|
202
|
+
let(:pipeline_settings) { {
|
203
|
+
:config_string => pipeline_config,
|
204
|
+
} }
|
205
|
+
|
206
|
+
context "when allow_env is false" do
|
207
|
+
it "does not interpolate environment variables" do
|
208
|
+
expect(subject).to receive(:fetch_config).and_return(pipeline_config)
|
209
|
+
subject.register_pipeline(pipeline_id, pipeline_settings)
|
210
|
+
expect(subject.pipelines[pipeline_id].inputs.first.message).to eq("${FOO}-bar")
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context "when allow_env is true" do
|
215
|
+
before :each do
|
216
|
+
@foo_content = ENV["FOO"]
|
217
|
+
ENV["FOO"] = "foo"
|
218
|
+
pipeline_settings.merge!(:allow_env => true)
|
219
|
+
end
|
220
|
+
|
221
|
+
after :each do
|
222
|
+
ENV["FOO"] = @foo_content
|
223
|
+
end
|
224
|
+
|
225
|
+
it "doesn't upgrade the state" do
|
226
|
+
expect(subject).to receive(:fetch_config).and_return(pipeline_config)
|
227
|
+
subject.register_pipeline(pipeline_id, pipeline_settings)
|
228
|
+
expect(subject.pipelines[pipeline_id].inputs.first.message).to eq("foo-bar")
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
193
232
|
|
194
233
|
describe "#upgrade_pipeline" do
|
195
234
|
let(:pipeline_id) { "main" }
|
@@ -242,34 +281,11 @@ describe LogStash::Agent do
|
|
242
281
|
end
|
243
282
|
end
|
244
283
|
|
245
|
-
context "--pluginpath" do
|
246
|
-
let(:single_path) { "/some/path" }
|
247
|
-
let(:multiple_paths) { ["/some/path1", "/some/path2"] }
|
248
|
-
|
249
|
-
it "should add single valid dir path to the environment" do
|
250
|
-
expect(File).to receive(:directory?).and_return(true)
|
251
|
-
expect(LogStash::Environment).to receive(:add_plugin_path).with(single_path)
|
252
|
-
subject.configure_plugin_paths(single_path)
|
253
|
-
end
|
254
|
-
|
255
|
-
it "should fail with single invalid dir path" do
|
256
|
-
expect(File).to receive(:directory?).and_return(false)
|
257
|
-
expect(LogStash::Environment).not_to receive(:add_plugin_path)
|
258
|
-
expect{subject.configure_plugin_paths(single_path)}.to raise_error(Clamp::UsageError)
|
259
|
-
end
|
260
|
-
|
261
|
-
it "should add multiple valid dir path to the environment" do
|
262
|
-
expect(File).to receive(:directory?).exactly(multiple_paths.size).times.and_return(true)
|
263
|
-
multiple_paths.each{|path| expect(LogStash::Environment).to receive(:add_plugin_path).with(path)}
|
264
|
-
subject.configure_plugin_paths(multiple_paths)
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
284
|
describe "#fetch_config" do
|
269
285
|
let(:file_config) { "input { generator { count => 100 } } output { }" }
|
270
286
|
let(:cli_config) { "filter { drop { } } " }
|
271
287
|
let(:tmp_config_path) { Stud::Temporary.pathname }
|
272
|
-
let(:agent_args) {
|
288
|
+
let(:agent_args) { { :logger => logger, :config_string => "filter { drop { } } ", :config_path => tmp_config_path } }
|
273
289
|
|
274
290
|
before :each do
|
275
291
|
IO.write(tmp_config_path, file_config)
|
@@ -286,138 +302,15 @@ describe LogStash::Agent do
|
|
286
302
|
end
|
287
303
|
end
|
288
304
|
|
289
|
-
context "
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
it "should fail with single invalid dir path" do
|
294
|
-
expect(File).to receive(:directory?).and_return(false)
|
295
|
-
expect(LogStash::Environment).not_to receive(:add_plugin_path)
|
296
|
-
expect{subject.configure_plugin_paths(single_path)}.to raise_error(Clamp::UsageError)
|
305
|
+
context "#started_at" do
|
306
|
+
it "return the start time when the agent is started" do
|
307
|
+
expect(described_class::STARTED_AT).to be_kind_of(Time)
|
297
308
|
end
|
298
309
|
end
|
299
310
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
context "with a good configuration" do
|
305
|
-
it "should exit successfuly" do
|
306
|
-
expect(subject.run(cli_args)).to eq(0)
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
|
-
context "with a bad configuration" do
|
311
|
-
let(:pipeline_string) { "rlwekjhrewlqrkjh" }
|
312
|
-
it "should fail by returning a bad exit code" do
|
313
|
-
expect(subject.run(cli_args)).to eq(1)
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
it "requests the config loader to format_config" do
|
318
|
-
expect(subject.config_loader).to receive(:format_config)
|
319
|
-
subject.run(cli_args)
|
320
|
-
end
|
321
|
-
end
|
322
|
-
|
323
|
-
describe "pipeline settings" do
|
324
|
-
let(:pipeline_string) { "input { stdin {} } output { stdout {} }" }
|
325
|
-
let(:main_pipeline_settings) { { :pipeline_id => "main" } }
|
326
|
-
let(:pipeline) { double("pipeline") }
|
327
|
-
|
328
|
-
before(:each) do
|
329
|
-
task = Stud::Task.new { 1 }
|
330
|
-
allow(pipeline).to receive(:run).and_return(task)
|
331
|
-
allow(pipeline).to receive(:shutdown)
|
332
|
-
end
|
333
|
-
|
334
|
-
context "when :pipeline_workers is not defined by the user" do
|
335
|
-
it "should not pass the value to the pipeline" do
|
336
|
-
expect(LogStash::Pipeline).to receive(:new).once.with(pipeline_string, hash_excluding(:pipeline_workers)).and_return(pipeline)
|
337
|
-
args = ["-e", pipeline_string]
|
338
|
-
subject.run(args)
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
context "when :pipeline_workers is defined by the user" do
|
343
|
-
it "should pass the value to the pipeline" do
|
344
|
-
main_pipeline_settings[:pipeline_workers] = 2
|
345
|
-
expect(LogStash::Pipeline).to receive(:new).with(pipeline_string, hash_including(main_pipeline_settings)).and_return(pipeline)
|
346
|
-
args = ["-w", "2", "-e", pipeline_string]
|
347
|
-
subject.run(args)
|
348
|
-
end
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
|
-
describe "debug_config" do
|
353
|
-
let(:pipeline_string) { "input {} output {}" }
|
354
|
-
let(:pipeline) { double("pipeline") }
|
355
|
-
|
356
|
-
it "should set 'debug_config' to false by default" do
|
357
|
-
expect(LogStash::Pipeline).to receive(:new).and_return(pipeline)
|
358
|
-
args = ["--debug", "-e", pipeline_string]
|
359
|
-
subject.run(args)
|
360
|
-
|
361
|
-
expect(subject.config_loader.debug_config).to be_falsey
|
362
|
-
end
|
363
|
-
|
364
|
-
it "should allow overriding debug_config" do
|
365
|
-
expect(LogStash::Pipeline).to receive(:new).and_return(pipeline)
|
366
|
-
args = ["--debug", "--debug-config", "-e", pipeline_string]
|
367
|
-
subject.run(args)
|
368
|
-
|
369
|
-
expect(subject.config_loader.debug_config).to be_truthy
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
describe "allow_env param passing to pipeline" do
|
374
|
-
let(:pipeline_string) { "input {} output {}" }
|
375
|
-
let(:pipeline) { double("pipeline") }
|
376
|
-
|
377
|
-
it "should set 'allow_env' to false by default" do
|
378
|
-
args = ["-e", pipeline_string]
|
379
|
-
expect(LogStash::Pipeline).to receive(:new).with(pipeline_string, hash_including(:allow_env => false)).and_return(pipeline)
|
380
|
-
subject.run(args)
|
381
|
-
end
|
382
|
-
|
383
|
-
it "should support templating environment variables" do
|
384
|
-
args = ["-e", pipeline_string, "--allow-env"]
|
385
|
-
expect(LogStash::Pipeline).to receive(:new).with(pipeline_string, hash_including(:allow_env => true)).and_return(pipeline)
|
386
|
-
subject.run(args)
|
387
|
-
end
|
388
|
-
end
|
389
|
-
|
390
|
-
describe "Environment variables in config" do
|
391
|
-
let(:pipeline_id) { "main" }
|
392
|
-
let(:pipeline_config) { "input { generator { message => '${FOO}-bar' } } filter { } output { }" }
|
393
|
-
let(:pipeline_settings) { { :config_string => pipeline_config } }
|
394
|
-
let(:pipeline) { double("pipeline") }
|
395
|
-
|
396
|
-
context "when allow_env is false" do
|
397
|
-
it "does not interpolate environment variables" do
|
398
|
-
expect(subject).to receive(:fetch_config).and_return(pipeline_config)
|
399
|
-
subject.register_pipeline(pipeline_id, pipeline_settings)
|
400
|
-
expect(subject.pipelines[pipeline_id].inputs.first.message).to eq("${FOO}-bar")
|
401
|
-
end
|
402
|
-
end
|
403
|
-
|
404
|
-
context "when allow_env is true" do
|
405
|
-
before :each do
|
406
|
-
@foo_content = ENV["FOO"]
|
407
|
-
ENV["FOO"] = "foo"
|
408
|
-
pipeline_settings.merge!(:allow_env => true)
|
409
|
-
end
|
410
|
-
|
411
|
-
after :each do
|
412
|
-
ENV["FOO"] = @foo_content
|
413
|
-
end
|
414
|
-
|
415
|
-
it "doesn't upgrade the state" do
|
416
|
-
expect(subject).to receive(:fetch_config).and_return(pipeline_config)
|
417
|
-
subject.register_pipeline(pipeline_id, pipeline_settings)
|
418
|
-
expect(subject.pipelines[pipeline_id].inputs.first.message).to eq("foo-bar")
|
419
|
-
end
|
311
|
+
context "#uptime" do
|
312
|
+
it "return the number of milliseconds since start time" do
|
313
|
+
expect(subject.uptime).to be >= 0
|
420
314
|
end
|
421
315
|
end
|
422
316
|
end
|
423
|
-
|