logstash-core 6.6.0-java → 6.6.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/logstash/agent.rb +61 -56
- data/lib/logstash/instrument/periodic_poller/dlq.rb +5 -7
- data/lib/logstash/instrument/periodic_poller/pq.rb +6 -8
- data/lib/logstash/instrument/periodic_pollers.rb +3 -3
- data/lib/logstash/java_pipeline.rb +22 -6
- data/lib/logstash/pipeline.rb +25 -8
- data/lib/logstash/pipeline_action/base.rb +1 -1
- data/lib/logstash/pipeline_action/create.rb +7 -13
- data/lib/logstash/pipeline_action/reload.rb +35 -12
- data/lib/logstash/pipeline_action/stop.rb +4 -6
- data/lib/logstash/pipelines_registry.rb +166 -0
- data/lib/logstash/state_resolver.rb +5 -5
- data/lib/logstash/util/safe_uri.rb +1 -0
- data/spec/logstash/agent/converge_spec.rb +25 -31
- data/spec/logstash/agent_spec.rb +5 -5
- data/spec/logstash/pipeline_action/create_spec.rb +9 -8
- data/spec/logstash/pipeline_action/reload_spec.rb +10 -9
- data/spec/logstash/pipeline_action/stop_spec.rb +4 -3
- data/spec/logstash/pipelines_registry_spec.rb +220 -0
- data/spec/logstash/runner_spec.rb +2 -0
- data/spec/logstash/state_resolver_spec.rb +26 -22
- data/spec/logstash/util/safe_uri_spec.rb +40 -0
- data/spec/support/matchers.rb +25 -19
- data/spec/support/shared_contexts.rb +3 -3
- data/versions-gem-copy.yml +2 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ae11e5a947442d4fe74bd284d674355a78112f5aff290403930bb35665ad724
|
4
|
+
data.tar.gz: 30c09cc64470baa5bb29f806cff27614fe64f83a205b6704740db4be569dd3a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81f35a278ce95f4cb063524c5333f4ce09f1de1a14fbefdc09a4b72f62cea73ec519a90b5b2b27cd720bd802bf40001656e6f90a294440c9898738567104dbdd
|
7
|
+
data.tar.gz: 74fdec603be67ac988e3b786e890733fd8254caa78c7d03b2c99afc1a8bb25779b0fefc9cb5675fdfec1fa06b3e124c6af880c0ee0197320d14e176d1370c742
|
data/lib/logstash/agent.rb
CHANGED
@@ -8,6 +8,7 @@ require "logstash/webserver"
|
|
8
8
|
require "logstash/config/source_loader"
|
9
9
|
require "logstash/pipeline_action"
|
10
10
|
require "logstash/state_resolver"
|
11
|
+
require "logstash/pipelines_registry"
|
11
12
|
require "stud/trap"
|
12
13
|
require "uri"
|
13
14
|
require "socket"
|
@@ -19,7 +20,7 @@ class LogStash::Agent
|
|
19
20
|
include LogStash::Util::Loggable
|
20
21
|
STARTED_AT = Time.now.freeze
|
21
22
|
|
22
|
-
attr_reader :metric, :name, :settings, :
|
23
|
+
attr_reader :metric, :name, :settings, :dispatcher, :ephemeral_id, :pipeline_bus
|
23
24
|
attr_accessor :logger
|
24
25
|
|
25
26
|
# initialize method for LogStash::Agent
|
@@ -36,11 +37,12 @@ class LogStash::Agent
|
|
36
37
|
# Mutex to synchonize in the exclusive method
|
37
38
|
# Initial usage for the Ruby pipeline initialization which is not thread safe
|
38
39
|
@exclusive_lock = Mutex.new
|
40
|
+
@webserver_control_lock = Mutex.new
|
39
41
|
|
40
42
|
# Special bus object for inter-pipelines communications. Used by the `pipeline` input/output
|
41
43
|
@pipeline_bus = org.logstash.plugins.pipeline.PipelineBus.new
|
42
44
|
|
43
|
-
@
|
45
|
+
@pipelines_registry = LogStash::PipelinesRegistry.new
|
44
46
|
|
45
47
|
@name = setting("node.name")
|
46
48
|
@http_host = setting("http.host")
|
@@ -118,14 +120,17 @@ class LogStash::Agent
|
|
118
120
|
converge_state_and_update unless stopped?
|
119
121
|
end
|
120
122
|
else
|
121
|
-
|
123
|
+
# exit with error status if the initial converge_state_and_update did not create any pipeline
|
124
|
+
return 1 if @pipelines_registry.empty?
|
122
125
|
|
123
126
|
while !Stud.stop?
|
124
|
-
if
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
127
|
+
# exit if all pipelines are terminated and none are reloading
|
128
|
+
break if no_pipeline?
|
129
|
+
|
130
|
+
# exit if there are no user defined pipelines (not system pipeline) and none are reloading
|
131
|
+
break if !running_user_defined_pipelines?
|
132
|
+
|
133
|
+
sleep(0.5)
|
129
134
|
end
|
130
135
|
end
|
131
136
|
|
@@ -139,11 +144,11 @@ class LogStash::Agent
|
|
139
144
|
end
|
140
145
|
|
141
146
|
def running?
|
142
|
-
@running.
|
147
|
+
@running.true?
|
143
148
|
end
|
144
149
|
|
145
150
|
def stopped?
|
146
|
-
|
151
|
+
@running.false?
|
147
152
|
end
|
148
153
|
|
149
154
|
def converge_state_and_update
|
@@ -237,43 +242,48 @@ class LogStash::Agent
|
|
237
242
|
@id_path ||= ::File.join(settings.get("path.data"), "uuid")
|
238
243
|
end
|
239
244
|
|
245
|
+
#
|
246
|
+
# Backward compatibility proxies to the PipelineRegistry
|
247
|
+
#
|
248
|
+
|
240
249
|
def get_pipeline(pipeline_id)
|
241
|
-
|
250
|
+
@pipelines_registry.get_pipeline(pipeline_id)
|
242
251
|
end
|
243
252
|
|
244
253
|
def pipelines_count
|
245
|
-
|
254
|
+
@pipelines_registry.size
|
246
255
|
end
|
247
256
|
|
248
257
|
def running_pipelines
|
249
|
-
|
250
|
-
|
258
|
+
@pipelines_registry.running_pipelines
|
259
|
+
end
|
251
260
|
|
252
261
|
def non_running_pipelines
|
253
|
-
|
262
|
+
@pipelines_registry.non_running_pipelines
|
254
263
|
end
|
255
264
|
|
256
265
|
def running_pipelines?
|
257
|
-
|
266
|
+
@pipelines_registry.running_pipelines.any?
|
258
267
|
end
|
259
268
|
|
260
269
|
def running_pipelines_count
|
261
|
-
running_pipelines.size
|
270
|
+
@pipelines_registry.running_pipelines.size
|
262
271
|
end
|
263
272
|
|
264
273
|
def running_user_defined_pipelines?
|
265
|
-
|
274
|
+
@pipelines_registry.running_user_defined_pipelines.any?
|
266
275
|
end
|
267
276
|
|
268
277
|
def running_user_defined_pipelines
|
269
|
-
|
278
|
+
@pipelines_registry.running_user_defined_pipelines
|
270
279
|
end
|
271
280
|
|
272
|
-
def
|
273
|
-
|
281
|
+
def no_pipeline?
|
282
|
+
@pipelines_registry.running_pipelines.empty?
|
274
283
|
end
|
275
284
|
|
276
285
|
private
|
286
|
+
|
277
287
|
def transition_to_stopped
|
278
288
|
@running.make_false
|
279
289
|
end
|
@@ -298,7 +308,7 @@ class LogStash::Agent
|
|
298
308
|
converge_result = LogStash::ConvergeResult.new(pipeline_actions.size)
|
299
309
|
|
300
310
|
pipeline_actions.map do |action|
|
301
|
-
Thread.new do
|
311
|
+
Thread.new(action, converge_result) do |action, converge_result|
|
302
312
|
java.lang.Thread.currentThread().setName("Converge #{action}");
|
303
313
|
# We execute every task we need to converge the current state of pipelines
|
304
314
|
# for every task we will record the action result, that will help us
|
@@ -314,34 +324,35 @@ class LogStash::Agent
|
|
314
324
|
# that we currently have.
|
315
325
|
begin
|
316
326
|
logger.debug("Executing action", :action => action)
|
317
|
-
action_result = action.execute(self,
|
327
|
+
action_result = action.execute(self, @pipelines_registry)
|
318
328
|
converge_result.add(action, action_result)
|
319
329
|
|
320
330
|
unless action_result.successful?
|
321
|
-
logger.error("Failed to execute action",
|
322
|
-
|
323
|
-
|
331
|
+
logger.error("Failed to execute action",
|
332
|
+
:id => action.pipeline_id,
|
333
|
+
:action_type => action_result.class,
|
334
|
+
:message => action_result.message,
|
335
|
+
:backtrace => action_result.backtrace
|
336
|
+
)
|
324
337
|
end
|
325
|
-
rescue SystemExit => e
|
326
|
-
converge_result.add(action, e)
|
327
|
-
rescue Exception => e
|
338
|
+
rescue SystemExit, Exception => e
|
328
339
|
logger.error("Failed to execute action", :action => action, :exception => e.class.name, :message => e.message, :backtrace => e.backtrace)
|
329
340
|
converge_result.add(action, e)
|
330
341
|
end
|
331
342
|
end
|
332
343
|
end.each(&:join)
|
333
344
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
345
|
+
logger.trace? && logger.trace("Converge results",
|
346
|
+
:success => converge_result.success?,
|
347
|
+
:failed_actions => converge_result.failed_actions.collect { |a, r| "id: #{a.pipeline_id}, action_type: #{a.class}, message: #{r.message}" },
|
348
|
+
:successful_actions => converge_result.successful_actions.collect { |a, r| "id: #{a.pipeline_id}, action_type: #{a.class}" }
|
349
|
+
)
|
339
350
|
|
340
351
|
converge_result
|
341
352
|
end
|
342
353
|
|
343
354
|
def resolve_actions(pipeline_configs)
|
344
|
-
@state_resolver.resolve(@
|
355
|
+
@state_resolver.resolve(@pipelines_registry, pipeline_configs)
|
345
356
|
end
|
346
357
|
|
347
358
|
def dispatch_events(converge_results)
|
@@ -358,20 +369,24 @@ class LogStash::Agent
|
|
358
369
|
end
|
359
370
|
|
360
371
|
def start_webserver
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
372
|
+
@webserver_control_lock.synchronize do
|
373
|
+
options = {:http_host => @http_host, :http_ports => @http_port, :http_environment => @http_environment }
|
374
|
+
@webserver = LogStash::WebServer.new(@logger, self, options)
|
375
|
+
@webserver_thread = Thread.new(@webserver) do |webserver|
|
376
|
+
LogStash::Util.set_thread_name("Api Webserver")
|
377
|
+
webserver.run
|
378
|
+
end
|
366
379
|
end
|
367
380
|
end
|
368
381
|
|
369
382
|
def stop_webserver
|
370
|
-
|
371
|
-
@webserver
|
372
|
-
|
373
|
-
@webserver_thread.
|
374
|
-
|
383
|
+
@webserver_control_lock.synchronize do
|
384
|
+
if @webserver
|
385
|
+
@webserver.stop
|
386
|
+
if @webserver_thread.join(5).nil?
|
387
|
+
@webserver_thread.kill
|
388
|
+
@webserver_thread.join
|
389
|
+
end
|
375
390
|
end
|
376
391
|
end
|
377
392
|
end
|
@@ -399,7 +414,7 @@ class LogStash::Agent
|
|
399
414
|
end
|
400
415
|
|
401
416
|
def shutdown_pipelines
|
402
|
-
logger.debug("Shutting down all pipelines", :pipelines_count =>
|
417
|
+
logger.debug("Shutting down all pipelines", :pipelines_count => running_pipelines_count)
|
403
418
|
|
404
419
|
# In this context I could just call shutdown, but I've decided to
|
405
420
|
# use the stop action implementation for that so we have the same code.
|
@@ -408,16 +423,6 @@ class LogStash::Agent
|
|
408
423
|
converge_state(pipeline_actions)
|
409
424
|
end
|
410
425
|
|
411
|
-
def running_pipeline?(pipeline_id)
|
412
|
-
pipeline = get_pipeline(pipeline_id)
|
413
|
-
return false unless pipeline
|
414
|
-
thread = pipeline.thread
|
415
|
-
thread.is_a?(Thread) && thread.alive?
|
416
|
-
end
|
417
|
-
|
418
|
-
def clean_state?
|
419
|
-
pipelines.empty?
|
420
|
-
end
|
421
426
|
|
422
427
|
def setting(key)
|
423
428
|
@settings.get(key)
|
@@ -10,13 +10,11 @@ module LogStash module Instrument module PeriodicPoller
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def collect
|
13
|
-
pipelines = @agent.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
}
|
13
|
+
pipelines = @agent.running_user_defined_pipelines
|
14
|
+
pipelines.each do |_, pipeline|
|
15
|
+
unless pipeline.nil?
|
16
|
+
pipeline.collect_dlq_stats
|
17
|
+
end
|
20
18
|
end
|
21
19
|
end
|
22
20
|
end
|
@@ -11,14 +11,12 @@ module LogStash module Instrument module PeriodicPoller
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def collect
|
14
|
-
pipelines = @agent.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
}
|
14
|
+
pipelines = @agent.running_user_defined_pipelines
|
15
|
+
pipelines.each do |_, pipeline|
|
16
|
+
unless pipeline.nil?
|
17
|
+
pipeline.collect_stats
|
18
|
+
end
|
21
19
|
end
|
22
20
|
end
|
23
21
|
end
|
24
|
-
end
|
22
|
+
end end end
|
@@ -11,12 +11,12 @@ module LogStash module Instrument
|
|
11
11
|
class PeriodicPollers
|
12
12
|
attr_reader :metric
|
13
13
|
|
14
|
-
def initialize(metric, queue_type,
|
14
|
+
def initialize(metric, queue_type, agent)
|
15
15
|
@metric = metric
|
16
16
|
@periodic_pollers = [PeriodicPoller::Os.new(metric),
|
17
17
|
PeriodicPoller::JVM.new(metric),
|
18
|
-
PeriodicPoller::PersistentQueue.new(metric, queue_type,
|
19
|
-
PeriodicPoller::DeadLetterQueue.new(metric,
|
18
|
+
PeriodicPoller::PersistentQueue.new(metric, queue_type, agent),
|
19
|
+
PeriodicPoller::DeadLetterQueue.new(metric, agent)]
|
20
20
|
end
|
21
21
|
|
22
22
|
def start
|
@@ -41,9 +41,23 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
41
41
|
@flushRequested = java.util.concurrent.atomic.AtomicBoolean.new(false)
|
42
42
|
@shutdownRequested = java.util.concurrent.atomic.AtomicBoolean.new(false)
|
43
43
|
@outputs_registered = Concurrent::AtomicBoolean.new(false)
|
44
|
+
|
45
|
+
# @finished_execution signals that the pipeline thread has finished its execution
|
46
|
+
# regardless of any exceptions; it will always be true when the thread completes
|
44
47
|
@finished_execution = Concurrent::AtomicBoolean.new(false)
|
48
|
+
|
49
|
+
# @finished_run signals that the run methods called in the pipeline thread was completed
|
50
|
+
# without errors and it will NOT be set if the run method exits from an exception; this
|
51
|
+
# is by design and necessary for the wait_until_started semantic
|
52
|
+
@finished_run = Concurrent::AtomicBoolean.new(false)
|
53
|
+
|
54
|
+
@thread = nil
|
45
55
|
end # def initialize
|
46
56
|
|
57
|
+
def finished_execution?
|
58
|
+
@finished_execution.true?
|
59
|
+
end
|
60
|
+
|
47
61
|
def ready?
|
48
62
|
@ready.value
|
49
63
|
end
|
@@ -85,15 +99,18 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
85
99
|
@logger.debug("Starting pipeline", default_logging_keys)
|
86
100
|
|
87
101
|
@finished_execution.make_false
|
102
|
+
@finished_run.make_false
|
88
103
|
|
89
104
|
@thread = Thread.new do
|
90
105
|
begin
|
91
106
|
LogStash::Util.set_thread_name("pipeline.#{pipeline_id}")
|
92
107
|
run
|
93
|
-
@
|
108
|
+
@finished_run.make_true
|
94
109
|
rescue => e
|
95
110
|
close
|
96
111
|
logger.error("Pipeline aborted due to error", default_logging_keys(:exception => e, :backtrace => e.backtrace))
|
112
|
+
ensure
|
113
|
+
@finished_execution.make_true
|
97
114
|
end
|
98
115
|
end
|
99
116
|
|
@@ -108,15 +125,14 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
108
125
|
|
109
126
|
def wait_until_started
|
110
127
|
while true do
|
111
|
-
|
112
|
-
|
113
|
-
# a generator { count => 1 } its possible that `Thread#alive?` doesn't return true
|
114
|
-
# because the execution of the thread was successful and complete
|
115
|
-
if @finished_execution.true?
|
128
|
+
if @finished_run.true?
|
129
|
+
# it completed run without exception
|
116
130
|
return true
|
117
131
|
elsif thread.nil? || !thread.alive?
|
132
|
+
# some exception occurred and the thread is dead
|
118
133
|
return false
|
119
134
|
elsif running?
|
135
|
+
# fully initialized and running
|
120
136
|
return true
|
121
137
|
else
|
122
138
|
sleep 0.01
|
data/lib/logstash/pipeline.rb
CHANGED
@@ -107,8 +107,23 @@ module LogStash; class Pipeline < BasePipeline
|
|
107
107
|
@flushing = Concurrent::AtomicReference.new(false)
|
108
108
|
@outputs_registered = Concurrent::AtomicBoolean.new(false)
|
109
109
|
@worker_shutdown = java.util.concurrent.atomic.AtomicBoolean.new(false)
|
110
|
+
|
111
|
+
# @finished_execution signals that the pipeline thread has finished its execution
|
112
|
+
# regardless of any exceptions; it will always be true when the thread completes
|
113
|
+
@finished_execution = Concurrent::AtomicBoolean.new(false)
|
114
|
+
|
115
|
+
# @finished_run signals that the run methods called in the pipeline thread was completed
|
116
|
+
# without errors and it will NOT be set if the run method exits from an exception; this
|
117
|
+
# is by design and necessary for the wait_until_started semantic
|
118
|
+
@finished_run = Concurrent::AtomicBoolean.new(false)
|
119
|
+
|
120
|
+
@thread = nil
|
110
121
|
end # def initialize
|
111
122
|
|
123
|
+
def finished_execution?
|
124
|
+
@finished_execution.true?
|
125
|
+
end
|
126
|
+
|
112
127
|
def ready?
|
113
128
|
@ready.value
|
114
129
|
end
|
@@ -152,16 +167,19 @@ module LogStash; class Pipeline < BasePipeline
|
|
152
167
|
"pipeline.batch.size" => settings.get("pipeline.batch.size"),
|
153
168
|
"pipeline.batch.delay" => settings.get("pipeline.batch.delay")))
|
154
169
|
|
155
|
-
@finished_execution
|
170
|
+
@finished_execution.make_false
|
171
|
+
@finished_run.make_false
|
156
172
|
|
157
173
|
@thread = Thread.new do
|
158
174
|
begin
|
159
175
|
LogStash::Util.set_thread_name("pipeline.#{pipeline_id}")
|
160
176
|
run
|
161
|
-
@
|
177
|
+
@finished_run.make_true
|
162
178
|
rescue => e
|
163
179
|
close
|
164
180
|
@logger.error("Pipeline aborted due to error", default_logging_keys(:exception => e, :backtrace => e.backtrace))
|
181
|
+
ensure
|
182
|
+
@finished_execution.make_true
|
165
183
|
end
|
166
184
|
end
|
167
185
|
|
@@ -176,15 +194,14 @@ module LogStash; class Pipeline < BasePipeline
|
|
176
194
|
|
177
195
|
def wait_until_started
|
178
196
|
while true do
|
179
|
-
|
180
|
-
|
181
|
-
# a generator { count => 1 } its possible that `Thread#alive?` doesn't return true
|
182
|
-
# because the execution of the thread was successful and complete
|
183
|
-
if @finished_execution.true?
|
197
|
+
if @finished_run.true?
|
198
|
+
# it completed run without exception
|
184
199
|
return true
|
185
|
-
elsif !thread.alive?
|
200
|
+
elsif thread.nil? || !thread.alive?
|
201
|
+
# some exception occured and the thread is dead
|
186
202
|
return false
|
187
203
|
elsif running?
|
204
|
+
# fully initialized and running
|
188
205
|
return true
|
189
206
|
else
|
190
207
|
sleep 0.01
|