logstash-core 7.0.0.alpha2-java → 7.0.0.beta1-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.
- checksums.yaml +4 -4
- data/lib/logstash/agent.rb +62 -57
- data/lib/logstash/compiler/lscl.rb +2 -3
- data/lib/logstash/config/config_ast.rb +59 -17
- data/lib/logstash/environment.rb +1 -1
- data/lib/logstash/instrument/metric_store.rb +1 -1
- 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 +36 -15
- data/lib/logstash/patches/resolv.rb +0 -21
- data/lib/logstash/pipeline.rb +27 -10
- 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/pipeline_settings.rb +1 -1
- data/lib/logstash/pipelines_registry.rb +166 -0
- data/lib/logstash/settings.rb +5 -5
- data/lib/logstash/state_resolver.rb +5 -5
- data/lib/logstash/util/duration_formatter.rb +1 -1
- data/lib/logstash/util/safe_uri.rb +1 -0
- data/lib/logstash/util.rb +11 -1
- data/locales/en.yml +1 -1
- data/logstash-core.gemspec +17 -20
- data/spec/logstash/acked_queue_concurrent_stress_spec.rb +1 -1
- data/spec/logstash/agent/converge_spec.rb +25 -31
- data/spec/logstash/agent_spec.rb +5 -5
- data/spec/logstash/event_spec.rb +2 -2
- data/spec/logstash/instrument/wrapped_write_client_spec.rb +1 -1
- data/spec/logstash/legacy_ruby_event_spec.rb +6 -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/queue_factory_spec.rb +2 -1
- data/spec/logstash/runner_spec.rb +2 -0
- data/spec/logstash/settings/array_coercible_spec.rb +1 -1
- data/spec/logstash/settings/bytes_spec.rb +2 -2
- data/spec/logstash/settings/port_range_spec.rb +1 -1
- data/spec/logstash/state_resolver_spec.rb +26 -22
- data/spec/logstash/util/safe_uri_spec.rb +40 -0
- data/spec/logstash/util/time_value_spec.rb +1 -1
- data/spec/logstash/util/wrapped_acked_queue_spec.rb +1 -1
- data/spec/support/matchers.rb +25 -19
- data/spec/support/shared_contexts.rb +3 -3
- data/versions-gem-copy.yml +6 -6
- metadata +73 -88
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 650eff422fce2ce58c826a22c759238b5cb14bb407232b3cb0ffe2119635df29
|
4
|
+
data.tar.gz: 44a83cccdc93c56fcc4952746675702b7593e0f494b167efcfc4fe002566dfb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94c5e143d649f75006330dfc9f77d3551d011aabef1e18017cb0eff8f96ae16d6690b5487acbabec3e9adae5eb0d3a4cb8bfb974a174cbb8d4073f659ab821cf
|
7
|
+
data.tar.gz: 1500544458de19cb215a0f45e6b83a00b4d8ef0b05f951536a080f2fad359502eaf847792b20719e1781727caddc11349d7c504c82d0cfe47aa5ff8e158f66e8
|
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")
|
@@ -114,14 +116,17 @@ class LogStash::Agent
|
|
114
116
|
converge_state_and_update unless stopped?
|
115
117
|
end
|
116
118
|
else
|
117
|
-
|
119
|
+
# exit with error status if the initial converge_state_and_update did not create any pipeline
|
120
|
+
return 1 if @pipelines_registry.empty?
|
118
121
|
|
119
122
|
while !Stud.stop?
|
120
|
-
if
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
123
|
+
# exit if all pipelines are terminated and none are reloading
|
124
|
+
break if no_pipeline?
|
125
|
+
|
126
|
+
# exit if there are no user defined pipelines (not system pipeline) and none are reloading
|
127
|
+
break if !running_user_defined_pipelines?
|
128
|
+
|
129
|
+
sleep(0.5)
|
125
130
|
end
|
126
131
|
end
|
127
132
|
|
@@ -135,11 +140,11 @@ class LogStash::Agent
|
|
135
140
|
end
|
136
141
|
|
137
142
|
def running?
|
138
|
-
@running.
|
143
|
+
@running.true?
|
139
144
|
end
|
140
145
|
|
141
146
|
def stopped?
|
142
|
-
|
147
|
+
@running.false?
|
143
148
|
end
|
144
149
|
|
145
150
|
def converge_state_and_update
|
@@ -178,7 +183,7 @@ class LogStash::Agent
|
|
178
183
|
|
179
184
|
# Calculate the Logstash uptime in milliseconds
|
180
185
|
#
|
181
|
-
# @return [
|
186
|
+
# @return [Integer] Uptime in milliseconds
|
182
187
|
def uptime
|
183
188
|
((Time.now.to_f - STARTED_AT.to_f) * 1000.0).to_i
|
184
189
|
end
|
@@ -233,43 +238,48 @@ class LogStash::Agent
|
|
233
238
|
@id_path ||= ::File.join(settings.get("path.data"), "uuid")
|
234
239
|
end
|
235
240
|
|
241
|
+
#
|
242
|
+
# Backward compatibility proxies to the PipelineRegistry
|
243
|
+
#
|
244
|
+
|
236
245
|
def get_pipeline(pipeline_id)
|
237
|
-
|
246
|
+
@pipelines_registry.get_pipeline(pipeline_id)
|
238
247
|
end
|
239
248
|
|
240
249
|
def pipelines_count
|
241
|
-
|
250
|
+
@pipelines_registry.size
|
242
251
|
end
|
243
252
|
|
244
253
|
def running_pipelines
|
245
|
-
|
246
|
-
|
254
|
+
@pipelines_registry.running_pipelines
|
255
|
+
end
|
247
256
|
|
248
257
|
def non_running_pipelines
|
249
|
-
|
258
|
+
@pipelines_registry.non_running_pipelines
|
250
259
|
end
|
251
260
|
|
252
261
|
def running_pipelines?
|
253
|
-
|
262
|
+
@pipelines_registry.running_pipelines.any?
|
254
263
|
end
|
255
264
|
|
256
265
|
def running_pipelines_count
|
257
|
-
running_pipelines.size
|
266
|
+
@pipelines_registry.running_pipelines.size
|
258
267
|
end
|
259
268
|
|
260
269
|
def running_user_defined_pipelines?
|
261
|
-
|
270
|
+
@pipelines_registry.running_user_defined_pipelines.any?
|
262
271
|
end
|
263
272
|
|
264
273
|
def running_user_defined_pipelines
|
265
|
-
|
274
|
+
@pipelines_registry.running_user_defined_pipelines
|
266
275
|
end
|
267
276
|
|
268
|
-
def
|
269
|
-
|
277
|
+
def no_pipeline?
|
278
|
+
@pipelines_registry.running_pipelines.empty?
|
270
279
|
end
|
271
280
|
|
272
281
|
private
|
282
|
+
|
273
283
|
def transition_to_stopped
|
274
284
|
@running.make_false
|
275
285
|
end
|
@@ -294,7 +304,7 @@ class LogStash::Agent
|
|
294
304
|
converge_result = LogStash::ConvergeResult.new(pipeline_actions.size)
|
295
305
|
|
296
306
|
pipeline_actions.map do |action|
|
297
|
-
Thread.new do
|
307
|
+
Thread.new(action, converge_result) do |action, converge_result|
|
298
308
|
java.lang.Thread.currentThread().setName("Converge #{action}");
|
299
309
|
# We execute every task we need to converge the current state of pipelines
|
300
310
|
# for every task we will record the action result, that will help us
|
@@ -310,34 +320,35 @@ class LogStash::Agent
|
|
310
320
|
# that we currently have.
|
311
321
|
begin
|
312
322
|
logger.debug("Executing action", :action => action)
|
313
|
-
action_result = action.execute(self,
|
323
|
+
action_result = action.execute(self, @pipelines_registry)
|
314
324
|
converge_result.add(action, action_result)
|
315
325
|
|
316
326
|
unless action_result.successful?
|
317
|
-
logger.error("Failed to execute action",
|
318
|
-
|
319
|
-
|
327
|
+
logger.error("Failed to execute action",
|
328
|
+
:id => action.pipeline_id,
|
329
|
+
:action_type => action_result.class,
|
330
|
+
:message => action_result.message,
|
331
|
+
:backtrace => action_result.backtrace
|
332
|
+
)
|
320
333
|
end
|
321
|
-
rescue SystemExit => e
|
322
|
-
converge_result.add(action, e)
|
323
|
-
rescue Exception => e
|
334
|
+
rescue SystemExit, Exception => e
|
324
335
|
logger.error("Failed to execute action", :action => action, :exception => e.class.name, :message => e.message, :backtrace => e.backtrace)
|
325
336
|
converge_result.add(action, e)
|
326
337
|
end
|
327
338
|
end
|
328
339
|
end.each(&:join)
|
329
340
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
341
|
+
logger.trace? && logger.trace("Converge results",
|
342
|
+
:success => converge_result.success?,
|
343
|
+
:failed_actions => converge_result.failed_actions.collect { |a, r| "id: #{a.pipeline_id}, action_type: #{a.class}, message: #{r.message}" },
|
344
|
+
:successful_actions => converge_result.successful_actions.collect { |a, r| "id: #{a.pipeline_id}, action_type: #{a.class}" }
|
345
|
+
)
|
335
346
|
|
336
347
|
converge_result
|
337
348
|
end
|
338
349
|
|
339
350
|
def resolve_actions(pipeline_configs)
|
340
|
-
@state_resolver.resolve(@
|
351
|
+
@state_resolver.resolve(@pipelines_registry, pipeline_configs)
|
341
352
|
end
|
342
353
|
|
343
354
|
def dispatch_events(converge_results)
|
@@ -354,20 +365,24 @@ class LogStash::Agent
|
|
354
365
|
end
|
355
366
|
|
356
367
|
def start_webserver
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
368
|
+
@webserver_control_lock.synchronize do
|
369
|
+
options = {:http_host => @http_host, :http_ports => @http_port, :http_environment => @http_environment }
|
370
|
+
@webserver = LogStash::WebServer.new(@logger, self, options)
|
371
|
+
@webserver_thread = Thread.new(@webserver) do |webserver|
|
372
|
+
LogStash::Util.set_thread_name("Api Webserver")
|
373
|
+
webserver.run
|
374
|
+
end
|
362
375
|
end
|
363
376
|
end
|
364
377
|
|
365
378
|
def stop_webserver
|
366
|
-
|
367
|
-
@webserver
|
368
|
-
|
369
|
-
@webserver_thread.
|
370
|
-
|
379
|
+
@webserver_control_lock.synchronize do
|
380
|
+
if @webserver
|
381
|
+
@webserver.stop
|
382
|
+
if @webserver_thread.join(5).nil?
|
383
|
+
@webserver_thread.kill
|
384
|
+
@webserver_thread.join
|
385
|
+
end
|
371
386
|
end
|
372
387
|
end
|
373
388
|
end
|
@@ -395,7 +410,7 @@ class LogStash::Agent
|
|
395
410
|
end
|
396
411
|
|
397
412
|
def shutdown_pipelines
|
398
|
-
logger.debug("Shutting down all pipelines", :pipelines_count =>
|
413
|
+
logger.debug("Shutting down all pipelines", :pipelines_count => running_pipelines_count)
|
399
414
|
|
400
415
|
# In this context I could just call shutdown, but I've decided to
|
401
416
|
# use the stop action implementation for that so we have the same code.
|
@@ -404,16 +419,6 @@ class LogStash::Agent
|
|
404
419
|
converge_state(pipeline_actions)
|
405
420
|
end
|
406
421
|
|
407
|
-
def running_pipeline?(pipeline_id)
|
408
|
-
pipeline = get_pipeline(pipeline_id)
|
409
|
-
return false unless pipeline
|
410
|
-
thread = pipeline.thread
|
411
|
-
thread.is_a?(Thread) && thread.alive?
|
412
|
-
end
|
413
|
-
|
414
|
-
def clean_state?
|
415
|
-
pipelines.empty?
|
416
|
-
end
|
417
422
|
|
418
423
|
def setting(key)
|
419
424
|
@settings.get(key)
|
@@ -317,10 +317,9 @@ module LogStashCompilerLSCLGrammar; module LogStash; module Compiler; module LSC
|
|
317
317
|
|
318
318
|
def precedence(op)
|
319
319
|
# Believe this is right for logstash?
|
320
|
-
|
321
|
-
when AND_METHOD
|
320
|
+
if op == AND_METHOD
|
322
321
|
2
|
323
|
-
|
322
|
+
elsif op == OR_METHOD
|
324
323
|
1
|
325
324
|
else
|
326
325
|
raise ArgumentError, "Unexpected operator #{op}"
|
@@ -7,28 +7,60 @@ require "logstash/compiler/treetop_monkeypatches"
|
|
7
7
|
module LogStash; module Config; module AST
|
8
8
|
PROCESS_ESCAPE_SEQUENCES = :process_escape_sequences
|
9
9
|
|
10
|
-
|
11
|
-
@
|
12
|
-
|
10
|
+
class << self
|
11
|
+
# @api private
|
12
|
+
MUTEX = Mutex.new
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
# Executes the given block with exclusive access to the AST global variables
|
15
|
+
#
|
16
|
+
# @yieldreturn [Object]: the object that is returned from the block is returned by this method
|
17
|
+
#
|
18
|
+
# @return [Object]
|
19
|
+
def exclusive
|
20
|
+
MUTEX.synchronize { yield }
|
21
|
+
end
|
17
22
|
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
def deferred_conditionals=(val)
|
24
|
+
ensure_exclusive!
|
25
|
+
@deferred_conditionals = val
|
26
|
+
end
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
28
|
+
def deferred_conditionals
|
29
|
+
ensure_exclusive!
|
30
|
+
@deferred_conditionals
|
31
|
+
end
|
25
32
|
|
26
|
-
|
27
|
-
|
28
|
-
|
33
|
+
def deferred_conditionals_index
|
34
|
+
ensure_exclusive!
|
35
|
+
@deferred_conditionals_index
|
36
|
+
end
|
37
|
+
|
38
|
+
def deferred_conditionals_index=(val)
|
39
|
+
ensure_exclusive!
|
40
|
+
@deferred_conditionals_index = val
|
41
|
+
end
|
29
42
|
|
30
|
-
|
31
|
-
|
43
|
+
def plugin_instance_index
|
44
|
+
ensure_exclusive!
|
45
|
+
@plugin_instance_index
|
46
|
+
end
|
47
|
+
|
48
|
+
def plugin_instance_index=(val)
|
49
|
+
ensure_exclusive!
|
50
|
+
@plugin_instance_index = val
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Raises a descriptive error if the thread in which it is invoked does
|
56
|
+
# not have exclusive access.
|
57
|
+
#
|
58
|
+
# @raise [RuntimeError]
|
59
|
+
def ensure_exclusive!
|
60
|
+
return if MUTEX.owned?
|
61
|
+
|
62
|
+
raise "Illegal access without exclusive lock at `#{caller[1]}`"
|
63
|
+
end
|
32
64
|
end
|
33
65
|
|
34
66
|
class Node < Treetop::Runtime::SyntaxNode
|
@@ -46,6 +78,15 @@ module LogStash; module Config; module AST
|
|
46
78
|
|
47
79
|
|
48
80
|
def compile
|
81
|
+
LogStash::Config::AST.exclusive { do_compile }
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
# NON-threadsafe method compiles an AST into executable Ruby code.
|
87
|
+
# @see Config#compile, which is a threadsafe wrapper around this method.
|
88
|
+
# @api private
|
89
|
+
def do_compile
|
49
90
|
LogStash::Config::AST.deferred_conditionals = []
|
50
91
|
LogStash::Config::AST.deferred_conditionals_index = 0
|
51
92
|
LogStash::Config::AST.plugin_instance_index = 0
|
@@ -491,6 +532,7 @@ module LogStash; module Config; module AST
|
|
491
532
|
end; end; end
|
492
533
|
|
493
534
|
|
535
|
+
|
494
536
|
# Monkeypatch Treetop::Runtime::SyntaxNode's inspect method to skip
|
495
537
|
# any Whitespace or SyntaxNodes with no children.
|
496
538
|
class Treetop::Runtime::SyntaxNode
|
data/lib/logstash/environment.rb
CHANGED
@@ -38,7 +38,6 @@ module LogStash
|
|
38
38
|
Setting::String.new("pipeline.id", "main"),
|
39
39
|
Setting::Boolean.new("pipeline.system", false),
|
40
40
|
Setting::PositiveInteger.new("pipeline.workers", LogStash::Config::CpuCoreStrategy.maximum),
|
41
|
-
Setting::PositiveInteger.new("pipeline.output.workers", 1),
|
42
41
|
Setting::PositiveInteger.new("pipeline.batch.size", 125),
|
43
42
|
Setting::Numeric.new("pipeline.batch.delay", 50), # in milliseconds
|
44
43
|
Setting::Boolean.new("pipeline.unsafe_shutdown", false),
|
@@ -62,6 +61,7 @@ module LogStash
|
|
62
61
|
Setting::Numeric.new("queue.checkpoint.acks", 1024), # 0 is unlimited
|
63
62
|
Setting::Numeric.new("queue.checkpoint.writes", 1024), # 0 is unlimited
|
64
63
|
Setting::Numeric.new("queue.checkpoint.interval", 1000), # 0 is no time-based checkpointing
|
64
|
+
Setting::Boolean.new("queue.checkpoint.retry", false),
|
65
65
|
Setting::Boolean.new("dead_letter_queue.enable", false),
|
66
66
|
Setting::Bytes.new("dead_letter_queue.max_bytes", "1024mb"),
|
67
67
|
Setting::TimeValue.new("slowlog.threshold.warn", "-1"),
|
@@ -302,7 +302,7 @@ module LogStash module Instrument
|
|
302
302
|
#
|
303
303
|
# @param [Concurrent::Map] Map to search for the key
|
304
304
|
# @param [Array] List of path to create
|
305
|
-
# @param [
|
305
|
+
# @param [Integer] Which part from the list to create
|
306
306
|
#
|
307
307
|
def fetch_or_store_namespace_recursively(map, namespaces_path, idx = 0)
|
308
308
|
current = namespaces_path[idx]
|
@@ -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
|
@@ -25,8 +25,6 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
25
25
|
|
26
26
|
@worker_threads = []
|
27
27
|
|
28
|
-
@java_inputs_controller = org.logstash.execution.InputsController.new(lir_execution.javaInputs)
|
29
|
-
|
30
28
|
@drain_queue = settings.get_value("queue.drain") || settings.get("queue.type") == "memory"
|
31
29
|
|
32
30
|
@events_filtered = java.util.concurrent.atomic.LongAdder.new
|
@@ -40,9 +38,23 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
40
38
|
@flushRequested = java.util.concurrent.atomic.AtomicBoolean.new(false)
|
41
39
|
@shutdownRequested = java.util.concurrent.atomic.AtomicBoolean.new(false)
|
42
40
|
@outputs_registered = Concurrent::AtomicBoolean.new(false)
|
41
|
+
|
42
|
+
# @finished_execution signals that the pipeline thread has finished its execution
|
43
|
+
# regardless of any exceptions; it will always be true when the thread completes
|
43
44
|
@finished_execution = Concurrent::AtomicBoolean.new(false)
|
45
|
+
|
46
|
+
# @finished_run signals that the run methods called in the pipeline thread was completed
|
47
|
+
# without errors and it will NOT be set if the run method exits from an exception; this
|
48
|
+
# is by design and necessary for the wait_until_started semantic
|
49
|
+
@finished_run = Concurrent::AtomicBoolean.new(false)
|
50
|
+
|
51
|
+
@thread = nil
|
44
52
|
end # def initialize
|
45
53
|
|
54
|
+
def finished_execution?
|
55
|
+
@finished_execution.true?
|
56
|
+
end
|
57
|
+
|
46
58
|
def ready?
|
47
59
|
@ready.value
|
48
60
|
end
|
@@ -84,15 +96,18 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
84
96
|
@logger.debug("Starting pipeline", default_logging_keys)
|
85
97
|
|
86
98
|
@finished_execution.make_false
|
99
|
+
@finished_run.make_false
|
87
100
|
|
88
101
|
@thread = Thread.new do
|
89
102
|
begin
|
90
103
|
LogStash::Util.set_thread_name("pipeline.#{pipeline_id}")
|
91
104
|
run
|
92
|
-
@
|
105
|
+
@finished_run.make_true
|
93
106
|
rescue => e
|
94
107
|
close
|
95
108
|
logger.error("Pipeline aborted due to error", default_logging_keys(:exception => e, :backtrace => e.backtrace))
|
109
|
+
ensure
|
110
|
+
@finished_execution.make_true
|
96
111
|
end
|
97
112
|
end
|
98
113
|
|
@@ -107,15 +122,14 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
107
122
|
|
108
123
|
def wait_until_started
|
109
124
|
while true do
|
110
|
-
|
111
|
-
|
112
|
-
# a generator { count => 1 } its possible that `Thread#alive?` doesn't return true
|
113
|
-
# because the execution of the thread was successful and complete
|
114
|
-
if @finished_execution.true?
|
125
|
+
if @finished_run.true?
|
126
|
+
# it completed run without exception
|
115
127
|
return true
|
116
128
|
elsif thread.nil? || !thread.alive?
|
129
|
+
# some exception occurred and the thread is dead
|
117
130
|
return false
|
118
131
|
elsif running?
|
132
|
+
# fully initialized and running
|
119
133
|
return true
|
120
134
|
else
|
121
135
|
sleep 0.01
|
@@ -217,11 +231,11 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
217
231
|
|
218
232
|
pipeline_workers.times do |t|
|
219
233
|
thread = Thread.new do
|
234
|
+
Util.set_thread_name("[#{pipeline_id}]>worker#{t}")
|
220
235
|
org.logstash.execution.WorkerLoop.new(
|
221
236
|
lir_execution, filter_queue_client, @events_filtered, @events_consumed,
|
222
237
|
@flushRequested, @flushing, @shutdownRequested, @drain_queue).run
|
223
238
|
end
|
224
|
-
Util.set_thread_name("[#{pipeline_id}]>worker#{t}")
|
225
239
|
@worker_threads << thread
|
226
240
|
end
|
227
241
|
|
@@ -242,8 +256,13 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
242
256
|
end
|
243
257
|
|
244
258
|
def wait_inputs
|
245
|
-
@input_threads.each
|
246
|
-
|
259
|
+
@input_threads.each do |thread|
|
260
|
+
if thread.class == Java::JavaObject
|
261
|
+
thread.to_java.join
|
262
|
+
else
|
263
|
+
thread.join
|
264
|
+
end
|
265
|
+
end
|
247
266
|
end
|
248
267
|
|
249
268
|
def start_inputs
|
@@ -262,11 +281,14 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
262
281
|
|
263
282
|
# then after all input plugins are successfully registered, start them
|
264
283
|
inputs.each { |input| start_input(input) }
|
265
|
-
@java_inputs_controller.startInputs(self)
|
266
284
|
end
|
267
285
|
|
268
286
|
def start_input(plugin)
|
269
|
-
|
287
|
+
if plugin.class == LogStash::JavaInputDelegator
|
288
|
+
@input_threads << plugin.start
|
289
|
+
else
|
290
|
+
@input_threads << Thread.new { inputworker(plugin) }
|
291
|
+
end
|
270
292
|
end
|
271
293
|
|
272
294
|
def inputworker(plugin)
|
@@ -328,7 +350,6 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
328
350
|
def stop_inputs
|
329
351
|
@logger.debug("Closing inputs", default_logging_keys)
|
330
352
|
inputs.each(&:do_stop)
|
331
|
-
@java_inputs_controller.stopInputs
|
332
353
|
@logger.debug("Closed inputs", default_logging_keys)
|
333
354
|
end
|
334
355
|
|
@@ -377,7 +398,7 @@ module LogStash; class JavaPipeline < JavaBasePipeline
|
|
377
398
|
end
|
378
399
|
|
379
400
|
def plugin_threads_info
|
380
|
-
input_threads = @input_threads.select {|t| t.alive? }
|
401
|
+
input_threads = @input_threads.select {|t| t.class == Thread && t.alive? }
|
381
402
|
worker_threads = @worker_threads.select {|t| t.alive? }
|
382
403
|
(input_threads + worker_threads).map {|t| Util.thread_info(t) }
|
383
404
|
end
|
@@ -10,7 +10,6 @@ require "resolv"
|
|
10
10
|
|
11
11
|
# make sure we abort if a known correct JRuby version is installed
|
12
12
|
# to avoid having an unnecessary legacy patch being applied in the future.
|
13
|
-
raise("Unnecessary patch on resolv.rb for JRuby version 9.1.16+") if Gem::Version.new(JRUBY_VERSION) >= Gem::Version.new("9.1.16.0")
|
14
13
|
|
15
14
|
# The code below is copied from JRuby 9.1.16.0 resolv.rb:
|
16
15
|
# https://github.com/jruby/jruby/blob/9.1.16.0/lib/ruby/stdlib/resolv.rb#L775-L784
|
@@ -18,23 +17,3 @@ raise("Unnecessary patch on resolv.rb for JRuby version 9.1.16+") if Gem::Versio
|
|
18
17
|
# JRuby is Copyright (c) 2007-2017 The JRuby project, and is released
|
19
18
|
# under a tri EPL/GPL/LGPL license.
|
20
19
|
# Full license available at https://github.com/jruby/jruby/blob/9.1.16.0/COPYING
|
21
|
-
|
22
|
-
class Resolv
|
23
|
-
class DNS
|
24
|
-
class Requester
|
25
|
-
class UnconnectedUDP
|
26
|
-
def sender(msg, data, host, port=Port)
|
27
|
-
sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"]
|
28
|
-
return nil if !sock
|
29
|
-
service = [IPAddr.new(host), port]
|
30
|
-
id = DNS.allocate_request_id(service[0], service[1])
|
31
|
-
request = msg.encode
|
32
|
-
request[0,2] = [id].pack('n')
|
33
|
-
return @senders[[service, id]] =
|
34
|
-
Sender.new(request, data, sock, host, port)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|