logstash-core 6.1.4-java → 6.2.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.rb +10 -31
- data/lib/logstash/agent.rb +3 -23
- data/lib/logstash/api/modules/logging.rb +11 -0
- data/lib/logstash/config/source/multi_local.rb +5 -3
- data/lib/logstash/environment.rb +10 -3
- data/lib/logstash/event.rb +0 -1
- data/lib/logstash/filter_delegator.rb +1 -2
- data/lib/logstash/inputs/base.rb +1 -1
- data/lib/logstash/instrument/periodic_poller/base.rb +4 -4
- data/lib/logstash/instrument/periodic_poller/jvm.rb +5 -3
- data/lib/logstash/java_filter_delegator.rb +1 -2
- data/lib/logstash/java_pipeline.rb +6 -2
- data/lib/logstash/modules/kibana_client.rb +1 -1
- data/lib/logstash/output_delegator.rb +2 -3
- data/lib/logstash/output_delegator_strategies/legacy.rb +4 -4
- data/lib/logstash/output_delegator_strategies/shared.rb +4 -4
- data/lib/logstash/output_delegator_strategies/single.rb +2 -2
- data/lib/logstash/pipeline.rb +16 -24
- data/lib/logstash/plugin.rb +1 -1
- data/lib/logstash/plugins/plugin_factory.rb +3 -4
- data/lib/logstash/runner.rb +5 -0
- data/lib/logstash/settings.rb +5 -0
- data/lib/logstash/timestamp.rb +2 -25
- data/lib/logstash/util/secretstore.rb +36 -0
- data/lib/logstash/util/settings_helper.rb +1 -0
- data/lib/logstash/util/substitution_variables.rb +18 -5
- data/lib/logstash/util/wrapped_acked_queue.rb +1 -1
- data/lib/logstash/util/wrapped_synchronous_queue.rb +3 -35
- data/locales/en.yml +4 -4
- data/logstash-core.gemspec +0 -7
- data/spec/conditionals_spec.rb +21 -24
- data/spec/logstash/filter_delegator_spec.rb +3 -4
- data/spec/logstash/java_filter_delegator_spec.rb +3 -4
- data/spec/logstash/java_pipeline_spec.rb +97 -2
- data/spec/logstash/legacy_ruby_timestamp_spec.rb +0 -1
- data/spec/logstash/output_delegator_spec.rb +5 -7
- data/spec/logstash/queue_factory_spec.rb +1 -1
- data/spec/logstash/settings_spec.rb +49 -22
- data/spec/logstash/timestamp_spec.rb +0 -1
- data/spec/logstash/util/secretstore_spec.rb +69 -0
- data/spec/support/mocks_classes.rb +21 -0
- data/versions-gem-copy.yml +2 -2
- metadata +6 -42
- data/gemspec_jars.rb +0 -12
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core_jars.rb +0 -28
data/lib/logstash/plugin.rb
CHANGED
@@ -32,11 +32,10 @@ module LogStash
|
|
32
32
|
class PluginFactory
|
33
33
|
include org.logstash.config.ir.compiler.RubyIntegration::PluginFactory
|
34
34
|
|
35
|
-
def initialize(lir, metric_factory,
|
35
|
+
def initialize(lir, metric_factory, exec_factory, filter_class)
|
36
36
|
@lir = lir
|
37
37
|
@plugins_by_id = {}
|
38
38
|
@metric_factory = metric_factory
|
39
|
-
@logger = logger
|
40
39
|
@exec_factory = exec_factory
|
41
40
|
@filter_class = filter_class
|
42
41
|
end
|
@@ -83,9 +82,9 @@ module LogStash
|
|
83
82
|
execution_context = @exec_factory.create(id, klass.config_name)
|
84
83
|
|
85
84
|
if plugin_type == "output"
|
86
|
-
OutputDelegator.new(
|
85
|
+
OutputDelegator.new(klass, type_scoped_metric, execution_context, OutputDelegatorStrategyRegistry.instance, args)
|
87
86
|
elsif plugin_type == "filter"
|
88
|
-
@filter_class.new(
|
87
|
+
@filter_class.new(klass, type_scoped_metric, execution_context, args)
|
89
88
|
else # input or codec plugin
|
90
89
|
plugin_instance = klass.new(args)
|
91
90
|
scoped_metric = type_scoped_metric.namespace(id.to_sym)
|
data/lib/logstash/runner.rb
CHANGED
@@ -85,6 +85,11 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
85
85
|
:attribute_name => "cloud.auth"
|
86
86
|
|
87
87
|
# Pipeline settings
|
88
|
+
option ["--pipeline.id"], "ID",
|
89
|
+
I18n.t("logstash.runner.flag.pipeline-id"),
|
90
|
+
:attribute_name => "pipeline.id",
|
91
|
+
:default => LogStash::SETTINGS.get_default("pipeline.id")
|
92
|
+
|
88
93
|
option ["-w", "--pipeline.workers"], "COUNT",
|
89
94
|
I18n.t("logstash.runner.flag.pipeline-workers"),
|
90
95
|
:attribute_name => "pipeline.workers",
|
data/lib/logstash/settings.rb
CHANGED
@@ -9,6 +9,7 @@ module LogStash
|
|
9
9
|
class Settings
|
10
10
|
|
11
11
|
include LogStash::Util::SubstitutionVariables
|
12
|
+
include LogStash::Util::Loggable
|
12
13
|
|
13
14
|
def initialize
|
14
15
|
@settings = {}
|
@@ -27,6 +28,10 @@ module LogStash
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
31
|
+
def registered?(setting_name)
|
32
|
+
@settings.key?(setting_name)
|
33
|
+
end
|
34
|
+
|
30
35
|
def get_setting(setting_name)
|
31
36
|
setting = @settings[setting_name]
|
32
37
|
raise ArgumentError.new("Setting \"#{setting_name}\" hasn't been registered") if setting.nil?
|
data/lib/logstash/timestamp.rb
CHANGED
@@ -1,25 +1,2 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
require "logstash/namespace"
|
4
|
-
|
5
|
-
module LogStash
|
6
|
-
|
7
|
-
class Timestamp
|
8
|
-
include Comparable
|
9
|
-
|
10
|
-
def eql?(other)
|
11
|
-
self.== other
|
12
|
-
end
|
13
|
-
|
14
|
-
# TODO (colin) implement in Java
|
15
|
-
def +(other)
|
16
|
-
self.time + other
|
17
|
-
end
|
18
|
-
|
19
|
-
# TODO (colin) implement in Java
|
20
|
-
def -(value)
|
21
|
-
self.time - (value.is_a?(Timestamp) ? value.time : value)
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
1
|
+
# The contents of this file have been ported to Java. It is included for for compatibility
|
2
|
+
# with plugins that directly require "logstash/timestamp".
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Ruby helper to work with the secret store
|
4
|
+
module ::LogStash::Util::SecretStore
|
5
|
+
|
6
|
+
java_import "org.logstash.secret.store.SecretStoreFactory"
|
7
|
+
java_import "org.logstash.secret.SecretIdentifier"
|
8
|
+
java_import "org.logstash.secret.store.SecureConfig"
|
9
|
+
java_import "org.logstash.secret.cli.SecretStoreCli"
|
10
|
+
|
11
|
+
# Return the configuration necessary to work with a secret store
|
12
|
+
def self.get_config
|
13
|
+
secure_config = SecureConfig.new
|
14
|
+
secure_config.add("keystore.file", LogStash::SETTINGS.get_setting("keystore.file").value.chars)
|
15
|
+
pass = ENV["LOGSTASH_KEYSTORE_PASS"]
|
16
|
+
secure_config.add("keystore.pass", pass.chars) unless pass.nil?
|
17
|
+
secure_config.add("keystore.classname", LogStash::SETTINGS.get_setting("keystore.classname").value.chars)
|
18
|
+
secure_config
|
19
|
+
end
|
20
|
+
|
21
|
+
# Check to see if the secret store exists, return true if exists, false otherwise
|
22
|
+
def self.exists?
|
23
|
+
SecretStoreFactory.exists(get_config)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a org.logstash.secret.store.SecretStore if it exists, nil otherwise
|
27
|
+
def self.get_if_exists
|
28
|
+
SecretStoreFactory.load(get_config) if exists?
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns a org.org.logstash.secret.SecretIdentifier for use with the secret store
|
32
|
+
def self.get_store_id(id)
|
33
|
+
SecretIdentifier.new(id)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -32,6 +32,7 @@ module LogStash::Util::SettingsHelper
|
|
32
32
|
settings_path = fetch_settings_path(args)
|
33
33
|
|
34
34
|
LogStash::SETTINGS.set("path.settings", settings_path) if settings_path
|
35
|
+
LogStash::SETTINGS.set("keystore.file", ::File.join(settings_path, "logstash.keystore")) if settings_path
|
35
36
|
|
36
37
|
begin
|
37
38
|
LogStash::SETTINGS.from_yaml(LogStash::SETTINGS.get("path.settings"))
|
@@ -1,9 +1,15 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require "logstash/logging"
|
3
|
+
require "logstash/util/loggable"
|
4
|
+
require "logstash/util/secretstore"
|
5
|
+
|
2
6
|
module ::LogStash::Util::SubstitutionVariables
|
3
7
|
|
8
|
+
include LogStash::Util::Loggable
|
9
|
+
|
4
10
|
SUBSTITUTION_PLACEHOLDER_REGEX = /\${(?<name>[a-zA-Z_.][a-zA-Z0-9_.]*)(:(?<default>[^}]*))?}/
|
5
11
|
|
6
|
-
# Recursive method to replace
|
12
|
+
# Recursive method to replace substitution variable references in parameters
|
7
13
|
def deep_replace(value)
|
8
14
|
if value.is_a?(Hash)
|
9
15
|
value.each do |valueHashKey, valueHashValue|
|
@@ -22,7 +28,7 @@ module ::LogStash::Util::SubstitutionVariables
|
|
22
28
|
|
23
29
|
# Replace all substitution variable references in the 'value' param and returns the substituted value, or the original value if a substitution can not be made
|
24
30
|
# Process following patterns : ${VAR}, ${VAR:defaultValue}
|
25
|
-
# If value matches the pattern, returns the following precedence : Environment entry value, default value as provided in the pattern
|
31
|
+
# If value matches the pattern, returns the following precedence : Secret store value, Environment entry value, default value as provided in the pattern
|
26
32
|
# If the value does not match the pattern, the 'value' param returns as-is
|
27
33
|
def replace_placeholders(value)
|
28
34
|
return value unless value.is_a?(String)
|
@@ -34,12 +40,19 @@ module ::LogStash::Util::SubstitutionVariables
|
|
34
40
|
# [1] http://ruby-doc.org/core-2.1.1/Regexp.html#method-c-last_match
|
35
41
|
name = Regexp.last_match(:name)
|
36
42
|
default = Regexp.last_match(:default)
|
43
|
+
logger.debug("Replacing `#{placeholder}` with actual value")
|
37
44
|
|
38
|
-
|
45
|
+
#check the secret store if it exists
|
46
|
+
secret_store = LogStash::Util::SecretStore.get_if_exists
|
47
|
+
replacement = secret_store.nil? ? nil : secret_store.retrieveSecret(LogStash::Util::SecretStore.get_store_id(name))
|
48
|
+
#check the environment
|
49
|
+
replacement = ENV.fetch(name, default) if replacement.nil?
|
39
50
|
if replacement.nil?
|
40
|
-
raise LogStash::ConfigurationError, "Cannot evaluate `#{placeholder}`.
|
51
|
+
raise LogStash::ConfigurationError, "Cannot evaluate `#{placeholder}`. Replacement variable `#{name}` is not defined in a Logstash secret store " +
|
52
|
+
"or as an Environment entry and there is no default value given."
|
41
53
|
end
|
42
|
-
replacement
|
54
|
+
replacement.to_s
|
43
55
|
end
|
44
56
|
end # def replace_placeholders
|
57
|
+
|
45
58
|
end
|
@@ -94,7 +94,7 @@ module LogStash; module Util
|
|
94
94
|
# from this queue. We also depend on this to be able to block consumers while we snapshot
|
95
95
|
# in-flight buffers
|
96
96
|
|
97
|
-
def initialize(queue, batch_size = 125, wait_for =
|
97
|
+
def initialize(queue, batch_size = 125, wait_for = 50)
|
98
98
|
@queue = queue
|
99
99
|
@mutex = Mutex.new
|
100
100
|
# Note that @inflight_batches as a central mechanism for tracking inflight
|
@@ -29,7 +29,7 @@ module LogStash; module Util
|
|
29
29
|
# from this queue. We also depend on this to be able to block consumers while we snapshot
|
30
30
|
# in-flight buffers
|
31
31
|
|
32
|
-
def initialize(queue, batch_size = 125, wait_for =
|
32
|
+
def initialize(queue, batch_size = 125, wait_for = 50)
|
33
33
|
@queue = queue
|
34
34
|
# Note that @inflight_batches as a central mechanism for tracking inflight
|
35
35
|
# batches will fail if we have multiple read clients in the pipeline.
|
@@ -83,11 +83,11 @@ module LogStash; module Util
|
|
83
83
|
# create a new empty batch
|
84
84
|
# @return [ReadBatch] a new empty read batch
|
85
85
|
def new_batch
|
86
|
-
|
86
|
+
LogStash::MemoryReadBatch.new(java.util.LinkedHashSet.new(0))
|
87
87
|
end
|
88
88
|
|
89
89
|
def read_batch
|
90
|
-
batch =
|
90
|
+
batch = LogStash::MemoryReadBatch.new(LsQueueUtils.drain(@queue, @batch_size, @wait_for))
|
91
91
|
start_metrics(batch)
|
92
92
|
batch
|
93
93
|
end
|
@@ -125,38 +125,6 @@ module LogStash; module Util
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
|
-
class ReadBatch
|
129
|
-
def initialize(queue, size, wait)
|
130
|
-
# TODO: disabled for https://github.com/elastic/logstash/issues/6055 - will have to properly refactor
|
131
|
-
# @cancelled = Hash.new
|
132
|
-
|
133
|
-
@originals = LsQueueUtils.drain(queue, size, wait)
|
134
|
-
end
|
135
|
-
|
136
|
-
def merge(event)
|
137
|
-
return if event.nil?
|
138
|
-
@originals.add(event)
|
139
|
-
end
|
140
|
-
|
141
|
-
def to_a
|
142
|
-
events = []
|
143
|
-
@originals.each {|e| events << e unless e.cancelled?}
|
144
|
-
events
|
145
|
-
end
|
146
|
-
|
147
|
-
def each(&blk)
|
148
|
-
# below the checks for @cancelled.include?(e) have been replaced by e.cancelled?
|
149
|
-
# TODO: for https://github.com/elastic/logstash/issues/6055 = will have to properly refactor
|
150
|
-
@originals.each {|e| blk.call(e) unless e.cancelled?}
|
151
|
-
end
|
152
|
-
|
153
|
-
def filtered_size
|
154
|
-
@originals.size
|
155
|
-
end
|
156
|
-
|
157
|
-
alias_method(:size, :filtered_size)
|
158
|
-
end
|
159
|
-
|
160
128
|
class WriteClient
|
161
129
|
def initialize(queue)
|
162
130
|
@queue = queue
|
data/locales/en.yml
CHANGED
@@ -58,9 +58,9 @@ en:
|
|
58
58
|
sighup: >-
|
59
59
|
SIGHUP received.
|
60
60
|
sigint: >-
|
61
|
-
SIGINT received. Shutting down
|
61
|
+
SIGINT received. Shutting down.
|
62
62
|
sigterm: >-
|
63
|
-
SIGTERM received. Shutting down
|
63
|
+
SIGTERM received. Shutting down.
|
64
64
|
slow_shutdown: |-
|
65
65
|
Received shutdown signal, but pipeline is still waiting for in-flight events
|
66
66
|
to be processed. Sending another ^C will force quit Logstash, but this may cause
|
@@ -262,6 +262,8 @@ en:
|
|
262
262
|
Check configuration for valid syntax and then exit.
|
263
263
|
http_host: Web API binding host
|
264
264
|
http_port: Web API http port
|
265
|
+
pipeline-id: |+
|
266
|
+
Sets the ID of the pipeline.
|
265
267
|
pipeline-workers: |+
|
266
268
|
Sets the number of pipeline workers to run.
|
267
269
|
experimental-java-execution: |+
|
@@ -327,8 +329,6 @@ en:
|
|
327
329
|
name: |+
|
328
330
|
Specify the name of this logstash instance, if no value is given
|
329
331
|
it will default to the current hostname.
|
330
|
-
agent: |+
|
331
|
-
Specify an alternate agent plugin name.
|
332
332
|
config_debug: |+
|
333
333
|
Print the compiled config ruby code out as a debug log (you must also have --log.level=debug enabled).
|
334
334
|
WARNING: This will include any 'password' options passed to plugin configs as plaintext, and may result
|
data/logstash-core.gemspec
CHANGED
@@ -70,13 +70,6 @@ Gem::Specification.new do |gem|
|
|
70
70
|
|
71
71
|
gem.add_runtime_dependency "jrjackson", "~> #{ALL_VERSIONS.fetch('jrjackson')}" #(Apache 2.0 license)
|
72
72
|
|
73
|
-
gem.add_runtime_dependency "jar-dependencies"
|
74
|
-
# as of Feb 3rd 2016, the ruby-maven gem is resolved to version 3.3.3 and that version
|
75
|
-
# has an rdoc problem that causes a bundler exception. 3.3.9 is the current latest version
|
76
|
-
# which does not have this problem.
|
77
|
-
gem.add_runtime_dependency "ruby-maven", "~> 3.3.9"
|
78
73
|
gem.add_runtime_dependency "elasticsearch", "~> 5.0", ">= 5.0.4" # Ruby client for ES (Apache 2.0 license)
|
79
74
|
gem.add_runtime_dependency "manticore", '>= 0.5.4', '< 1.0.0'
|
80
|
-
|
81
|
-
eval(File.read(File.expand_path("../gemspec_jars.rb", __FILE__)))
|
82
75
|
end
|
data/spec/conditionals_spec.rb
CHANGED
@@ -491,15 +491,14 @@ describe "conditionals in filter" do
|
|
491
491
|
sample_one({"type" => "original"}) do
|
492
492
|
expect(subject).to be_an(Array)
|
493
493
|
expect(subject.length).to eq(2)
|
494
|
-
|
495
|
-
|
496
|
-
expect(
|
497
|
-
expect(
|
498
|
-
|
499
|
-
|
500
|
-
expect(
|
501
|
-
|
502
|
-
# expect(subject[1].get("cond2")).to eq("true")
|
494
|
+
original_event = subject[0]
|
495
|
+
expect(original_event.get("type")).to eq("original")
|
496
|
+
expect(original_event.get("cond1")).to eq("true")
|
497
|
+
expect(original_event.get("cond2")).to eq(nil)
|
498
|
+
cloned_event = subject[1]
|
499
|
+
expect(cloned_event.get("cond1")).to eq(nil)
|
500
|
+
expect(cloned_event.get("cond2")).to eq("true")
|
501
|
+
expect(cloned_event.get("type")).to eq("clone")
|
503
502
|
end
|
504
503
|
end
|
505
504
|
|
@@ -520,20 +519,18 @@ describe "conditionals in filter" do
|
|
520
519
|
CONFIG
|
521
520
|
|
522
521
|
sample_one({"type" => "original"}) do
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
expect(
|
527
|
-
|
528
|
-
expect(
|
529
|
-
|
530
|
-
expect(
|
531
|
-
|
532
|
-
expect(
|
533
|
-
|
534
|
-
expect(
|
535
|
-
expect(subject[2].get("cond1")).to eq(nil)
|
536
|
-
expect(subject[2].get("cond2")).to eq(nil)
|
522
|
+
clone_event_1 = subject[0]
|
523
|
+
expect(clone_event_1.get("type")).to eq("clone1")
|
524
|
+
expect(clone_event_1.get("cond1")).to eq("true")
|
525
|
+
expect(clone_event_1.get("cond2")).to eq(nil)
|
526
|
+
clone_event_2 = subject[1]
|
527
|
+
expect(clone_event_2.get("type")).to eq("clone2")
|
528
|
+
expect(clone_event_2.get("cond1")).to eq(nil)
|
529
|
+
expect(clone_event_2.get("cond2")).to eq("true")
|
530
|
+
original_event = subject[2]
|
531
|
+
expect(original_event.get("type")).to eq("original")
|
532
|
+
expect(original_event.get("cond1")).to eq(nil)
|
533
|
+
expect(original_event.get("cond2")).to eq(nil)
|
537
534
|
end
|
538
535
|
end
|
539
536
|
|
@@ -586,7 +583,7 @@ describe "conditionals in filter" do
|
|
586
583
|
expect(tags[6]).to eq("prev")
|
587
584
|
expect(tags[7]).to eq("final")
|
588
585
|
end
|
589
|
-
|
586
|
+
|
590
587
|
sample_one("type" => "original") do
|
591
588
|
tags = subject.get("tags")
|
592
589
|
expect(tags[0]).to eq("prev")
|
@@ -14,8 +14,7 @@ describe LogStash::FilterDelegator do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
include_context "execution_context"
|
17
|
-
|
18
|
-
let(:logger) { double(:logger) }
|
17
|
+
|
19
18
|
let(:filter_id) { "my-filter" }
|
20
19
|
let(:config) do
|
21
20
|
{ "host" => "127.0.0.1", "id" => filter_id }
|
@@ -43,11 +42,11 @@ describe LogStash::FilterDelegator do
|
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
46
|
-
subject { described_class.new(
|
45
|
+
subject { described_class.new(plugin_klass, metric, execution_context, config) }
|
47
46
|
|
48
47
|
it "create a plugin with the passed options" do
|
49
48
|
expect(plugin_klass).to receive(:new).with(config).and_return(plugin_klass.new(config))
|
50
|
-
described_class.new(
|
49
|
+
described_class.new(plugin_klass, metric, execution_context, config)
|
51
50
|
end
|
52
51
|
|
53
52
|
context "when the plugin support flush" do
|
@@ -14,8 +14,7 @@ describe LogStash::JavaFilterDelegator do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
include_context "execution_context"
|
17
|
-
|
18
|
-
let(:logger) { double(:logger) }
|
17
|
+
|
19
18
|
let(:filter_id) { "my-filter" }
|
20
19
|
let(:config) do
|
21
20
|
{ "host" => "127.0.0.1", "id" => filter_id }
|
@@ -43,11 +42,11 @@ describe LogStash::JavaFilterDelegator do
|
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
46
|
-
subject { described_class.new(
|
45
|
+
subject { described_class.new(plugin_klass, metric, execution_context, config) }
|
47
46
|
|
48
47
|
it "create a plugin with the passed options" do
|
49
48
|
expect(plugin_klass).to receive(:new).with(config).and_return(plugin_klass.new(config))
|
50
|
-
described_class.new(
|
49
|
+
described_class.new(plugin_klass, metric, execution_context, config)
|
51
50
|
end
|
52
51
|
|
53
52
|
context "when the plugin support flush" do
|
@@ -355,7 +355,7 @@ describe LogStash::JavaPipeline do
|
|
355
355
|
after do
|
356
356
|
pipeline.shutdown
|
357
357
|
end
|
358
|
-
|
358
|
+
|
359
359
|
it "should call close of output without output-workers" do
|
360
360
|
pipeline.run
|
361
361
|
|
@@ -380,7 +380,7 @@ describe LogStash::JavaPipeline do
|
|
380
380
|
# cause the suite to fail :(
|
381
381
|
pipeline.close
|
382
382
|
end
|
383
|
-
|
383
|
+
|
384
384
|
it "should use LIR provided IDs" do
|
385
385
|
expect(pipeline.inputs.first.id).to eq(pipeline.lir.input_plugin_vertices.first.id)
|
386
386
|
expect(pipeline.filters.first.id).to eq(pipeline.lir.filter_plugin_vertices.first.id)
|
@@ -642,6 +642,101 @@ describe LogStash::JavaPipeline do
|
|
642
642
|
end
|
643
643
|
end
|
644
644
|
|
645
|
+
context "Periodic Flush Wrapped in Nested Conditional" do
|
646
|
+
let(:config) do
|
647
|
+
<<-EOS
|
648
|
+
input {
|
649
|
+
dummy_input {}
|
650
|
+
}
|
651
|
+
filter {
|
652
|
+
if [type] == "foo" {
|
653
|
+
if [@bar] {
|
654
|
+
dummy_flushing_filter {}
|
655
|
+
}
|
656
|
+
} else {
|
657
|
+
drop {}
|
658
|
+
}
|
659
|
+
}
|
660
|
+
output {
|
661
|
+
dummy_output {}
|
662
|
+
}
|
663
|
+
EOS
|
664
|
+
end
|
665
|
+
let(:output) { ::LogStash::Outputs::DummyOutput.new }
|
666
|
+
|
667
|
+
before do
|
668
|
+
allow(::LogStash::Outputs::DummyOutput).to receive(:new).with(any_args).and_return(output)
|
669
|
+
allow(LogStash::Plugin).to receive(:lookup).with("input", "dummy_input").and_return(LogStash::Inputs::DummyBlockingInput)
|
670
|
+
allow(LogStash::Plugin).to receive(:lookup).with("filter", "dummy_flushing_filter").and_return(DummyFlushingFilterPeriodic)
|
671
|
+
allow(LogStash::Plugin).to receive(:lookup).with("output", "dummy_output").and_return(::LogStash::Outputs::DummyOutput)
|
672
|
+
allow(LogStash::Plugin).to receive(:lookup).with("filter", "drop").and_call_original
|
673
|
+
allow(LogStash::Plugin).to receive(:lookup).with("codec", "plain").and_return(LogStash::Codecs::Plain)
|
674
|
+
end
|
675
|
+
|
676
|
+
it "flush periodically" do
|
677
|
+
Thread.abort_on_exception = true
|
678
|
+
pipeline = mock_java_pipeline_from_string(config, pipeline_settings_obj)
|
679
|
+
t = Thread.new { pipeline.run }
|
680
|
+
Timeout.timeout(timeout) do
|
681
|
+
sleep(0.1) until pipeline.ready?
|
682
|
+
end
|
683
|
+
Stud.try(max_retry.times, [StandardError, RSpec::Expectations::ExpectationNotMetError]) do
|
684
|
+
wait(11).for do
|
685
|
+
# give us a bit of time to flush the events
|
686
|
+
output.events.size >= 2
|
687
|
+
end.to be_truthy
|
688
|
+
end
|
689
|
+
|
690
|
+
expect(output.events.any? {|e| e.get("message") == "dummy_flush"}).to eq(true)
|
691
|
+
|
692
|
+
pipeline.shutdown
|
693
|
+
|
694
|
+
t.join
|
695
|
+
end
|
696
|
+
end
|
697
|
+
|
698
|
+
context "with multiple outputs" do
|
699
|
+
let(:config) do
|
700
|
+
<<-EOS
|
701
|
+
input {
|
702
|
+
generator { count => 10 }
|
703
|
+
}
|
704
|
+
filter {
|
705
|
+
clone {
|
706
|
+
add_field => {
|
707
|
+
'cloned' => 'cloned'
|
708
|
+
}
|
709
|
+
clones => ["clone1"]
|
710
|
+
}
|
711
|
+
}
|
712
|
+
output {
|
713
|
+
dummy_output {}
|
714
|
+
dummy_output {}
|
715
|
+
dummy_output {}
|
716
|
+
}
|
717
|
+
EOS
|
718
|
+
end
|
719
|
+
let(:output) { ::LogStash::Outputs::DummyOutput.new }
|
720
|
+
|
721
|
+
before do
|
722
|
+
allow(::LogStash::Outputs::DummyOutput).to receive(:new).with(any_args).and_return(output)
|
723
|
+
allow(LogStash::Plugin).to receive(:lookup).with("input", "generator").and_call_original
|
724
|
+
allow(LogStash::Plugin).to receive(:lookup).with("filter", "clone").and_call_original
|
725
|
+
3.times {
|
726
|
+
allow(LogStash::Plugin).to receive(:lookup).with("output", "dummy_output").and_return(::LogStash::Outputs::DummyOutput)
|
727
|
+
allow(LogStash::Plugin).to receive(:lookup).with("codec", "plain").and_return(LogStash::Codecs::Plain)
|
728
|
+
}
|
729
|
+
end
|
730
|
+
|
731
|
+
it "correctly distributes events" do
|
732
|
+
pipeline = mock_java_pipeline_from_string(config, pipeline_settings_obj)
|
733
|
+
pipeline.run
|
734
|
+
pipeline.shutdown
|
735
|
+
expect(output.events.size).to eq(60)
|
736
|
+
expect(output.events.count {|e| e.get("cloned") == "cloned"}).to eq(30)
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
645
740
|
context "#started_at" do
|
646
741
|
# use a run limiting count to shutdown the pipeline automatically
|
647
742
|
let(:config) do
|