logstash-core 5.2.2-java → 5.3.0-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-core/logstash-core.jar +0 -0
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash/agent.rb +21 -17
- data/lib/logstash/api/commands/node.rb +4 -3
- data/lib/logstash/api/commands/stats.rb +4 -6
- data/lib/logstash/filter_delegator.rb +2 -1
- data/lib/logstash/output_delegator.rb +4 -0
- data/lib/logstash/pipeline.rb +30 -54
- data/lib/logstash/plugin.rb +8 -0
- data/lib/logstash/queue_factory.rb +36 -0
- data/lib/logstash/runner.rb +2 -2
- data/lib/logstash/version.rb +1 -1
- data/spec/api/spec_helper.rb +1 -1
- data/spec/conditionals_spec.rb +1 -1
- data/spec/logstash/agent_spec.rb +76 -56
- data/spec/logstash/pipeline_spec.rb +6 -4
- data/spec/logstash/plugin_spec.rb +35 -0
- data/spec/logstash/queue_factory_spec.rb +83 -0
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32438210f44fc19cf00eefbd7dc9b439936be0dd
|
4
|
+
data.tar.gz: 67e8f76e6c310aa08de14edce2170e8658c08d6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9a50f2852a3cee3dcf045d56f5650e4d521e0e792fb557e326e1fd70b42dd57f843ebc43c1c5d74d967d706e0d51a73ffc0a87a402ef32426f6128e404a0a42
|
7
|
+
data.tar.gz: 2f03c599450bf46ae2db2a367360710a5b693dfcf3f1d81b0f342ebcbf69de2c0e87a2a79619ae8c73c4914659b58dabcd8be5cb798db80e3e18230f0ee248b0
|
Binary file
|
data/lib/logstash/agent.rb
CHANGED
@@ -88,13 +88,13 @@ class LogStash::Agent
|
|
88
88
|
# @param pipeline_id [String] pipeline string identifier
|
89
89
|
# @param settings [Hash] settings that will be passed when creating the pipeline.
|
90
90
|
# keys should be symbols such as :pipeline_workers and :pipeline_batch_delay
|
91
|
-
def register_pipeline(
|
91
|
+
def register_pipeline(settings)
|
92
92
|
pipeline_settings = settings.clone
|
93
|
-
pipeline_settings.
|
93
|
+
pipeline_id = pipeline_settings.get("pipeline.id")
|
94
94
|
|
95
95
|
pipeline = create_pipeline(pipeline_settings)
|
96
96
|
return unless pipeline.is_a?(LogStash::Pipeline)
|
97
|
-
if @auto_reload && pipeline.
|
97
|
+
if @auto_reload && !pipeline.reloadable?
|
98
98
|
@logger.error(I18n.t("logstash.agent.non_reloadable_config_register"),
|
99
99
|
:pipeline_id => pipeline_id,
|
100
100
|
:plugins => pipeline.non_reloadable_plugins.map(&:class))
|
@@ -222,16 +222,13 @@ class LogStash::Agent
|
|
222
222
|
@collector = LogStash::Instrument::Collector.new
|
223
223
|
|
224
224
|
@metric = if collect_metrics?
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
225
|
+
@logger.debug("Agent: Configuring metric collection")
|
226
|
+
LogStash::Instrument::Metric.new(@collector)
|
227
|
+
else
|
228
|
+
LogStash::Instrument::NullMetric.new(@collector)
|
229
|
+
end
|
231
230
|
|
232
|
-
@periodic_pollers = LogStash::Instrument::PeriodicPollers.new(@metric,
|
233
|
-
settings.get("queue.type"),
|
234
|
-
self)
|
231
|
+
@periodic_pollers = LogStash::Instrument::PeriodicPollers.new(@metric, settings.get("queue.type"), self)
|
235
232
|
@periodic_pollers.start
|
236
233
|
end
|
237
234
|
|
@@ -261,13 +258,18 @@ class LogStash::Agent
|
|
261
258
|
end
|
262
259
|
end
|
263
260
|
|
261
|
+
# create a new pipeline with the given settings and config, if the pipeline initialization failed
|
262
|
+
# increment the failures metrics
|
263
|
+
# @param settings [Settings] the setting for the new pipelines
|
264
|
+
# @param config [String] the configuration string or nil to fetch the configuration per settings
|
265
|
+
# @return [Pipeline] the new pipeline or nil if it failed
|
264
266
|
def create_pipeline(settings, config = nil)
|
265
267
|
if config.nil?
|
266
268
|
begin
|
267
269
|
config = fetch_config(settings)
|
268
270
|
rescue => e
|
269
271
|
@logger.error("failed to fetch pipeline configuration", :message => e.message)
|
270
|
-
return
|
272
|
+
return nil
|
271
273
|
end
|
272
274
|
end
|
273
275
|
|
@@ -275,7 +277,7 @@ class LogStash::Agent
|
|
275
277
|
LogStash::Pipeline.new(config, settings, metric)
|
276
278
|
rescue => e
|
277
279
|
increment_reload_failures_metrics(settings.get("pipeline.id"), e.message, e.backtrace)
|
278
|
-
return
|
280
|
+
return nil
|
279
281
|
end
|
280
282
|
end
|
281
283
|
|
@@ -297,7 +299,7 @@ class LogStash::Agent
|
|
297
299
|
|
298
300
|
# check if this pipeline is not reloadable. it should not happen as per the check below
|
299
301
|
# but keep it here as a safety net if a reloadable pipeline was releoaded with a non reloadable pipeline
|
300
|
-
if old_pipeline.
|
302
|
+
if !old_pipeline.reloadable?
|
301
303
|
@logger.error("pipeline is not reloadable", :pipeline => id)
|
302
304
|
return
|
303
305
|
end
|
@@ -312,7 +314,7 @@ class LogStash::Agent
|
|
312
314
|
end
|
313
315
|
|
314
316
|
# check if the new pipeline will be reloadable in which case we want to log that as an error and abort
|
315
|
-
if pipeline_validator.
|
317
|
+
if !pipeline_validator.reloadable?
|
316
318
|
@logger.error(I18n.t("logstash.agent.non_reloadable_config_reload"), :pipeline_id => id, :plugins => pipeline_validator.non_reloadable_plugins.map(&:class))
|
317
319
|
increment_reload_failures_metrics(id, "non reloadable pipeline")
|
318
320
|
return
|
@@ -351,7 +353,7 @@ class LogStash::Agent
|
|
351
353
|
|
352
354
|
# check if the new pipeline will be reloadable in which case we want to log that as an error and abort. this should normally not
|
353
355
|
# happen since the check should be done in reload_pipeline! prior to get here.
|
354
|
-
if new_pipeline.
|
356
|
+
if !new_pipeline.reloadable?
|
355
357
|
@logger.error(I18n.t("logstash.agent.non_reloadable_config_reload"), :pipeline_id => pipeline_id, :plugins => new_pipeline.non_reloadable_plugins.map(&:class))
|
356
358
|
increment_reload_failures_metrics(pipeline_id, "non reloadable pipeline")
|
357
359
|
new_pipeline.close
|
@@ -393,6 +395,8 @@ class LogStash::Agent
|
|
393
395
|
n.gauge(:last_failure_timestamp, LogStash::Timestamp.now)
|
394
396
|
end
|
395
397
|
@logger.error("Pipeline aborted due to error", :exception => e, :backtrace => e.backtrace)
|
398
|
+
|
399
|
+
# TODO: this is weird, why dont we return directly here? any reason we need to enter the while true loop below?!
|
396
400
|
end
|
397
401
|
end
|
398
402
|
while true do
|
@@ -17,11 +17,12 @@ module LogStash
|
|
17
17
|
payload
|
18
18
|
end
|
19
19
|
|
20
|
-
def pipeline
|
21
|
-
extract_metrics(
|
22
|
-
[:stats, :pipelines,
|
20
|
+
def pipeline(pipeline_id = LogStash::SETTINGS.get("pipeline.id").to_sym)
|
21
|
+
stats = extract_metrics(
|
22
|
+
[:stats, :pipelines, pipeline_id, :config],
|
23
23
|
:workers, :batch_size, :batch_delay, :config_reload_automatic, :config_reload_interval
|
24
24
|
)
|
25
|
+
stats.merge(:id => pipeline_id)
|
25
26
|
end
|
26
27
|
|
27
28
|
def os
|
@@ -45,9 +45,10 @@ module LogStash
|
|
45
45
|
)
|
46
46
|
end
|
47
47
|
|
48
|
-
def pipeline
|
49
|
-
stats = service.get_shallow(:stats, :pipelines)
|
50
|
-
PluginsStats.report(stats)
|
48
|
+
def pipeline(pipeline_id = LogStash::SETTINGS.get("pipeline.id").to_sym)
|
49
|
+
stats = service.get_shallow(:stats, :pipelines, pipeline_id)
|
50
|
+
stats = PluginsStats.report(stats)
|
51
|
+
stats.merge(:id => pipeline_id)
|
51
52
|
end
|
52
53
|
|
53
54
|
def memory
|
@@ -98,9 +99,6 @@ module LogStash
|
|
98
99
|
end
|
99
100
|
|
100
101
|
def report(stats)
|
101
|
-
# Only one pipeline right now.
|
102
|
-
stats = stats[:main]
|
103
|
-
|
104
102
|
{
|
105
103
|
:events => stats[:events],
|
106
104
|
:plugins => {
|
data/lib/logstash/pipeline.rb
CHANGED
@@ -5,8 +5,6 @@ require "concurrent"
|
|
5
5
|
require "logstash/namespace"
|
6
6
|
require "logstash/errors"
|
7
7
|
require "logstash-core/logstash-core"
|
8
|
-
require "logstash/util/wrapped_acked_queue"
|
9
|
-
require "logstash/util/wrapped_synchronous_queue"
|
10
8
|
require "logstash/event"
|
11
9
|
require "logstash/config/file"
|
12
10
|
require "logstash/filters/base"
|
@@ -21,16 +19,13 @@ require "logstash/instrument/namespaced_null_metric"
|
|
21
19
|
require "logstash/instrument/collector"
|
22
20
|
require "logstash/output_delegator"
|
23
21
|
require "logstash/filter_delegator"
|
22
|
+
require "logstash/queue_factory"
|
24
23
|
|
25
24
|
module LogStash; class BasePipeline
|
26
25
|
include LogStash::Util::Loggable
|
27
26
|
|
28
27
|
attr_reader :config_str, :config_hash, :inputs, :filters, :outputs, :pipeline_id
|
29
28
|
|
30
|
-
RELOAD_INCOMPATIBLE_PLUGINS = [
|
31
|
-
"LogStash::Inputs::Stdin"
|
32
|
-
]
|
33
|
-
|
34
29
|
def initialize(config_str, settings = SETTINGS)
|
35
30
|
@logger = self.logger
|
36
31
|
@config_str = config_str
|
@@ -75,27 +70,25 @@ module LogStash; class BasePipeline
|
|
75
70
|
args = args.reduce({}, &:merge)
|
76
71
|
|
77
72
|
id = if args["id"].nil? || args["id"].empty?
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
73
|
+
args["id"] = "#{@config_hash}-#{@plugin_counter}"
|
74
|
+
else
|
75
|
+
args["id"]
|
76
|
+
end
|
82
77
|
|
83
78
|
raise ConfigurationError, "Two plugins have the id '#{id}', please fix this conflict" if @plugins_by_id[id]
|
84
|
-
|
85
79
|
@plugins_by_id[id] = true
|
86
80
|
|
87
81
|
# use NullMetric if called in the BasePipeline context otherwise use the @metric value
|
88
82
|
metric = @metric || Instrument::NullMetric.new
|
89
83
|
|
90
84
|
pipeline_scoped_metric = metric.namespace([:stats, :pipelines, pipeline_id.to_s.to_sym, :plugins])
|
91
|
-
|
92
85
|
# Scope plugins of type 'input' to 'inputs'
|
93
86
|
type_scoped_metric = pipeline_scoped_metric.namespace("#{plugin_type}s".to_sym)
|
94
87
|
|
95
88
|
klass = Plugin.lookup(plugin_type, name)
|
96
89
|
|
97
90
|
if plugin_type == "output"
|
98
|
-
OutputDelegator.new(@logger, klass, type_scoped_metric,
|
91
|
+
OutputDelegator.new(@logger, klass, type_scoped_metric, OutputDelegatorStrategyRegistry.instance, args)
|
99
92
|
elsif plugin_type == "filter"
|
100
93
|
FilterDelegator.new(@logger, klass, type_scoped_metric, args)
|
101
94
|
else # input
|
@@ -105,10 +98,12 @@ module LogStash; class BasePipeline
|
|
105
98
|
end
|
106
99
|
end
|
107
100
|
|
101
|
+
def reloadable?
|
102
|
+
non_reloadable_plugins.empty?
|
103
|
+
end
|
104
|
+
|
108
105
|
def non_reloadable_plugins
|
109
|
-
(inputs + filters + outputs).select
|
110
|
-
RELOAD_INCOMPATIBLE_PLUGINS.include?(plugin.class.name)
|
111
|
-
end
|
106
|
+
(inputs + filters + outputs).select { |plugin| !plugin.reloadable? }
|
112
107
|
end
|
113
108
|
end; end
|
114
109
|
|
@@ -129,13 +124,13 @@ module LogStash; class Pipeline < BasePipeline
|
|
129
124
|
MAX_INFLIGHT_WARN_THRESHOLD = 10_000
|
130
125
|
|
131
126
|
def initialize(config_str, settings = SETTINGS, namespaced_metric = nil)
|
132
|
-
# This needs to be configured before we evaluate the code to make
|
127
|
+
# This needs to be configured before we call super which will evaluate the code to make
|
133
128
|
# sure the metric instance is correctly send to the plugins to make the namespace scoping work
|
134
129
|
@metric = if namespaced_metric
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
130
|
+
settings.get("metric.collect") ? namespaced_metric : Instrument::NullMetric.new(namespaced_metric.collector)
|
131
|
+
else
|
132
|
+
Instrument::NullMetric.new
|
133
|
+
end
|
139
134
|
|
140
135
|
@settings = settings
|
141
136
|
@reporter = PipelineReporter.new(@logger, self)
|
@@ -143,7 +138,13 @@ module LogStash; class Pipeline < BasePipeline
|
|
143
138
|
|
144
139
|
super(config_str, settings)
|
145
140
|
|
146
|
-
|
141
|
+
begin
|
142
|
+
@queue = LogStash::QueueFactory.create(settings)
|
143
|
+
rescue => e
|
144
|
+
@logger.error("Logstash failed to create queue", "exception" => e.message, "backtrace" => e.backtrace)
|
145
|
+
raise e
|
146
|
+
end
|
147
|
+
|
147
148
|
@input_queue_client = @queue.write_client
|
148
149
|
@filter_queue_client = @queue.read_client
|
149
150
|
@signal_queue = Queue.new
|
@@ -164,32 +165,6 @@ module LogStash; class Pipeline < BasePipeline
|
|
164
165
|
@flushing = Concurrent::AtomicReference.new(false)
|
165
166
|
end # def initialize
|
166
167
|
|
167
|
-
def build_queue_from_settings
|
168
|
-
queue_type = settings.get("queue.type")
|
169
|
-
queue_page_capacity = settings.get("queue.page_capacity")
|
170
|
-
queue_max_bytes = settings.get("queue.max_bytes")
|
171
|
-
queue_max_events = settings.get("queue.max_events")
|
172
|
-
checkpoint_max_acks = settings.get("queue.checkpoint.acks")
|
173
|
-
checkpoint_max_writes = settings.get("queue.checkpoint.writes")
|
174
|
-
checkpoint_max_interval = settings.get("queue.checkpoint.interval")
|
175
|
-
|
176
|
-
if queue_type == "memory_acked"
|
177
|
-
# memory_acked is used in tests/specs
|
178
|
-
LogStash::Util::WrappedAckedQueue.create_memory_based("", queue_page_capacity, queue_max_events, queue_max_bytes)
|
179
|
-
elsif queue_type == "memory"
|
180
|
-
# memory is the legacy and default setting
|
181
|
-
LogStash::Util::WrappedSynchronousQueue.new()
|
182
|
-
elsif queue_type == "persisted"
|
183
|
-
# persisted is the disk based acked queue
|
184
|
-
queue_path = settings.get("path.queue")
|
185
|
-
LogStash::Util::WrappedAckedQueue.create_file_based(queue_path, queue_page_capacity, queue_max_events, checkpoint_max_writes, checkpoint_max_acks, checkpoint_max_interval, queue_max_bytes)
|
186
|
-
else
|
187
|
-
raise(ConfigurationError, "invalid queue.type setting")
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
private :build_queue_from_settings
|
192
|
-
|
193
168
|
def ready?
|
194
169
|
@ready.value
|
195
170
|
end
|
@@ -390,8 +365,9 @@ module LogStash; class Pipeline < BasePipeline
|
|
390
365
|
# Users need to check their configuration or see if there is a bug in the
|
391
366
|
# plugin.
|
392
367
|
@logger.error("Exception in pipelineworker, the pipeline stopped processing new events, please check your filter configuration and restart Logstash.",
|
393
|
-
"exception" => e, "backtrace" => e.backtrace)
|
394
|
-
|
368
|
+
"exception" => e.message, "backtrace" => e.backtrace)
|
369
|
+
|
370
|
+
raise e
|
395
371
|
end
|
396
372
|
|
397
373
|
# Take an array of events and send them to the correct output
|
@@ -450,7 +426,7 @@ module LogStash; class Pipeline < BasePipeline
|
|
450
426
|
rescue => e
|
451
427
|
if plugin.stop?
|
452
428
|
@logger.debug("Input plugin raised exception during shutdown, ignoring it.",
|
453
|
-
:plugin => plugin.class.config_name, :exception => e,
|
429
|
+
:plugin => plugin.class.config_name, :exception => e.message,
|
454
430
|
:backtrace => e.backtrace)
|
455
431
|
return
|
456
432
|
end
|
@@ -458,12 +434,12 @@ module LogStash; class Pipeline < BasePipeline
|
|
458
434
|
# otherwise, report error and restart
|
459
435
|
if @logger.debug?
|
460
436
|
@logger.error(I18n.t("logstash.pipeline.worker-error-debug",
|
461
|
-
:plugin => plugin.inspect, :error => e.
|
437
|
+
:plugin => plugin.inspect, :error => e.message,
|
462
438
|
:exception => e.class,
|
463
439
|
:stacktrace => e.backtrace.join("\n")))
|
464
440
|
else
|
465
441
|
@logger.error(I18n.t("logstash.pipeline.worker-error",
|
466
|
-
:plugin => plugin.inspect, :error => e))
|
442
|
+
:plugin => plugin.inspect, :error => e.message))
|
467
443
|
end
|
468
444
|
|
469
445
|
# Assuming the failure that caused this exception is transient,
|
@@ -628,4 +604,4 @@ module LogStash; class Pipeline < BasePipeline
|
|
628
604
|
:flushing => @flushing
|
629
605
|
}
|
630
606
|
end
|
631
|
-
end
|
607
|
+
end end
|
data/lib/logstash/plugin.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "fileutils"
|
3
|
+
require "logstash/event"
|
4
|
+
require "logstash/namespace"
|
5
|
+
require "logstash/util/wrapped_acked_queue"
|
6
|
+
require "logstash/util/wrapped_synchronous_queue"
|
7
|
+
|
8
|
+
module LogStash
|
9
|
+
class QueueFactory
|
10
|
+
def self.create(settings)
|
11
|
+
queue_type = settings.get("queue.type")
|
12
|
+
queue_page_capacity = settings.get("queue.page_capacity")
|
13
|
+
queue_max_bytes = settings.get("queue.max_bytes")
|
14
|
+
queue_max_events = settings.get("queue.max_events")
|
15
|
+
checkpoint_max_acks = settings.get("queue.checkpoint.acks")
|
16
|
+
checkpoint_max_writes = settings.get("queue.checkpoint.writes")
|
17
|
+
checkpoint_max_interval = settings.get("queue.checkpoint.interval")
|
18
|
+
|
19
|
+
case queue_type
|
20
|
+
when "memory_acked"
|
21
|
+
# memory_acked is used in tests/specs
|
22
|
+
LogStash::Util::WrappedAckedQueue.create_memory_based("", queue_page_capacity, queue_max_events, queue_max_bytes)
|
23
|
+
when "memory"
|
24
|
+
# memory is the legacy and default setting
|
25
|
+
LogStash::Util::WrappedSynchronousQueue.new
|
26
|
+
when "persisted"
|
27
|
+
# persisted is the disk based acked queue
|
28
|
+
queue_path = ::File.join(settings.get("path.queue"), settings.get("pipeline.id"))
|
29
|
+
FileUtils.mkdir_p(queue_path)
|
30
|
+
LogStash::Util::WrappedAckedQueue.create_file_based(queue_path, queue_page_capacity, queue_max_events, checkpoint_max_writes, checkpoint_max_acks, checkpoint_max_interval, queue_max_bytes)
|
31
|
+
else
|
32
|
+
raise ConfigurationError, "Invalid setting `#{queue_type}` for `queue.type`, supported types are: 'memory_acked', 'memory', 'persisted'"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/logstash/runner.rb
CHANGED
@@ -200,7 +200,7 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
200
200
|
# override log level that may have been introduced from a custom log4j config file
|
201
201
|
LogStash::Logging::Logger::configure_logging(setting("log.level"))
|
202
202
|
|
203
|
-
if setting("config.debug") && logger.debug?
|
203
|
+
if setting("config.debug") && !logger.debug?
|
204
204
|
logger.warn("--config.debug was specified, but log.level was not set to \'debug\'! No config info will be logged.")
|
205
205
|
end
|
206
206
|
|
@@ -261,7 +261,7 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
261
261
|
|
262
262
|
@agent = create_agent(@settings)
|
263
263
|
|
264
|
-
@agent.register_pipeline(
|
264
|
+
@agent.register_pipeline(@settings)
|
265
265
|
|
266
266
|
# enable sigint/sigterm before starting the agent
|
267
267
|
# to properly handle a stalled agent
|
data/lib/logstash/version.rb
CHANGED
data/spec/api/spec_helper.rb
CHANGED
@@ -59,7 +59,7 @@ class LogStashRunner
|
|
59
59
|
def start
|
60
60
|
# We start a pipeline that will generate a finite number of events
|
61
61
|
# before starting the expectations
|
62
|
-
agent.register_pipeline(
|
62
|
+
agent.register_pipeline(@settings)
|
63
63
|
@agent_task = Stud::Task.new { agent.execute }
|
64
64
|
@agent_task.wait
|
65
65
|
end
|
data/spec/conditionals_spec.rb
CHANGED
@@ -287,7 +287,7 @@ describe "conditionals in filter" do
|
|
287
287
|
conditional "!([message] <= 'sample')" do
|
288
288
|
sample("apple") { expect(subject.get("tags")).not_to include("success") }
|
289
289
|
sample("zebra") { expect(subject.get("tags")).not_to include("failure") }
|
290
|
-
sample("sample") { expect(subject.get("tags")).not_to include("success")
|
290
|
+
sample("sample") { expect(subject.get("tags")).not_to include("success")}
|
291
291
|
end
|
292
292
|
|
293
293
|
conditional "!([message] >= 'sample')" do
|
data/spec/logstash/agent_spec.rb
CHANGED
@@ -9,13 +9,14 @@ require_relative "../support/helpers"
|
|
9
9
|
describe LogStash::Agent do
|
10
10
|
|
11
11
|
let(:agent_settings) { LogStash::SETTINGS }
|
12
|
+
let(:default_pipeline_id) { LogStash::SETTINGS.get("pipeline.id") }
|
12
13
|
let(:agent_args) { {} }
|
13
14
|
let(:pipeline_settings) { agent_settings.clone }
|
14
15
|
let(:pipeline_args) { {} }
|
15
16
|
let(:config_file) { Stud::Temporary.pathname }
|
16
17
|
let(:config_file_txt) { "input { generator { count => 100000 } } output { }" }
|
17
18
|
|
18
|
-
|
19
|
+
subject { LogStash::Agent.new(agent_settings) }
|
19
20
|
|
20
21
|
before :each do
|
21
22
|
# This MUST run first, before `subject` is invoked to ensure clean state
|
@@ -41,7 +42,6 @@ describe LogStash::Agent do
|
|
41
42
|
end
|
42
43
|
|
43
44
|
describe "register_pipeline" do
|
44
|
-
let(:pipeline_id) { "main" }
|
45
45
|
let(:config_string) { "input { } filter { } output { }" }
|
46
46
|
let(:agent_args) do
|
47
47
|
{
|
@@ -61,7 +61,7 @@ describe LogStash::Agent do
|
|
61
61
|
expect(arg1).to eq(config_string)
|
62
62
|
expect(arg2.to_hash).to include(agent_args)
|
63
63
|
end
|
64
|
-
subject.register_pipeline(
|
64
|
+
subject.register_pipeline(agent_settings)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -79,7 +79,7 @@ describe LogStash::Agent do
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
|
82
|
+
describe "#execute" do
|
83
83
|
let(:config_file_txt) { "input { generator { count => 100000 } } output { }" }
|
84
84
|
|
85
85
|
before :each do
|
@@ -94,10 +94,9 @@ describe LogStash::Agent do
|
|
94
94
|
"path.config" => config_file
|
95
95
|
}
|
96
96
|
end
|
97
|
-
let(:pipeline_id) { "main" }
|
98
97
|
|
99
98
|
before(:each) do
|
100
|
-
subject.register_pipeline(
|
99
|
+
subject.register_pipeline(pipeline_settings)
|
101
100
|
end
|
102
101
|
|
103
102
|
context "if state is clean" do
|
@@ -110,7 +109,10 @@ describe LogStash::Agent do
|
|
110
109
|
it "should not reload_state!" do
|
111
110
|
expect(subject).to_not receive(:reload_state!)
|
112
111
|
t = Thread.new { subject.execute }
|
113
|
-
|
112
|
+
|
113
|
+
# TODO: refactor this. forcing an arbitrary fixed delay for thread concurrency issues is an indication of
|
114
|
+
# a bad test design or missing class functionality.
|
115
|
+
sleep(0.1)
|
114
116
|
Stud.stop!(t)
|
115
117
|
t.join
|
116
118
|
subject.shutdown
|
@@ -123,11 +125,14 @@ describe LogStash::Agent do
|
|
123
125
|
|
124
126
|
it "does not upgrade the new config" do
|
125
127
|
t = Thread.new { subject.execute }
|
126
|
-
sleep
|
128
|
+
sleep(0.1) until subject.running_pipelines? && subject.pipelines.values.first.ready?
|
127
129
|
expect(subject).to_not receive(:upgrade_pipeline)
|
128
130
|
File.open(config_file, "w") { |f| f.puts second_pipeline_config }
|
129
131
|
subject.send(:"reload_pipeline!", "main")
|
130
|
-
|
132
|
+
|
133
|
+
# TODO: refactor this. forcing an arbitrary fixed delay for thread concurrency issues is an indication of
|
134
|
+
# a bad test design or missing class functionality.
|
135
|
+
sleep(0.1)
|
131
136
|
Stud.stop!(t)
|
132
137
|
t.join
|
133
138
|
subject.shutdown
|
@@ -139,14 +144,16 @@ describe LogStash::Agent do
|
|
139
144
|
|
140
145
|
it "does upgrade the new config" do
|
141
146
|
t = Thread.new { subject.execute }
|
142
|
-
sleep
|
147
|
+
sleep(0.1) until subject.running_pipelines? && subject.pipelines.values.first.ready?
|
143
148
|
expect(subject).to receive(:upgrade_pipeline).once.and_call_original
|
144
149
|
File.open(config_file, "w") { |f| f.puts second_pipeline_config }
|
145
150
|
subject.send(:"reload_pipeline!", "main")
|
146
|
-
|
151
|
+
|
152
|
+
# TODO: refactor this. forcing an arbitrary fixed delay for thread concurrency issues is an indication of
|
153
|
+
# a bad test design or missing class functionality.
|
154
|
+
sleep(0.1)
|
147
155
|
Stud.stop!(t)
|
148
156
|
t.join
|
149
|
-
|
150
157
|
subject.shutdown
|
151
158
|
end
|
152
159
|
end
|
@@ -159,14 +166,16 @@ describe LogStash::Agent do
|
|
159
166
|
|
160
167
|
it "does not try to reload the pipeline" do
|
161
168
|
t = Thread.new { subject.execute }
|
162
|
-
sleep
|
169
|
+
sleep(0.01) until subject.running_pipelines? && subject.pipelines.values.first.running?
|
163
170
|
expect(subject).to_not receive(:reload_pipeline!)
|
164
171
|
File.open(config_file, "w") { |f| f.puts second_pipeline_config }
|
165
172
|
subject.reload_state!
|
166
|
-
|
173
|
+
|
174
|
+
# TODO: refactor this. forcing an arbitrary fixed delay for thread concurrency issues is an indication of
|
175
|
+
# a bad test design or missing class functionality.
|
176
|
+
sleep(0.1)
|
167
177
|
Stud.stop!(t)
|
168
178
|
t.join
|
169
|
-
|
170
179
|
subject.shutdown
|
171
180
|
end
|
172
181
|
end
|
@@ -177,14 +186,16 @@ describe LogStash::Agent do
|
|
177
186
|
|
178
187
|
it "tries to reload the pipeline" do
|
179
188
|
t = Thread.new { subject.execute }
|
180
|
-
sleep
|
189
|
+
sleep(0.01) until subject.running_pipelines? && subject.pipelines.values.first.running?
|
181
190
|
expect(subject).to receive(:reload_pipeline!).once.and_call_original
|
182
191
|
File.open(config_file, "w") { |f| f.puts second_pipeline_config }
|
183
192
|
subject.reload_state!
|
184
|
-
|
193
|
+
|
194
|
+
# TODO: refactor this. forcing an arbitrary fixed delay for thread concurrency issues is an indication of
|
195
|
+
# a bad test design or missing class functionality.
|
196
|
+
sleep(0.1)
|
185
197
|
Stud.stop!(t)
|
186
198
|
t.join
|
187
|
-
|
188
199
|
subject.shutdown
|
189
200
|
end
|
190
201
|
end
|
@@ -199,19 +210,21 @@ describe LogStash::Agent do
|
|
199
210
|
"path.config" => config_file,
|
200
211
|
}
|
201
212
|
end
|
202
|
-
let(:pipeline_id) { "main" }
|
203
213
|
|
204
214
|
before(:each) do
|
205
|
-
subject.register_pipeline(
|
215
|
+
subject.register_pipeline(pipeline_settings)
|
206
216
|
end
|
207
217
|
|
208
218
|
context "if state is clean" do
|
209
219
|
it "should periodically reload_state" do
|
210
220
|
allow(subject).to receive(:clean_state?).and_return(false)
|
211
221
|
t = Thread.new { subject.execute }
|
212
|
-
sleep
|
222
|
+
sleep(0.01) until subject.running_pipelines? && subject.pipelines.values.first.running?
|
213
223
|
expect(subject).to receive(:reload_state!).at_least(2).times
|
214
|
-
|
224
|
+
|
225
|
+
# TODO: refactor this. forcing an arbitrary fixed delay for thread concurrency issues is an indication of
|
226
|
+
# a bad test design or missing class functionality.
|
227
|
+
sleep(0.1)
|
215
228
|
Stud.stop!(t)
|
216
229
|
t.join
|
217
230
|
subject.shutdown
|
@@ -224,10 +237,13 @@ describe LogStash::Agent do
|
|
224
237
|
|
225
238
|
it "does not upgrade the new config" do
|
226
239
|
t = Thread.new { subject.execute }
|
227
|
-
sleep
|
240
|
+
sleep(0.01) until subject.running_pipelines? && subject.pipelines.values.first.running?
|
228
241
|
expect(subject).to_not receive(:upgrade_pipeline)
|
229
242
|
File.open(config_file, "w") { |f| f.puts second_pipeline_config }
|
230
|
-
|
243
|
+
|
244
|
+
# TODO: refactor this. forcing an arbitrary fixed delay for thread concurrency issues is an indication of
|
245
|
+
# a bad test design or missing class functionality.
|
246
|
+
sleep(0.1)
|
231
247
|
Stud.stop!(t)
|
232
248
|
t.join
|
233
249
|
subject.shutdown
|
@@ -239,10 +255,13 @@ describe LogStash::Agent do
|
|
239
255
|
|
240
256
|
it "does upgrade the new config" do
|
241
257
|
t = Thread.new { subject.execute }
|
242
|
-
sleep
|
258
|
+
sleep(0.01) until subject.running_pipelines? && subject.pipelines.values.first.running?
|
243
259
|
expect(subject).to receive(:upgrade_pipeline).once.and_call_original
|
244
260
|
File.open(config_file, "w") { |f| f.puts second_pipeline_config }
|
245
|
-
|
261
|
+
|
262
|
+
# TODO: refactor this. forcing an arbitrary fixed delay for thread concurrency issues is an indication of
|
263
|
+
# a bad test design or missing class functionality.
|
264
|
+
sleep(0.1)
|
246
265
|
Stud.stop!(t)
|
247
266
|
t.join
|
248
267
|
subject.shutdown
|
@@ -253,7 +272,6 @@ describe LogStash::Agent do
|
|
253
272
|
end
|
254
273
|
|
255
274
|
describe "#reload_state!" do
|
256
|
-
let(:pipeline_id) { "main" }
|
257
275
|
let(:first_pipeline_config) { "input { } filter { } output { }" }
|
258
276
|
let(:second_pipeline_config) { "input { generator {} } filter { } output { }" }
|
259
277
|
let(:pipeline_args) { {
|
@@ -263,7 +281,7 @@ describe LogStash::Agent do
|
|
263
281
|
} }
|
264
282
|
|
265
283
|
before(:each) do
|
266
|
-
subject.register_pipeline(
|
284
|
+
subject.register_pipeline(pipeline_settings)
|
267
285
|
end
|
268
286
|
|
269
287
|
after(:each) do
|
@@ -273,7 +291,7 @@ describe LogStash::Agent do
|
|
273
291
|
context "when fetching a new state" do
|
274
292
|
it "upgrades the state" do
|
275
293
|
expect(subject).to receive(:fetch_config).and_return(second_pipeline_config)
|
276
|
-
expect(subject).to receive(:upgrade_pipeline).with(
|
294
|
+
expect(subject).to receive(:upgrade_pipeline).with(default_pipeline_id, kind_of(LogStash::Settings), second_pipeline_config)
|
277
295
|
subject.reload_state!
|
278
296
|
end
|
279
297
|
end
|
@@ -293,7 +311,6 @@ describe LogStash::Agent do
|
|
293
311
|
"config.reload.interval" => 0.01,
|
294
312
|
"config.string" => pipeline_config
|
295
313
|
} }
|
296
|
-
let(:pipeline_id) { "main" }
|
297
314
|
|
298
315
|
context "environment variable templating" do
|
299
316
|
before :each do
|
@@ -308,14 +325,13 @@ describe LogStash::Agent do
|
|
308
325
|
|
309
326
|
it "doesn't upgrade the state" do
|
310
327
|
allow(subject).to receive(:fetch_config).and_return(pipeline_config)
|
311
|
-
subject.register_pipeline(
|
312
|
-
expect(subject.pipelines[
|
328
|
+
subject.register_pipeline(pipeline_settings)
|
329
|
+
expect(subject.pipelines[default_pipeline_id].inputs.first.message).to eq("foo-bar")
|
313
330
|
end
|
314
331
|
end
|
315
332
|
end
|
316
333
|
|
317
334
|
describe "#upgrade_pipeline" do
|
318
|
-
let(:pipeline_id) { "main" }
|
319
335
|
let(:pipeline_config) { "input { } filter { } output { }" }
|
320
336
|
let(:pipeline_args) { {
|
321
337
|
"config.string" => pipeline_config,
|
@@ -324,10 +340,12 @@ describe LogStash::Agent do
|
|
324
340
|
let(:new_pipeline_config) { "input { generator {} } output { }" }
|
325
341
|
|
326
342
|
before(:each) do
|
327
|
-
subject.register_pipeline(
|
343
|
+
subject.register_pipeline(pipeline_settings)
|
328
344
|
end
|
329
345
|
|
330
346
|
after(:each) do
|
347
|
+
# new pipelines will be created part of the upgrade process so we need
|
348
|
+
# to close any initialized pipelines
|
331
349
|
subject.close_pipelines
|
332
350
|
end
|
333
351
|
|
@@ -336,42 +354,51 @@ describe LogStash::Agent do
|
|
336
354
|
allow(subject).to receive(:fetch_config).and_return(new_pipeline_config)
|
337
355
|
allow(subject).to receive(:create_pipeline).and_return(nil)
|
338
356
|
allow(subject).to receive(:stop_pipeline) do |id|
|
357
|
+
# we register_pipeline but we never execute them so we have to mock #stop_pipeline to
|
358
|
+
# not call Pipeline#shutdown but Pipeline#close
|
339
359
|
subject.close_pipeline(id)
|
340
360
|
end
|
341
361
|
end
|
342
362
|
|
343
363
|
it "leaves the state untouched" do
|
344
|
-
subject.send(:"reload_pipeline!",
|
345
|
-
expect(subject.pipelines[
|
364
|
+
subject.send(:"reload_pipeline!", default_pipeline_id)
|
365
|
+
expect(subject.pipelines[default_pipeline_id].config_str).to eq(pipeline_config)
|
346
366
|
end
|
347
367
|
|
348
368
|
context "and current state is empty" do
|
349
369
|
it "should not start a pipeline" do
|
350
370
|
expect(subject).to_not receive(:start_pipeline)
|
351
|
-
subject.send(:"reload_pipeline!",
|
371
|
+
subject.send(:"reload_pipeline!", default_pipeline_id)
|
352
372
|
end
|
353
373
|
end
|
354
374
|
end
|
355
375
|
|
356
376
|
context "when the upgrade succeeds" do
|
357
377
|
let(:new_config) { "input { generator { count => 1 } } output { }" }
|
378
|
+
|
358
379
|
before :each do
|
359
380
|
allow(subject).to receive(:fetch_config).and_return(new_config)
|
360
|
-
allow(subject).to receive(:start_pipeline)
|
381
|
+
allow(subject).to receive(:start_pipeline).and_return(true)
|
361
382
|
allow(subject).to receive(:stop_pipeline) do |id|
|
362
|
-
|
383
|
+
# we register_pipeline but we never execute them so we have to mock #stop_pipeline to
|
384
|
+
# not call Pipeline#shutdown but Pipeline#close
|
385
|
+
subject.close_pipeline(id)
|
363
386
|
end
|
364
387
|
end
|
388
|
+
|
365
389
|
it "updates the state" do
|
366
|
-
subject.send(:"reload_pipeline!",
|
367
|
-
expect(subject.pipelines[
|
390
|
+
subject.send(:"reload_pipeline!", default_pipeline_id)
|
391
|
+
expect(subject.pipelines[default_pipeline_id].config_str).to eq(new_config)
|
368
392
|
end
|
393
|
+
|
369
394
|
it "starts the pipeline" do
|
370
|
-
expect(subject).to receive(:start_pipeline)
|
395
|
+
expect(subject).to receive(:start_pipeline).and_return(true)
|
371
396
|
expect(subject).to receive(:stop_pipeline) do |id|
|
397
|
+
# we register_pipeline but we never execute them so we have to mock #stop_pipeline to
|
398
|
+
# not call Pipeline#shutdown but Pipeline#close
|
372
399
|
subject.close_pipeline(id)
|
373
400
|
end
|
374
|
-
subject.send(:"reload_pipeline!",
|
401
|
+
subject.send(:"reload_pipeline!", default_pipeline_id)
|
375
402
|
end
|
376
403
|
end
|
377
404
|
end
|
@@ -398,9 +425,9 @@ describe LogStash::Agent do
|
|
398
425
|
end
|
399
426
|
end
|
400
427
|
|
401
|
-
|
402
428
|
context "metrics after config reloading" do
|
403
429
|
let!(:config) { "input { generator { } } output { dummyoutput { } }" }
|
430
|
+
|
404
431
|
let!(:config_path) do
|
405
432
|
f = Stud::Temporary.file
|
406
433
|
f.write(config)
|
@@ -408,6 +435,7 @@ describe LogStash::Agent do
|
|
408
435
|
f.close
|
409
436
|
f.path
|
410
437
|
end
|
438
|
+
|
411
439
|
let(:pipeline_args) do
|
412
440
|
{
|
413
441
|
"pipeline.workers" => 2,
|
@@ -433,11 +461,12 @@ describe LogStash::Agent do
|
|
433
461
|
let(:initial_generator_threshold) { 1000 }
|
434
462
|
let(:pipeline_thread) do
|
435
463
|
Thread.new do
|
436
|
-
subject.register_pipeline(
|
464
|
+
subject.register_pipeline(pipeline_settings)
|
437
465
|
subject.execute
|
438
466
|
end
|
439
467
|
end
|
440
468
|
|
469
|
+
|
441
470
|
before :each do
|
442
471
|
allow(LogStash::Outputs::DroppingDummyOutput).to receive(:new).at_least(:once).with(anything).and_return(dummy_output)
|
443
472
|
allow(DummyOutput2).to receive(:new).at_least(:once).with(anything).and_return(dummy_output2)
|
@@ -451,13 +480,9 @@ describe LogStash::Agent do
|
|
451
480
|
Thread.abort_on_exception = true
|
452
481
|
|
453
482
|
pipeline_thread
|
454
|
-
# @t = Thread.new do
|
455
|
-
# subject.register_pipeline("main", pipeline_settings)
|
456
|
-
# subject.execute
|
457
|
-
# end
|
458
483
|
|
459
484
|
# wait for some events to reach the dummy_output
|
460
|
-
sleep(0.
|
485
|
+
sleep(0.1) until dummy_output.events_received > initial_generator_threshold
|
461
486
|
end
|
462
487
|
|
463
488
|
after :each do
|
@@ -523,12 +548,10 @@ describe LogStash::Agent do
|
|
523
548
|
value = snapshot.metric_store.get_with_path("/stats/pipelines")[:stats][:pipelines][:main][:reloads][:last_error].value
|
524
549
|
expect(value).to be(nil)
|
525
550
|
end
|
526
|
-
|
527
551
|
end
|
528
552
|
|
529
553
|
context "when reloading a bad config" do
|
530
554
|
let(:new_config) { "input { generator { count => " }
|
531
|
-
let(:new_config_generator_counter) { 500 }
|
532
555
|
before :each do
|
533
556
|
|
534
557
|
File.open(config_path, "w") do |f|
|
@@ -573,7 +596,6 @@ describe LogStash::Agent do
|
|
573
596
|
|
574
597
|
context "when reloading a config that raises exception on pipeline.run" do
|
575
598
|
let(:new_config) { "input { generator { count => 10000 } }" }
|
576
|
-
let(:new_config_generator_counter) { 500 }
|
577
599
|
|
578
600
|
class BrokenGenerator < LogStash::Inputs::Generator
|
579
601
|
def register
|
@@ -582,14 +604,12 @@ describe LogStash::Agent do
|
|
582
604
|
end
|
583
605
|
|
584
606
|
before :each do
|
585
|
-
|
586
607
|
allow(LogStash::Plugin).to receive(:lookup).with("input", "generator").and_return(BrokenGenerator)
|
587
608
|
|
588
609
|
File.open(config_path, "w") do |f|
|
589
610
|
f.write(new_config)
|
590
611
|
f.fsync
|
591
612
|
end
|
592
|
-
|
593
613
|
end
|
594
614
|
|
595
615
|
it "does not increase the successful reload count" do
|
@@ -600,7 +620,7 @@ describe LogStash::Agent do
|
|
600
620
|
}
|
601
621
|
end
|
602
622
|
|
603
|
-
it "increases the
|
623
|
+
it "increases the failures reload count" do
|
604
624
|
expect { subject.send(:"reload_pipeline!", "main") }.to change {
|
605
625
|
snapshot = subject.metric.collector.snapshot_metric
|
606
626
|
reload_metrics = snapshot.metric_store.get_with_path("/stats/pipelines")[:stats][:pipelines][:main][:reloads]
|
@@ -139,7 +139,7 @@ describe LogStash::Pipeline do
|
|
139
139
|
|
140
140
|
pipeline = LogStash::Pipeline.new(config, pipeline_settings_obj)
|
141
141
|
t = Thread.new { pipeline.run }
|
142
|
-
sleep
|
142
|
+
sleep(0.1) until pipeline.ready?
|
143
143
|
wait(3).for do
|
144
144
|
# give us a bit of time to flush the events
|
145
145
|
# puts("*****" + output.events.map{|e| e.message}.to_s)
|
@@ -366,7 +366,6 @@ describe LogStash::Pipeline do
|
|
366
366
|
|
367
367
|
sample(["foo", "bar"]) do
|
368
368
|
expect(subject.size).to eq(2)
|
369
|
-
|
370
369
|
expect(subject[0].get("message")).to eq("foo\nbar")
|
371
370
|
expect(subject[0].get("type")).to be_nil
|
372
371
|
expect(subject[1].get("message")).to eq("foo\nbar")
|
@@ -388,7 +387,9 @@ describe LogStash::Pipeline do
|
|
388
387
|
allow(LogStash::Plugin).to receive(:lookup).with("codec", "plain").and_return(DummyCodec)
|
389
388
|
allow(LogStash::Plugin).to receive(:lookup).with("output", "dummyoutput").and_return(::LogStash::Outputs::DummyOutput)
|
390
389
|
allow(logger).to receive(:warn)
|
391
|
-
|
390
|
+
|
391
|
+
# pipeline must be first called outside the thread context because it lazyly initialize and will create a
|
392
|
+
# race condition if called in the thread
|
392
393
|
p = pipeline
|
393
394
|
t = Thread.new { p.run }
|
394
395
|
sleep(0.1) until pipeline.ready?
|
@@ -596,7 +597,7 @@ describe LogStash::Pipeline do
|
|
596
597
|
Thread.abort_on_exception = true
|
597
598
|
pipeline = LogStash::Pipeline.new(config, pipeline_settings_obj)
|
598
599
|
t = Thread.new { pipeline.run }
|
599
|
-
sleep
|
600
|
+
sleep(0.1) until pipeline.ready?
|
600
601
|
wait(3).for do
|
601
602
|
# give us a bit of time to flush the events
|
602
603
|
output.events.empty?
|
@@ -699,6 +700,7 @@ describe LogStash::Pipeline do
|
|
699
700
|
s = subject
|
700
701
|
t = Thread.new { s.run }
|
701
702
|
sleep(0.1) until subject.ready?
|
703
|
+
|
702
704
|
sleep(0.1)
|
703
705
|
expect(subject.uptime).to be > 0
|
704
706
|
subject.shutdown
|
@@ -7,6 +7,41 @@ require "logstash/inputs/base"
|
|
7
7
|
require "logstash/filters/base"
|
8
8
|
|
9
9
|
describe LogStash::Plugin do
|
10
|
+
context "reloadable" do
|
11
|
+
context "by default" do
|
12
|
+
subject do
|
13
|
+
Class.new(LogStash::Plugin) do
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "makes .reloadable? return true" do
|
18
|
+
expect(subject.reloadable?).to be_truthy
|
19
|
+
end
|
20
|
+
|
21
|
+
it "makes #reloadable? return true" do
|
22
|
+
expect(subject.new({}).reloadable?).to be_truthy
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "user can overrides" do
|
27
|
+
subject do
|
28
|
+
Class.new(LogStash::Plugin) do
|
29
|
+
def self.reloadable?
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "makes .reloadable? return true" do
|
36
|
+
expect(subject.reloadable?).to be_falsey
|
37
|
+
end
|
38
|
+
|
39
|
+
it "makes #reloadable? return true" do
|
40
|
+
expect(subject.new({}).reloadable?).to be_falsey
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
10
45
|
it "should fail lookup on inexisting type" do
|
11
46
|
#expect_any_instance_of(Cabin::Channel).to receive(:debug).once
|
12
47
|
expect { LogStash::Plugin.lookup("badbadtype", "badname") }.to raise_error(LogStash::PluginLoadingError)
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/queue_factory"
|
3
|
+
require "logstash/settings"
|
4
|
+
require "stud/temporary"
|
5
|
+
|
6
|
+
describe LogStash::QueueFactory do
|
7
|
+
let(:pipeline_id) { "my_pipeline" }
|
8
|
+
let(:settings_array) do
|
9
|
+
[
|
10
|
+
LogStash::Setting::WritableDirectory.new("path.queue", Stud::Temporary.pathname),
|
11
|
+
LogStash::Setting::String.new("queue.type", "memory", true, ["persisted", "memory", "memory_acked"]),
|
12
|
+
LogStash::Setting::Bytes.new("queue.page_capacity", "250mb"),
|
13
|
+
LogStash::Setting::Bytes.new("queue.max_bytes", "1024mb"),
|
14
|
+
LogStash::Setting::Numeric.new("queue.max_events", 0),
|
15
|
+
LogStash::Setting::Numeric.new("queue.checkpoint.acks", 1024),
|
16
|
+
LogStash::Setting::Numeric.new("queue.checkpoint.writes", 1024),
|
17
|
+
LogStash::Setting::Numeric.new("queue.checkpoint.interval", 1000),
|
18
|
+
LogStash::Setting::String.new("pipeline.id", pipeline_id)
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:settings) do
|
23
|
+
s = LogStash::Settings.new
|
24
|
+
|
25
|
+
settings_array.each do |setting|
|
26
|
+
s.register(setting)
|
27
|
+
end
|
28
|
+
s
|
29
|
+
end
|
30
|
+
|
31
|
+
subject { described_class }
|
32
|
+
|
33
|
+
context "when `queue.type` is `persisted`" do
|
34
|
+
before do
|
35
|
+
settings.set("queue.type", "persisted")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns a `WrappedAckedQueue`" do
|
39
|
+
queue = subject.create(settings)
|
40
|
+
expect(queue).to be_kind_of(LogStash::Util::WrappedAckedQueue)
|
41
|
+
queue.close
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "per pipeline id subdirectory creation" do
|
45
|
+
let(:queue_path) { ::File.join(settings.get("path.queue"), pipeline_id) }
|
46
|
+
|
47
|
+
after :each do
|
48
|
+
FileUtils.rmdir(queue_path)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "creates a queue directory based on the pipeline id" do
|
52
|
+
expect(Dir.exist?(queue_path)).to be_falsey
|
53
|
+
queue = subject.create(settings)
|
54
|
+
expect(Dir.exist?(queue_path)).to be_truthy
|
55
|
+
queue.close
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when `queue.type` is `memory_acked`" do
|
61
|
+
before do
|
62
|
+
settings.set("queue.type", "memory_acked")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "returns a `WrappedAckedQueue`" do
|
66
|
+
queue = subject.create(settings)
|
67
|
+
expect(queue).to be_kind_of(LogStash::Util::WrappedAckedQueue)
|
68
|
+
queue.close
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when `queue.type` is `memory`" do
|
73
|
+
before do
|
74
|
+
settings.set("queue.type", "memory")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns a `WrappedAckedQueue`" do
|
78
|
+
queue = subject.create(settings)
|
79
|
+
expect(queue).to be_kind_of(LogStash::Util::WrappedSynchronousQueue)
|
80
|
+
queue.close
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
metadata
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.3.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
16
|
- - '='
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 5.
|
18
|
+
version: 5.3.0
|
19
19
|
name: logstash-core-event-java
|
20
20
|
prerelease: false
|
21
21
|
type: :runtime
|
@@ -23,13 +23,13 @@ dependencies:
|
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.
|
26
|
+
version: 5.3.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - '='
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 5.
|
32
|
+
version: 5.3.0
|
33
33
|
name: logstash-core-queue-jruby
|
34
34
|
prerelease: false
|
35
35
|
type: :runtime
|
@@ -37,7 +37,7 @@ dependencies:
|
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 5.
|
40
|
+
version: 5.3.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
@@ -405,6 +405,7 @@ files:
|
|
405
405
|
- lib/logstash/plugins/hooks_registry.rb
|
406
406
|
- lib/logstash/plugins/registry.rb
|
407
407
|
- lib/logstash/program.rb
|
408
|
+
- lib/logstash/queue_factory.rb
|
408
409
|
- lib/logstash/runner.rb
|
409
410
|
- lib/logstash/settings.rb
|
410
411
|
- lib/logstash/shutdown_watcher.rb
|
@@ -482,6 +483,7 @@ files:
|
|
482
483
|
- spec/logstash/plugin_spec.rb
|
483
484
|
- spec/logstash/plugins/hooks_registry_spec.rb
|
484
485
|
- spec/logstash/plugins/registry_spec.rb
|
486
|
+
- spec/logstash/queue_factory_spec.rb
|
485
487
|
- spec/logstash/runner_spec.rb
|
486
488
|
- spec/logstash/setting_spec.rb
|
487
489
|
- spec/logstash/settings/array_coercible_spec.rb
|
@@ -588,6 +590,7 @@ test_files:
|
|
588
590
|
- spec/logstash/plugin_spec.rb
|
589
591
|
- spec/logstash/plugins/hooks_registry_spec.rb
|
590
592
|
- spec/logstash/plugins/registry_spec.rb
|
593
|
+
- spec/logstash/queue_factory_spec.rb
|
591
594
|
- spec/logstash/runner_spec.rb
|
592
595
|
- spec/logstash/setting_spec.rb
|
593
596
|
- spec/logstash/settings/array_coercible_spec.rb
|