logstash-core 6.0.0.alpha1-java → 6.0.0.alpha2-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.
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