logstash-core 2.4.1-java → 5.0.0.alpha1-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 +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
|
-
|