logstash-core 6.0.1-java → 6.1.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/gemspec_jars.rb +1 -1
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/logstash-core.rb +14 -2
- data/lib/logstash-core_jars.rb +4 -2
- data/lib/logstash/agent.rb +8 -2
- data/lib/logstash/api/modules/node.rb +11 -5
- data/lib/logstash/api/modules/stats.rb +13 -7
- data/lib/logstash/compiler.rb +6 -10
- data/lib/logstash/compiler/lscl.rb +10 -1
- data/lib/logstash/compiler/lscl/helpers.rb +3 -1
- data/lib/logstash/config/mixin.rb +2 -2
- data/lib/logstash/environment.rb +1 -6
- data/lib/logstash/errors.rb +1 -1
- data/lib/logstash/event.rb +0 -2
- data/lib/logstash/filter_delegator.rb +1 -2
- data/lib/logstash/instrument/metric_type/counter.rb +1 -1
- data/lib/logstash/instrument/metric_type/gauge.rb +1 -1
- data/lib/logstash/instrument/wrapped_write_client.rb +1 -1
- data/lib/logstash/java_filter_delegator.rb +79 -0
- data/lib/logstash/java_pipeline.rb +690 -0
- data/lib/logstash/json.rb +4 -29
- data/lib/logstash/output_delegator.rb +3 -2
- data/lib/logstash/patches/bugfix_jruby_2558.rb +1 -1
- data/lib/logstash/pipeline.rb +32 -89
- data/lib/logstash/pipeline_action/create.rb +8 -2
- data/lib/logstash/pipeline_action/reload.rb +6 -1
- data/lib/logstash/pipeline_reporter.rb +2 -1
- data/lib/logstash/pipeline_settings.rb +1 -0
- data/lib/logstash/plugins/plugin_factory.rb +100 -0
- data/lib/logstash/plugins/registry.rb +18 -7
- data/lib/logstash/queue_factory.rb +3 -1
- data/lib/logstash/runner.rb +13 -56
- data/lib/logstash/settings.rb +2 -2
- data/lib/logstash/timestamp.rb +0 -1
- data/lib/logstash/util.rb +13 -21
- data/lib/logstash/util/java_version.rb +0 -1
- data/lib/logstash/util/settings_helper.rb +79 -0
- data/lib/logstash/util/{environment_variables.rb → substitution_variables.rb} +10 -8
- data/lib/logstash/util/wrapped_acked_queue.rb +17 -108
- data/lib/logstash/util/wrapped_synchronous_queue.rb +38 -178
- data/locales/en.yml +2 -0
- data/spec/conditionals_spec.rb +235 -80
- data/spec/logstash/api/modules/node_spec.rb +11 -0
- data/spec/logstash/compiler/compiler_spec.rb +28 -2
- data/spec/logstash/environment_spec.rb +0 -5
- data/spec/logstash/event_spec.rb +7 -2
- data/spec/logstash/filter_delegator_spec.rb +1 -1
- data/spec/logstash/filters/base_spec.rb +30 -28
- data/spec/logstash/instrument/wrapped_write_client_spec.rb +2 -2
- data/spec/logstash/java_filter_delegator_spec.rb +176 -0
- data/spec/logstash/java_pipeline_spec.rb +933 -0
- data/spec/logstash/json_spec.rb +27 -45
- data/spec/logstash/plugins/registry_spec.rb +7 -0
- data/spec/logstash/queue_factory_spec.rb +5 -2
- data/spec/logstash/settings_spec.rb +1 -1
- data/spec/logstash/util/java_version_spec.rb +1 -3
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +27 -24
- data/spec/logstash/webserver_spec.rb +3 -6
- data/spec/support/helpers.rb +5 -0
- data/spec/support/pipeline/pipeline_helpers.rb +97 -0
- data/versions-gem-copy.yml +5 -2
- metadata +14 -5
- data/lib/logstash/patches/rubygems.rb +0 -38
@@ -9,6 +9,8 @@ module LogStash module Plugins
|
|
9
9
|
class Registry
|
10
10
|
include LogStash::Util::Loggable
|
11
11
|
|
12
|
+
class UnknownPlugin < NameError; end
|
13
|
+
|
12
14
|
# Add a bit more sanity with when interacting with the rubygems'
|
13
15
|
# specifications database, most of out code interact directly with really low level
|
14
16
|
# components of bundler/rubygems we need to encapsulate that and this is a start.
|
@@ -152,14 +154,19 @@ module LogStash module Plugins
|
|
152
154
|
begin
|
153
155
|
path = "logstash/#{type}s/#{plugin_name}"
|
154
156
|
|
155
|
-
begin
|
156
|
-
|
157
|
-
rescue
|
158
|
-
# Plugin
|
159
|
-
|
157
|
+
klass = begin
|
158
|
+
namespace_lookup(type, plugin_name)
|
159
|
+
rescue UnknownPlugin => e
|
160
|
+
# Plugin not registered. Try to load it.
|
161
|
+
begin
|
162
|
+
require path
|
163
|
+
namespace_lookup(type, plugin_name)
|
164
|
+
rescue LoadError => e
|
165
|
+
logger.error("Tried to load a plugin's code, but failed.", :exception => e, :path => path, :type => type, :name => plugin_name)
|
166
|
+
raise
|
167
|
+
end
|
160
168
|
end
|
161
169
|
|
162
|
-
klass = namespace_lookup(type, plugin_name)
|
163
170
|
plugin = lazy_add(type, plugin_name, klass)
|
164
171
|
rescue => e
|
165
172
|
logger.error("Problems loading a plugin with",
|
@@ -195,6 +202,10 @@ module LogStash module Plugins
|
|
195
202
|
add_plugin(type, name, klass)
|
196
203
|
end
|
197
204
|
|
205
|
+
def remove(type, plugin_name)
|
206
|
+
@registry.delete(key_for(type, plugin_name))
|
207
|
+
end
|
208
|
+
|
198
209
|
def get(type, plugin_name)
|
199
210
|
@registry[key_for(type, plugin_name)]
|
200
211
|
end
|
@@ -223,7 +234,7 @@ module LogStash module Plugins
|
|
223
234
|
klass_sym = namespace.constants.find { |c| is_a_plugin?(namespace.const_get(c), name) }
|
224
235
|
klass = klass_sym && namespace.const_get(klass_sym)
|
225
236
|
|
226
|
-
raise(
|
237
|
+
raise(UnknownPlugin) unless klass
|
227
238
|
klass
|
228
239
|
end
|
229
240
|
|
@@ -29,7 +29,9 @@ module LogStash
|
|
29
29
|
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)
|
30
30
|
when "memory"
|
31
31
|
# memory is the legacy and default setting
|
32
|
-
LogStash::Util::WrappedSynchronousQueue.new
|
32
|
+
LogStash::Util::WrappedSynchronousQueue.new(
|
33
|
+
settings.get("pipeline.batch.size") * settings.get("pipeline.workers") * 2
|
34
|
+
)
|
33
35
|
else
|
34
36
|
raise ConfigurationError, "Invalid setting `#{queue_type}` for `queue.type`, supported types are: 'memory_acked', 'memory', 'persisted'"
|
35
37
|
end
|
data/lib/logstash/runner.rb
CHANGED
@@ -10,6 +10,7 @@ require "logstash/namespace"
|
|
10
10
|
require "logstash-core/logstash-core"
|
11
11
|
require "logstash/environment"
|
12
12
|
require "logstash/modules/cli_parser"
|
13
|
+
require "logstash/util/settings_helper"
|
13
14
|
|
14
15
|
LogStash::Environment.load_locale!
|
15
16
|
|
@@ -30,12 +31,8 @@ java_import 'org.logstash.FileLockFactory'
|
|
30
31
|
|
31
32
|
class LogStash::Runner < Clamp::StrictCommand
|
32
33
|
include LogStash::Util::Loggable
|
33
|
-
|
34
|
-
|
35
|
-
#
|
36
|
-
# See issue https://github.com/elastic/logstash/issues/5361
|
37
|
-
LogStash::SETTINGS.register(LogStash::Setting::String.new("path.settings", ::File.join(LogStash::Environment::LOGSTASH_HOME, "config")))
|
38
|
-
LogStash::SETTINGS.register(LogStash::Setting::String.new("path.logs", ::File.join(LogStash::Environment::LOGSTASH_HOME, "logs")))
|
34
|
+
|
35
|
+
LogStash::Util::SettingsHelper.pre_process
|
39
36
|
|
40
37
|
# Ordered list of check to run before starting logstash
|
41
38
|
# theses checks can be changed by a plugin loaded into memory.
|
@@ -93,6 +90,11 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
93
90
|
:attribute_name => "pipeline.workers",
|
94
91
|
:default => LogStash::SETTINGS.get_default("pipeline.workers")
|
95
92
|
|
93
|
+
option ["--experimental-java-execution"], :flag,
|
94
|
+
I18n.t("logstash.runner.flag.experimental-java-execution"),
|
95
|
+
:attribute_name => "pipeline.java_execution",
|
96
|
+
:default => LogStash::SETTINGS.get_default("pipeline.java_execution")
|
97
|
+
|
96
98
|
option ["-b", "--pipeline.batch.size"], "SIZE",
|
97
99
|
I18n.t("logstash.runner.flag.pipeline-batch-size"),
|
98
100
|
:attribute_name => "pipeline.batch.size",
|
@@ -208,35 +210,12 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
208
210
|
end
|
209
211
|
|
210
212
|
def run(args)
|
211
|
-
|
212
|
-
|
213
|
-
@settings.set("path.settings", settings_path) if settings_path
|
214
|
-
|
215
|
-
begin
|
216
|
-
LogStash::SETTINGS.from_yaml(LogStash::SETTINGS.get("path.settings"))
|
217
|
-
rescue Errno::ENOENT
|
218
|
-
$stderr.puts "WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults"
|
219
|
-
rescue => e
|
220
|
-
# abort unless we're just looking for the help
|
221
|
-
unless cli_help?(args)
|
222
|
-
if e.kind_of?(Psych::Exception)
|
223
|
-
yaml_file_path = ::File.join(LogStash::SETTINGS.get("path.settings"), "logstash.yml")
|
224
|
-
$stderr.puts "ERROR: Failed to parse YAML file \"#{yaml_file_path}\". Please confirm if the YAML structure is valid (e.g. look for incorrect usage of whitespace or indentation). Aborting... parser_error=>#{e.message}"
|
225
|
-
else
|
226
|
-
$stderr.puts "ERROR: Failed to load settings file from \"path.settings\". Aborting... path.setting=#{LogStash::SETTINGS.get("path.settings")}, exception=#{e.class}, message=>#{e.message}"
|
227
|
-
end
|
228
|
-
return 1
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
213
|
+
return 1 unless LogStash::Util::SettingsHelper.from_yaml(args)
|
232
214
|
super(*[args])
|
233
215
|
end
|
234
216
|
|
235
217
|
def execute
|
236
|
-
|
237
|
-
# We invoke post_process to apply extra logic to them.
|
238
|
-
# The post_process callbacks have been added in environment.rb
|
239
|
-
@settings.post_process
|
218
|
+
LogStash::Util::SettingsHelper.post_process
|
240
219
|
|
241
220
|
require "logstash/util"
|
242
221
|
require "logstash/util/java_version"
|
@@ -359,6 +338,8 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
359
338
|
sigint_id = trap_sigint()
|
360
339
|
sigterm_id = trap_sigterm()
|
361
340
|
|
341
|
+
logger.info("Starting Logstash", "logstash.version" => LOGSTASH_VERSION)
|
342
|
+
|
362
343
|
@agent_task = Stud::Task.new { @agent.execute }
|
363
344
|
|
364
345
|
# no point in enabling config reloading before the agent starts
|
@@ -402,7 +383,7 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
402
383
|
|
403
384
|
if logger.info?
|
404
385
|
show_version_ruby
|
405
|
-
show_version_java
|
386
|
+
show_version_java
|
406
387
|
show_gems if logger.debug?
|
407
388
|
end
|
408
389
|
end # def show_version
|
@@ -501,28 +482,4 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
501
482
|
@settings.get_value(key)
|
502
483
|
end
|
503
484
|
|
504
|
-
# where can I find the logstash.yml file?
|
505
|
-
# 1. look for a "--path.settings path"
|
506
|
-
# 2. look for a "--path.settings=path"
|
507
|
-
# 3. check if the LS_SETTINGS_DIR environment variable is set
|
508
|
-
# 4. return nil if not found
|
509
|
-
def fetch_settings_path(cli_args)
|
510
|
-
if i=cli_args.find_index("--path.settings")
|
511
|
-
cli_args[i+1]
|
512
|
-
elsif settings_arg = cli_args.find {|v| v.match(/--path.settings=/) }
|
513
|
-
match = settings_arg.match(/--path.settings=(.*)/)
|
514
|
-
match[1]
|
515
|
-
elsif ENV['LS_SETTINGS_DIR']
|
516
|
-
ENV['LS_SETTINGS_DIR']
|
517
|
-
else
|
518
|
-
nil
|
519
|
-
end
|
520
|
-
end
|
521
|
-
|
522
|
-
# is the user asking for CLI help subcommand?
|
523
|
-
def cli_help?(args)
|
524
|
-
# I know, double negative
|
525
|
-
!(["--help", "-h"] & args).empty?
|
526
|
-
end
|
527
|
-
|
528
485
|
end
|
data/lib/logstash/settings.rb
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
require "logstash/util/loggable"
|
3
3
|
require "fileutils"
|
4
4
|
require "logstash/util/byte_value"
|
5
|
-
require "logstash/util/
|
5
|
+
require "logstash/util/substitution_variables"
|
6
6
|
require "logstash/util/time_value"
|
7
7
|
|
8
8
|
module LogStash
|
9
9
|
class Settings
|
10
10
|
|
11
|
-
include LogStash::Util::
|
11
|
+
include LogStash::Util::SubstitutionVariables
|
12
12
|
|
13
13
|
def initialize
|
14
14
|
@settings = {}
|
data/lib/logstash/timestamp.rb
CHANGED
data/lib/logstash/util.rb
CHANGED
@@ -147,28 +147,20 @@ module LogStash::Util
|
|
147
147
|
# to support these pure Ruby object monkey patches.
|
148
148
|
# see logstash/json.rb and logstash/java_integration.rb
|
149
149
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
else
|
164
|
-
o
|
165
|
-
end
|
150
|
+
require "java"
|
151
|
+
# recursively convert any Java LinkedHashMap and ArrayList to pure Ruby.
|
152
|
+
# will not recurse into pure Ruby objects. Pure Ruby object should never
|
153
|
+
# contain LinkedHashMap and ArrayList since these are only created at
|
154
|
+
# initial deserialization, anything after (deeper) will be pure Ruby.
|
155
|
+
def self.normalize(o)
|
156
|
+
case o
|
157
|
+
when Java::JavaUtil::LinkedHashMap
|
158
|
+
o.inject({}){|r, (k, v)| r[k] = normalize(v); r}
|
159
|
+
when Java::JavaUtil::ArrayList
|
160
|
+
o.map{|i| normalize(i)}
|
161
|
+
else
|
162
|
+
o
|
166
163
|
end
|
167
|
-
|
168
|
-
else
|
169
|
-
|
170
|
-
# identity function, pure Ruby object don't need normalization.
|
171
|
-
def self.normalize(o); o; end
|
172
164
|
end
|
173
165
|
|
174
166
|
def self.stringify_symbols(o)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "logstash/settings"
|
2
|
+
require "logstash-core/logstash-core"
|
3
|
+
require "logstash/environment"
|
4
|
+
|
5
|
+
##########################
|
6
|
+
# Settings have an implicit initialization life-cycle, this helper exists to aid with the reading the settings.
|
7
|
+
#
|
8
|
+
# Defaults are read from "logstash/environment"
|
9
|
+
# SettingsHelper.pre_process - registers defaults unavailable from "logstash/environment"
|
10
|
+
# SettingsHelper.from_yaml - finds yaml based on "--path.settings" and updates defaults if needed.
|
11
|
+
# SettingsHelper.post_process - callback to re-calculate derived settings
|
12
|
+
#
|
13
|
+
# The methods should be called in the above order before the settings are ready to be used.
|
14
|
+
########################
|
15
|
+
module LogStash::Util::SettingsHelper
|
16
|
+
|
17
|
+
# The `path.settings` and `path.logs` can not be defined in "logstash/environment" since the `Environment::LOGSTASH_HOME` doesn't
|
18
|
+
# exist unless launched via "bootstrap/environment"
|
19
|
+
def self.pre_process
|
20
|
+
LogStash::SETTINGS.register(LogStash::Setting::String.new("path.settings", ::File.join(LogStash::Environment::LOGSTASH_HOME, "config")))
|
21
|
+
LogStash::SETTINGS.register(LogStash::Setting::String.new("path.logs", ::File.join(LogStash::Environment::LOGSTASH_HOME, "logs")))
|
22
|
+
end
|
23
|
+
|
24
|
+
# Ensure that any settings are re-calculated after loading yaml
|
25
|
+
def self.post_process
|
26
|
+
LogStash::SETTINGS.post_process
|
27
|
+
end
|
28
|
+
|
29
|
+
# param args: The array of all the command line arguments. Used to find the "path.settings" to read the settings yaml.
|
30
|
+
# Return true if successful, false otherwise
|
31
|
+
def self.from_yaml(args)
|
32
|
+
settings_path = fetch_settings_path(args)
|
33
|
+
|
34
|
+
LogStash::SETTINGS.set("path.settings", settings_path) if settings_path
|
35
|
+
|
36
|
+
begin
|
37
|
+
LogStash::SETTINGS.from_yaml(LogStash::SETTINGS.get("path.settings"))
|
38
|
+
rescue Errno::ENOENT
|
39
|
+
$stderr.puts "WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults"
|
40
|
+
rescue => e
|
41
|
+
# abort unless we're just looking for the help
|
42
|
+
unless cli_help?(args)
|
43
|
+
if e.kind_of?(Psych::Exception)
|
44
|
+
yaml_file_path = ::File.join(LogStash::SETTINGS.get("path.settings"), "logstash.yml")
|
45
|
+
$stderr.puts "ERROR: Failed to parse YAML file \"#{yaml_file_path}\". Please confirm if the YAML structure is valid (e.g. look for incorrect usage of whitespace or indentation). Aborting... parser_error=>#{e.message}"
|
46
|
+
else
|
47
|
+
$stderr.puts "ERROR: Failed to load settings file from \"path.settings\". Aborting... path.setting=#{LogStash::SETTINGS.get("path.settings")}, exception=#{e.class}, message=>#{e.message}"
|
48
|
+
end
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
return true
|
53
|
+
end
|
54
|
+
|
55
|
+
# where can I find the logstash.yml file?
|
56
|
+
# 1. look for a "--path.settings path"
|
57
|
+
# 2. look for a "--path.settings=path"
|
58
|
+
# 3. check if the LS_SETTINGS_DIR environment variable is set
|
59
|
+
# 4. return nil if not found
|
60
|
+
def self.fetch_settings_path(cli_args)
|
61
|
+
if i=cli_args.find_index("--path.settings")
|
62
|
+
cli_args[i+1]
|
63
|
+
elsif settings_arg = cli_args.find {|v| v.match(/--path.settings=/)}
|
64
|
+
match = settings_arg.match(/--path.settings=(.*)/)
|
65
|
+
match[1]
|
66
|
+
elsif ENV['LS_SETTINGS_DIR']
|
67
|
+
ENV['LS_SETTINGS_DIR']
|
68
|
+
else
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# is the user asking for CLI help subcommand?
|
74
|
+
def self.cli_help?(args)
|
75
|
+
# I know, double negative
|
76
|
+
!(["--help", "-h"] & args).empty?
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
module ::LogStash::Util::
|
2
|
+
module ::LogStash::Util::SubstitutionVariables
|
3
3
|
|
4
|
-
|
4
|
+
SUBSTITUTION_PLACEHOLDER_REGEX = /\${(?<name>[a-zA-Z_.][a-zA-Z0-9_.]*)(:(?<default>[^}]*))?}/
|
5
5
|
|
6
6
|
# Recursive method to replace environment variable references in parameters
|
7
7
|
def deep_replace(value)
|
@@ -15,17 +15,19 @@ module ::LogStash::Util::EnvironmentVariables
|
|
15
15
|
value[valueArrayIndex] = deep_replace(value[valueArrayIndex])
|
16
16
|
end
|
17
17
|
else
|
18
|
-
return
|
18
|
+
return replace_placeholders(value)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
# Replace all
|
24
|
-
# Process following patterns : $
|
25
|
-
|
23
|
+
# 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
|
+
# 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
|
26
|
+
# If the value does not match the pattern, the 'value' param returns as-is
|
27
|
+
def replace_placeholders(value)
|
26
28
|
return value unless value.is_a?(String)
|
27
29
|
|
28
|
-
value.gsub(
|
30
|
+
value.gsub(SUBSTITUTION_PLACEHOLDER_REGEX) do |placeholder|
|
29
31
|
# Note: Ruby docs claim[1] Regexp.last_match is thread-local and scoped to
|
30
32
|
# the call, so this should be thread-safe.
|
31
33
|
#
|
@@ -39,5 +41,5 @@ module ::LogStash::Util::EnvironmentVariables
|
|
39
41
|
end
|
40
42
|
replacement
|
41
43
|
end
|
42
|
-
end # def
|
44
|
+
end # def replace_placeholders
|
43
45
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require "jruby_acked_queue_ext"
|
4
|
-
require "jruby_acked_batch_ext"
|
5
3
|
require "concurrent"
|
6
4
|
# This is an adapted copy of the wrapped_synchronous_queue file
|
7
5
|
# ideally this should be moved to Java/JRuby
|
@@ -103,7 +101,7 @@ module LogStash; module Util
|
|
103
101
|
# batches will fail if we have multiple read clients in the pipeline.
|
104
102
|
@inflight_batches = {}
|
105
103
|
# allow the worker thread to report the execution time of the filter + output
|
106
|
-
@inflight_clocks =
|
104
|
+
@inflight_clocks = Concurrent::Map.new
|
107
105
|
@batch_size = batch_size
|
108
106
|
@wait_for = wait_for
|
109
107
|
end
|
@@ -151,10 +149,6 @@ module LogStash; module Util
|
|
151
149
|
end
|
152
150
|
end
|
153
151
|
|
154
|
-
def current_inflight_batch
|
155
|
-
@inflight_batches.fetch(Thread.current, [])
|
156
|
-
end
|
157
|
-
|
158
152
|
# create a new empty batch
|
159
153
|
# @return [ReadBatch] a new empty read batch
|
160
154
|
def new_batch
|
@@ -167,75 +161,52 @@ module LogStash; module Util
|
|
167
161
|
end
|
168
162
|
|
169
163
|
batch = new_batch
|
170
|
-
|
171
|
-
begin
|
172
|
-
batch.read_next
|
173
|
-
ensure
|
174
|
-
@mutex.unlock
|
175
|
-
end
|
164
|
+
batch.read_next
|
176
165
|
start_metrics(batch)
|
177
166
|
batch
|
178
167
|
end
|
179
168
|
|
180
169
|
def start_metrics(batch)
|
170
|
+
thread = Thread.current
|
181
171
|
@mutex.lock
|
182
172
|
begin
|
183
|
-
|
184
|
-
set_current_thread_inflight_batch(batch)
|
185
|
-
start_clock
|
173
|
+
@inflight_batches[thread] = batch
|
186
174
|
ensure
|
187
175
|
@mutex.unlock
|
188
176
|
end
|
189
|
-
|
190
|
-
|
191
|
-
def set_current_thread_inflight_batch(batch)
|
192
|
-
@inflight_batches[Thread.current] = batch
|
177
|
+
@inflight_clocks[thread] = java.lang.System.nano_time
|
193
178
|
end
|
194
179
|
|
195
180
|
def close_batch(batch)
|
181
|
+
thread = Thread.current
|
196
182
|
@mutex.lock
|
197
183
|
begin
|
198
184
|
batch.close
|
199
|
-
|
200
|
-
@inflight_batches.delete(Thread.current)
|
201
|
-
stop_clock(batch)
|
185
|
+
@inflight_batches.delete(thread)
|
202
186
|
ensure
|
203
187
|
@mutex.unlock
|
204
188
|
end
|
205
|
-
|
206
|
-
|
207
|
-
def start_clock
|
208
|
-
@inflight_clocks[Thread.current] = java.lang.System.nano_time
|
209
|
-
end
|
210
|
-
|
211
|
-
def stop_clock(batch)
|
212
|
-
unless @inflight_clocks[Thread.current].nil?
|
189
|
+
start_time = @inflight_clocks.get_and_set(thread, nil)
|
190
|
+
unless start_time.nil?
|
213
191
|
if batch.size > 0
|
214
192
|
# only stop (which also records) the metrics if the batch is non-empty.
|
215
193
|
# start_clock is now called at empty batch creation and an empty batch could
|
216
194
|
# stay empty all the way down to the close_batch call.
|
217
|
-
time_taken = (java.lang.System.nano_time -
|
195
|
+
time_taken = (java.lang.System.nano_time - start_time) / 1_000_000
|
218
196
|
@event_metric.report_time(:duration_in_millis, time_taken)
|
219
197
|
@pipeline_metric.report_time(:duration_in_millis, time_taken)
|
220
198
|
end
|
221
|
-
@inflight_clocks.delete(Thread.current)
|
222
199
|
end
|
223
200
|
end
|
224
201
|
|
225
|
-
def
|
226
|
-
|
227
|
-
@
|
228
|
-
@pipeline_metric.increment(:in, batch.starting_size)
|
229
|
-
end
|
230
|
-
|
231
|
-
def add_filtered_metrics(batch)
|
232
|
-
@event_metric.increment(:filtered, batch.filtered_size)
|
233
|
-
@pipeline_metric.increment(:filtered, batch.filtered_size)
|
202
|
+
def add_filtered_metrics(filtered_size)
|
203
|
+
@event_metric.increment(:filtered, filtered_size)
|
204
|
+
@pipeline_metric.increment(:filtered, filtered_size)
|
234
205
|
end
|
235
206
|
|
236
|
-
def add_output_metrics(
|
237
|
-
@event_metric.increment(:out,
|
238
|
-
@pipeline_metric.increment(:out,
|
207
|
+
def add_output_metrics(filtered_size)
|
208
|
+
@event_metric.increment(:out, filtered_size)
|
209
|
+
@pipeline_metric.increment(:out, filtered_size)
|
239
210
|
end
|
240
211
|
end
|
241
212
|
|
@@ -251,8 +222,6 @@ module LogStash; module Util
|
|
251
222
|
# @cancelled = Hash.new
|
252
223
|
|
253
224
|
@generated = Hash.new
|
254
|
-
@iterating_temp = Hash.new
|
255
|
-
@iterating = false # Atomic Boolean maybe? Although batches are not shared across threads
|
256
225
|
@acked_batch = nil
|
257
226
|
end
|
258
227
|
|
@@ -271,20 +240,7 @@ module LogStash; module Util
|
|
271
240
|
|
272
241
|
def merge(event)
|
273
242
|
return if event.nil? || @originals.key?(event)
|
274
|
-
|
275
|
-
# @iterating_temp is merged after the iteration
|
276
|
-
if iterating?
|
277
|
-
@iterating_temp[event] = true
|
278
|
-
else
|
279
|
-
# the periodic flush could generate events outside of an each iteration
|
280
|
-
@generated[event] = true
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
def cancel(event)
|
285
|
-
# TODO: disabled for https://github.com/elastic/logstash/issues/6055 - will have to properly refactor
|
286
|
-
raise("cancel is unsupported")
|
287
|
-
# @cancelled[event] = true
|
243
|
+
@generated[event] = true
|
288
244
|
end
|
289
245
|
|
290
246
|
def to_a
|
@@ -294,19 +250,14 @@ module LogStash; module Util
|
|
294
250
|
end
|
295
251
|
|
296
252
|
def each(&blk)
|
297
|
-
# take care not to cause @originals or @generated to change during iteration
|
298
|
-
|
299
253
|
# below the checks for @cancelled.include?(e) have been replaced by e.cancelled?
|
300
254
|
# TODO: for https://github.com/elastic/logstash/issues/6055 = will have to properly refactor
|
301
|
-
@iterating = true
|
302
255
|
@originals.each do |e, _|
|
303
256
|
blk.call(e) unless e.cancelled?
|
304
257
|
end
|
305
258
|
@generated.each do |e, _|
|
306
259
|
blk.call(e) unless e.cancelled?
|
307
260
|
end
|
308
|
-
@iterating = false
|
309
|
-
update_generated
|
310
261
|
end
|
311
262
|
|
312
263
|
def size
|
@@ -321,12 +272,6 @@ module LogStash; module Util
|
|
321
272
|
@originals.size + @generated.size
|
322
273
|
end
|
323
274
|
|
324
|
-
def cancelled_size
|
325
|
-
# TODO: disabled for https://github.com/elastic/logstash/issues/6055 = will have to properly refactor
|
326
|
-
raise("cancelled_size is unsupported ")
|
327
|
-
# @cancelled.size
|
328
|
-
end
|
329
|
-
|
330
275
|
def shutdown_signal_received?
|
331
276
|
false
|
332
277
|
end
|
@@ -334,17 +279,6 @@ module LogStash; module Util
|
|
334
279
|
def flush_signal_received?
|
335
280
|
false
|
336
281
|
end
|
337
|
-
|
338
|
-
private
|
339
|
-
|
340
|
-
def iterating?
|
341
|
-
@iterating
|
342
|
-
end
|
343
|
-
|
344
|
-
def update_generated
|
345
|
-
@generated.update(@iterating_temp)
|
346
|
-
@iterating_temp.clear
|
347
|
-
end
|
348
282
|
end
|
349
283
|
|
350
284
|
class WriteClient
|
@@ -352,10 +286,6 @@ module LogStash; module Util
|
|
352
286
|
@queue = queue
|
353
287
|
end
|
354
288
|
|
355
|
-
def get_new_batch
|
356
|
-
WriteBatch.new
|
357
|
-
end
|
358
|
-
|
359
289
|
def push(event)
|
360
290
|
if @queue.closed?
|
361
291
|
raise QueueClosedError.new("Attempted to write an event to a closed AckedQueue")
|
@@ -373,26 +303,5 @@ module LogStash; module Util
|
|
373
303
|
end
|
374
304
|
end
|
375
305
|
end
|
376
|
-
|
377
|
-
class WriteBatch
|
378
|
-
def initialize
|
379
|
-
@events = []
|
380
|
-
end
|
381
|
-
|
382
|
-
def size
|
383
|
-
@events.size
|
384
|
-
end
|
385
|
-
|
386
|
-
def push(event)
|
387
|
-
@events.push(event)
|
388
|
-
end
|
389
|
-
alias_method(:<<, :push)
|
390
|
-
|
391
|
-
def each(&blk)
|
392
|
-
@events.each do |e|
|
393
|
-
blk.call(e)
|
394
|
-
end
|
395
|
-
end
|
396
|
-
end
|
397
306
|
end
|
398
307
|
end end
|