logstash-core 6.0.0.alpha1-java → 6.0.0.alpha2-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/lib/logstash-core/logstash-core.jar +0 -0
  3. data/lib/logstash-core/version.rb +1 -1
  4. data/lib/logstash/agent.rb +81 -45
  5. data/lib/logstash/api/commands/hot_threads_reporter.rb +3 -3
  6. data/lib/logstash/api/commands/node.rb +13 -6
  7. data/lib/logstash/api/commands/stats.rb +18 -6
  8. data/lib/logstash/api/modules/node.rb +7 -0
  9. data/lib/logstash/api/modules/node_stats.rb +12 -5
  10. data/lib/logstash/bootstrap_check/default_config.rb +3 -7
  11. data/lib/logstash/compiler.rb +33 -15
  12. data/lib/logstash/compiler/lscl.rb +16 -8
  13. data/lib/logstash/config/mixin.rb +5 -42
  14. data/lib/logstash/config/pipeline_config.rb +1 -1
  15. data/lib/logstash/config/source/local.rb +28 -13
  16. data/lib/logstash/config/source/multi_local.rb +72 -0
  17. data/lib/logstash/config/source_loader.rb +1 -2
  18. data/lib/logstash/environment.rb +12 -3
  19. data/lib/logstash/execution_context.rb +7 -3
  20. data/lib/logstash/inputs/base.rb +2 -0
  21. data/lib/logstash/instrument/metric_type.rb +0 -2
  22. data/lib/logstash/instrument/periodic_poller/jvm.rb +5 -5
  23. data/lib/logstash/instrument/periodic_poller/pq.rb +1 -1
  24. data/lib/logstash/outputs/base.rb +2 -0
  25. data/lib/logstash/pipeline.rb +31 -14
  26. data/lib/logstash/pipeline_action/create.rb +1 -2
  27. data/lib/logstash/pipeline_action/reload.rb +2 -1
  28. data/lib/logstash/pipeline_settings.rb +50 -0
  29. data/lib/logstash/plugin.rb +1 -0
  30. data/lib/logstash/runner.rb +7 -5
  31. data/lib/logstash/settings.rb +11 -3
  32. data/lib/logstash/shutdown_watcher.rb +26 -0
  33. data/lib/logstash/state_resolver.rb +1 -3
  34. data/lib/logstash/util/dead_letter_queue_manager.rb +61 -0
  35. data/lib/logstash/util/environment_variables.rb +43 -0
  36. data/lib/logstash/util/thread_dump.rb +3 -1
  37. data/lib/logstash/version.rb +1 -1
  38. data/locales/en.yml +4 -0
  39. data/logstash-core.gemspec +4 -1
  40. data/spec/logstash/agent/converge_spec.rb +36 -35
  41. data/spec/logstash/agent_spec.rb +48 -177
  42. data/spec/{api/lib/commands/stats.rb → logstash/api/commands/stats_spec.rb} +7 -2
  43. data/spec/{api/lib → logstash/api}/errors_spec.rb +1 -1
  44. data/spec/{api/lib/api → logstash/api/modules}/logging_spec.rb +1 -10
  45. data/spec/{api/lib/api → logstash/api/modules}/node_plugins_spec.rb +1 -2
  46. data/spec/{api/lib/api → logstash/api/modules}/node_spec.rb +9 -8
  47. data/spec/{api/lib/api → logstash/api/modules}/node_stats_spec.rb +11 -9
  48. data/spec/{api/lib/api → logstash/api/modules}/plugins_spec.rb +4 -3
  49. data/spec/{api/lib/api → logstash/api/modules}/root_spec.rb +2 -2
  50. data/spec/{api/lib → logstash/api}/rack_app_spec.rb +0 -0
  51. data/spec/logstash/compiler/compiler_spec.rb +72 -9
  52. data/spec/logstash/config/source/local_spec.rb +20 -4
  53. data/spec/logstash/config/source/multi_local_spec.rb +113 -0
  54. data/spec/logstash/execution_context_spec.rb +14 -4
  55. data/spec/logstash/inputs/base_spec.rb +1 -1
  56. data/spec/logstash/instrument/wrapped_write_client_spec.rb +34 -19
  57. data/spec/logstash/output_delegator_spec.rb +1 -1
  58. data/spec/logstash/outputs/base_spec.rb +1 -1
  59. data/spec/logstash/pipeline_action/reload_spec.rb +1 -1
  60. data/spec/logstash/pipeline_action/stop_spec.rb +1 -1
  61. data/spec/logstash/pipeline_dlq_commit_spec.rb +107 -0
  62. data/spec/logstash/pipeline_pq_file_spec.rb +3 -1
  63. data/spec/logstash/pipeline_reporter_spec.rb +2 -1
  64. data/spec/logstash/pipeline_spec.rb +54 -43
  65. data/spec/logstash/runner_spec.rb +27 -36
  66. data/spec/logstash/settings/array_coercible_spec.rb +65 -0
  67. data/spec/logstash/settings_spec.rb +91 -0
  68. data/spec/logstash/shutdown_watcher_spec.rb +10 -16
  69. data/spec/logstash/state_resolver_spec.rb +6 -4
  70. data/spec/support/helpers.rb +16 -3
  71. data/spec/support/shared_contexts.rb +26 -2
  72. metadata +42 -39
  73. data/lib/logstash/instrument/metric_type/mean.rb +0 -33
  74. data/spec/api/lib/api/support/resource_dsl_methods.rb +0 -87
  75. data/spec/api/spec_helper.rb +0 -106
@@ -43,10 +43,6 @@ describe LogStash::Runner do
43
43
  allow(agent).to receive(:shutdown)
44
44
  end
45
45
 
46
- after :each do
47
- LogStash::SETTINGS.reset
48
- end
49
-
50
46
  describe "argument precedence" do
51
47
  let(:config) { "input {} output {}" }
52
48
  let(:cli_args) { ["-e", config, "-w", "20"] }
@@ -56,10 +52,6 @@ describe LogStash::Runner do
56
52
  allow(LogStash::SETTINGS).to receive(:read_yaml).and_return(settings_yml_hash)
57
53
  end
58
54
 
59
- after :each do
60
- LogStash::SETTINGS.reset
61
- end
62
-
63
55
  it "favors the last occurence of an option" do
64
56
  expect(LogStash::Agent).to receive(:new) do |settings|
65
57
  expect(settings.get("config.string")).to eq(config)
@@ -87,21 +79,6 @@ describe LogStash::Runner do
87
79
  subject.run(args)
88
80
  end
89
81
  end
90
-
91
- context "with no arguments" do
92
- let(:args) { [] }
93
-
94
- before(:each) do
95
- allow(LogStash::Util::JavaVersion).to receive(:warn_on_bad_java_version)
96
- end
97
-
98
- it "should show help" do
99
- expect($stderr).to receive(:puts).once
100
- expect(subject).to receive(:signal_usage_error).once.and_call_original
101
- expect(subject).to receive(:show_short_help).once
102
- subject.run(args)
103
- end
104
- end
105
82
  end
106
83
 
107
84
  context "--pluginpath" do
@@ -130,7 +107,7 @@ describe LogStash::Runner do
130
107
 
131
108
  context "--auto-reload" do
132
109
  subject { LogStash::Runner.new("") }
133
- context "when -f is not given" do
110
+ context "when -e is given" do
134
111
 
135
112
  let(:args) { ["-r", "-e", "input {} output {}"] }
136
113
 
@@ -143,10 +120,6 @@ describe LogStash::Runner do
143
120
  end
144
121
 
145
122
  describe "--config.test_and_exit" do
146
- before do
147
- # Reset the source in a clean state before any asserts
148
- LogStash::Config::SOURCE_LOADER.configure_sources([])
149
- end
150
123
  subject { LogStash::Runner.new("") }
151
124
  let(:args) { ["-t", "-e", pipeline_string] }
152
125
 
@@ -176,38 +149,56 @@ describe LogStash::Runner do
176
149
  allow(pipeline).to receive(:run).and_return(task)
177
150
  allow(pipeline).to receive(:shutdown)
178
151
  end
179
-
152
+
180
153
  context "when :path.data is defined by the user" do
181
154
  let(:test_data_path) { "/tmp/ls-test-data" }
182
155
  let(:test_queue_path) { test_data_path + "/" + "queue" }
183
-
156
+ let(:test_dlq_path) { test_data_path + "/" + "dead_letter_queue" }
157
+
184
158
  it "should set data paths" do
185
159
  expect(LogStash::Agent).to receive(:new) do |settings|
186
160
  expect(settings.get("path.data")).to eq(test_data_path)
187
161
  expect(settings.get("path.queue")).to eq(test_queue_path)
162
+ expect(settings.get("path.dead_letter_queue")).to eq(test_dlq_path)
188
163
  end
189
-
164
+
190
165
  args = ["--path.data", test_data_path, "-e", pipeline_string]
191
166
  subject.run("bin/logstash", args)
192
167
  end
193
-
168
+
194
169
  context "and path.queue is manually set" do
195
170
  let(:queue_override_path) { "/tmp/queue-override_path" }
196
-
171
+
197
172
  it "should set data paths" do
198
173
  expect(LogStash::Agent).to receive(:new) do |settings|
199
174
  expect(settings.get("path.data")).to eq(test_data_path)
200
175
  expect(settings.get("path.queue")).to eq(queue_override_path)
201
176
  end
202
-
177
+
203
178
  LogStash::SETTINGS.set("path.queue", queue_override_path)
204
-
179
+
180
+ args = ["--path.data", test_data_path, "-e", pipeline_string]
181
+ subject.run("bin/logstash", args)
182
+ end
183
+ end
184
+
185
+ context "and path.dead_letter_queue is manually set" do
186
+ let(:queue_override_path) { "/tmp/queue-override_path" }
187
+
188
+ it "should set data paths" do
189
+ expect(LogStash::Agent).to receive(:new) do |settings|
190
+ expect(settings.get("path.data")).to eq(test_data_path)
191
+ expect(settings.get("path.dead_letter_queue")).to eq(queue_override_path)
192
+ end
193
+
194
+ LogStash::SETTINGS.set("path.dead_letter_queue", queue_override_path)
195
+
205
196
  args = ["--path.data", test_data_path, "-e", pipeline_string]
206
197
  subject.run("bin/logstash", args)
207
198
  end
208
199
  end
209
200
  end
210
-
201
+
211
202
  context "when :http.host is defined by the user" do
212
203
  it "should pass the value to the webserver" do
213
204
  expect(LogStash::Agent).to receive(:new) do |settings|
@@ -43,4 +43,69 @@ describe LogStash::Setting::ArrayCoercible do
43
43
  end
44
44
  end
45
45
  end
46
+
47
+ describe "#==" do
48
+ context "when comparing two settings" do
49
+ let(:setting_1) { described_class.new("option_1", element_class_1, value_1) }
50
+ let(:element_class_1) { String }
51
+ let(:setting_2) { described_class.new("option_1", element_class_2, value_2) }
52
+ let(:element_class_2) { String }
53
+
54
+ context "where one was given a non array value" do
55
+ let(:value_1) { "a string" }
56
+ context "and the other also the same non array value" do
57
+ let(:value_2) { "a string" }
58
+ it "should be equal" do
59
+ expect(setting_1).to be == setting_2
60
+ end
61
+ end
62
+ context "and the other also the same value in an array" do
63
+ let(:value_2) { [ "a string" ] }
64
+ it "should be equal" do
65
+ expect(setting_1).to be == setting_2
66
+ end
67
+ end
68
+ context "and the other a different non array value" do
69
+ let(:value_2) { "a different string" }
70
+ it "should be equal" do
71
+ expect(setting_1).to_not be == setting_2
72
+ end
73
+ end
74
+ context "and the other a different value in an array" do
75
+ let(:value_2) { [ "a different string" ] }
76
+ it "should be equal" do
77
+ expect(setting_1).to_not be == setting_2
78
+ end
79
+ end
80
+ end
81
+
82
+ context "where one was given a value in an array" do
83
+ let(:value_1) { [ "a string"] }
84
+ context "and the other the same value in an array" do
85
+ let(:value_2) { [ "a string" ] }
86
+ it "should be equal" do
87
+ expect(setting_1).to be == setting_2
88
+ end
89
+ end
90
+ context "and the other the same value not in an array" do
91
+ let(:value_2) { "a string" }
92
+ it "should be equal" do
93
+ expect(setting_1).to be == setting_2
94
+ end
95
+ end
96
+ context "and the other a different value in an array" do
97
+ let(:value_2) { [ "a different string" ] }
98
+ it "should be equal" do
99
+ expect(setting_1).to_not be == setting_2
100
+ end
101
+ end
102
+ context "and the other a different value in an array" do
103
+ let(:value_2) { "a different string" }
104
+ it "should be equal" do
105
+ expect(setting_1).to_not be == setting_2
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
46
111
  end
@@ -1,5 +1,6 @@
1
1
  # encoding: utf-8
2
2
  require "spec_helper"
3
+ require "logstash/util/environment_variables"
3
4
  require "logstash/settings"
4
5
  require "fileutils"
5
6
 
@@ -146,4 +147,94 @@ describe LogStash::Settings do
146
147
  end
147
148
  end
148
149
  end
150
+
151
+ describe "#from_yaml" do
152
+
153
+ context "env placeholders in flat logstash.yml" do
154
+
155
+ after do
156
+ ENV.delete('SOME_LOGSTASH_SPEC_ENV_VAR')
157
+ ENV.delete('some.logstash.spec.env.var')
158
+ end
159
+
160
+ subject do
161
+ settings = described_class.new
162
+ settings.register(LogStash::Setting::String.new("interpolated", "missing"))
163
+ settings.register(LogStash::Setting::String.new("with_dot", "missing"))
164
+ settings
165
+ end
166
+
167
+ let(:values) {{
168
+ "interpolated" => "${SOME_LOGSTASH_SPEC_ENV_VAR}",
169
+ "with_dot" => "${some.logstash.spec.env.var}"
170
+ }}
171
+ let(:yaml_path) do
172
+ p = Stud::Temporary.pathname
173
+ FileUtils.mkdir_p(p)
174
+
175
+ ::File.open(::File.join(p, "logstash.yml"), "w+") do |f|
176
+ f.write(YAML.dump(values))
177
+ end
178
+ p
179
+ end
180
+
181
+ it "can interpolate environment into settings" do
182
+ expect(subject.get('interpolated')).to eq("missing")
183
+ expect(subject.get('with_dot')).to eq("missing")
184
+ ENV['SOME_LOGSTASH_SPEC_ENV_VAR'] = "correct_setting"
185
+ ENV['some.logstash.spec.env.var'] = "correct_setting_for_dotted"
186
+ subject.from_yaml(yaml_path)
187
+ expect(subject.get('interpolated')).to eq("correct_setting")
188
+ expect(subject.get('with_dot')).to eq("correct_setting_for_dotted")
189
+ end
190
+ end
191
+ end
192
+
193
+ context "env placeholders in nested logstash.yml" do
194
+
195
+ before do
196
+ ENV['lsspecdomain'] = "domain1"
197
+ ENV['lsspecdomain2'] = "domain2"
198
+ end
199
+
200
+ after do
201
+ ENV.delete('lsspecdomain')
202
+ ENV.delete('lsspecdomain2')
203
+ end
204
+
205
+ subject do
206
+ settings = described_class.new
207
+ settings.register(LogStash::Setting::ArrayCoercible.new("host", String, []))
208
+ settings.register(LogStash::Setting::ArrayCoercible.new("modules", Hash, []))
209
+ settings
210
+ end
211
+
212
+ let(:values) {{
213
+ "host" => ["dev1.${lsspecdomain}", "dev2.${lsspecdomain}"],
214
+ "modules" => [
215
+ {"name" => "${lsspecdomain}", "testing" => "${lsspecdomain}"},
216
+ {"name" => "${lsspecdomain2}", "testing" => "${lsspecdomain2}"}
217
+ ]
218
+ }}
219
+ let(:yaml_path) do
220
+ p = Stud::Temporary.pathname
221
+ FileUtils.mkdir_p(p)
222
+
223
+ ::File.open(::File.join(p, "logstash.yml"), "w+") do |f|
224
+ f.write(YAML.dump(values))
225
+ end
226
+ p
227
+ end
228
+
229
+ it "can interpolate environment into settings" do
230
+ expect(subject.get('host')).to match_array([])
231
+ expect(subject.get('modules')).to match_array([])
232
+ subject.from_yaml(yaml_path)
233
+ expect(subject.get('host')).to match_array(["dev1.domain1", "dev2.domain1"])
234
+ expect(subject.get('modules')).to match_array([
235
+ {"name" => "domain1", "testing" => "domain1"},
236
+ {"name" => "domain2", "testing" => "domain2"}
237
+ ])
238
+ end
239
+ end
149
240
  end
@@ -9,22 +9,12 @@ describe LogStash::ShutdownWatcher do
9
9
  let(:pipeline) { double("pipeline") }
10
10
  let(:reporter) { double("reporter") }
11
11
  let(:reporter_snapshot) { double("reporter snapshot") }
12
- report_count = 0
13
12
 
14
13
  before :each do
15
14
  allow(pipeline).to receive(:reporter).and_return(reporter)
16
15
  allow(pipeline).to receive(:thread).and_return(Thread.current)
17
16
  allow(reporter).to receive(:snapshot).and_return(reporter_snapshot)
18
17
  allow(reporter_snapshot).to receive(:o_simple_hash).and_return({})
19
-
20
- allow(subject).to receive(:pipeline_report_snapshot).and_wrap_original do |m, *args|
21
- report_count += 1
22
- m.call(*args)
23
- end
24
- end
25
-
26
- after :each do
27
- report_count = 0
28
18
  end
29
19
 
30
20
  context "when pipeline is stalled" do
@@ -69,8 +59,9 @@ describe LogStash::ShutdownWatcher do
69
59
  it "shouldn't force the shutdown" do
70
60
  expect(subject).to_not receive(:force_exit)
71
61
  thread = Thread.new(subject) {|subject| subject.start }
72
- sleep 0.1 until report_count > check_threshold
73
- thread.kill
62
+ sleep 0.1 until subject.attempts_count > check_threshold
63
+ subject.stop!
64
+ expect(thread.join(60)).to_not be_nil
74
65
  end
75
66
  end
76
67
  end
@@ -91,8 +82,9 @@ describe LogStash::ShutdownWatcher do
91
82
  it "should force the shutdown" do
92
83
  expect(subject).to_not receive(:force_exit)
93
84
  thread = Thread.new(subject) {|subject| subject.start }
94
- sleep 0.1 until report_count > check_threshold
95
- thread.kill
85
+ sleep 0.1 until subject.attempts_count > check_threshold
86
+ subject.stop!
87
+ expect(thread.join(60)).to_not be_nil
96
88
  end
97
89
  end
98
90
 
@@ -105,8 +97,10 @@ describe LogStash::ShutdownWatcher do
105
97
  it "shouldn't force the shutdown" do
106
98
  expect(subject).to_not receive(:force_exit)
107
99
  thread = Thread.new(subject) {|subject| subject.start }
108
- sleep 0.1 until report_count > check_threshold
109
- thread.kill
100
+ sleep 0.1 until subject.attempts_count > check_threshold
101
+ subject.stop!
102
+ thread.join
103
+ expect(thread.join(60)).to_not be_nil
110
104
  end
111
105
  end
112
106
  end
@@ -46,10 +46,12 @@ describe LogStash::StateResolver do
46
46
 
47
47
  context "when some pipeline are running" do
48
48
  context "when a pipeline is running" do
49
- let(:running_pipelines) { { :main => mock_pipeline(:main) } }
49
+ let(:main_pipeline) { mock_pipeline(:main) }
50
+ let(:main_pipeline_config) { main_pipeline.pipeline_config }
51
+ let(:running_pipelines) { { :main => main_pipeline } }
50
52
 
51
53
  context "when the pipeline config contains a new one and the existing" do
52
- let(:pipeline_configs) { [mock_pipeline_config(:hello_world), mock_pipeline_config(:main)] }
54
+ let(:pipeline_configs) { [mock_pipeline_config(:hello_world), main_pipeline_config ] }
53
55
 
54
56
  it "creates the new one and keep the other one" do
55
57
  expect(subject.resolve(running_pipelines, pipeline_configs)).to have_actions(
@@ -105,7 +107,7 @@ describe LogStash::StateResolver do
105
107
  context "without system pipeline" do
106
108
  let(:pipeline_configs) do
107
109
  [
108
- mock_pipeline_config(:main1),
110
+ running_pipelines[:main1].pipeline_config,
109
111
  mock_pipeline_config(:main9),
110
112
  mock_pipeline_config(:main5, "input { generator {}}"),
111
113
  mock_pipeline_config(:main3, "input { generator {}}"),
@@ -129,7 +131,7 @@ describe LogStash::StateResolver do
129
131
  context "with system pipeline" do
130
132
  let(:pipeline_configs) do
131
133
  [
132
- mock_pipeline_config(:main1),
134
+ running_pipelines[:main1].pipeline_config,
133
135
  mock_pipeline_config(:main9),
134
136
  mock_pipeline_config(:main5, "input { generator {}}"),
135
137
  mock_pipeline_config(:main3, "input { generator {}}"),
@@ -22,7 +22,7 @@ def clear_data_dir
22
22
  end
23
23
  end
24
24
 
25
- def mock_settings(settings_values)
25
+ def mock_settings(settings_values={})
26
26
  settings = LogStash::SETTINGS.clone
27
27
 
28
28
  settings_values.each do |key, value|
@@ -32,13 +32,26 @@ def mock_settings(settings_values)
32
32
  settings
33
33
  end
34
34
 
35
+ def make_test_agent(settings=mock_settings)
36
+ sl = LogStash::Config::SourceLoader.new
37
+ sl.add_source(LogStash::Config::Source::Local.new(settings))
38
+ sl
39
+
40
+ ::LogStash::Agent.new(settings, sl)
41
+ end
42
+
35
43
  def mock_pipeline(pipeline_id, reloadable = true, config_hash = nil)
36
44
  config_string = "input { stdin { id => '#{pipeline_id}' }}"
37
45
  settings = mock_settings("pipeline.id" => pipeline_id.to_s,
38
46
  "config.string" => config_string,
39
47
  "config.reload.automatic" => reloadable)
40
- pipeline = LogStash::Pipeline.new(config_string, settings)
41
- pipeline
48
+ pipeline_config = mock_pipeline_config(pipeline_id, config_string, settings)
49
+ LogStash::Pipeline.new(pipeline_config)
50
+ end
51
+
52
+ def mock_pipeline_from_string(config_string, settings = LogStash::SETTINGS, metric = nil)
53
+ pipeline_config = mock_pipeline_config(settings.get("pipeline.id"), config_string, settings)
54
+ LogStash::Pipeline.new(pipeline_config, metric)
42
55
  end
43
56
 
44
57
  def mock_pipeline_config(pipeline_id, config_string = nil, settings = {})
@@ -2,12 +2,36 @@ shared_context "execution_context" do
2
2
  let(:pipeline) { double("pipeline") }
3
3
  let(:pipeline_id) { :main }
4
4
  let(:agent) { double("agent") }
5
+ let(:plugin_id) { :plugin_id }
6
+ let(:plugin_type) { :plugin_type }
7
+ let(:dlq_writer) { double("dlq_writer") }
5
8
  let(:execution_context) do
6
- ::LogStash::ExecutionContext.new(pipeline, agent)
9
+ ::LogStash::ExecutionContext.new(pipeline, agent, plugin_id, plugin_type, dlq_writer)
7
10
  end
8
-
11
+
9
12
  before do
10
13
  allow(pipeline).to receive(:pipeline_id).and_return(pipeline_id)
11
14
  allow(pipeline).to receive(:agent).and_return(agent)
12
15
  end
13
16
  end
17
+
18
+ shared_context "api setup" do
19
+ before :all do
20
+ clear_data_dir
21
+ settings = mock_settings
22
+ config_string = "input { generator {id => 'api-generator-pipeline' count => 100 } } output { dummyoutput {} }"
23
+ settings.set("config.string", config_string)
24
+ @agent = make_test_agent(settings)
25
+ @agent.execute
26
+ end
27
+
28
+ after :all do
29
+ @agent.shutdown
30
+ end
31
+
32
+ include Rack::Test::Methods
33
+
34
+ def app()
35
+ described_class.new(nil, @agent)
36
+ end
37
+ end