logstash-core 5.2.2-java → 5.3.0-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-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
|