logstash-core 6.0.0.beta1-java → 6.0.0.beta2-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/logstash-core/logstash-core.jar +0 -0
- data/lib/logstash-core/version.rb +1 -1
- data/lib/logstash/agent.rb +0 -16
- data/lib/logstash/compiler/lscl.rb +2 -53
- data/lib/logstash/compiler/lscl/helpers.rb +55 -0
- data/lib/logstash/config/config_ast.rb +6 -3
- data/lib/logstash/config/modules_common.rb +4 -1
- data/lib/logstash/elasticsearch_client.rb +4 -1
- data/lib/logstash/environment.rb +8 -2
- data/lib/logstash/filter_delegator.rb +11 -6
- data/lib/logstash/instrument/collector.rb +7 -5
- data/lib/logstash/instrument/metric_store.rb +6 -9
- data/lib/logstash/instrument/namespaced_metric.rb +4 -0
- data/lib/logstash/instrument/namespaced_null_metric.rb +4 -0
- data/lib/logstash/instrument/null_metric.rb +10 -0
- data/lib/logstash/instrument/wrapped_write_client.rb +33 -24
- data/lib/logstash/modules/kibana_client.rb +5 -3
- data/lib/logstash/modules/kibana_config.rb +1 -4
- data/lib/logstash/modules/scaffold.rb +2 -0
- data/lib/logstash/modules/settings_merger.rb +52 -4
- data/lib/logstash/output_delegator.rb +7 -5
- data/lib/logstash/pipeline.rb +37 -14
- data/lib/logstash/pipeline_settings.rb +2 -0
- data/lib/logstash/runner.rb +14 -2
- data/lib/logstash/settings.rb +26 -0
- data/lib/logstash/util/cloud_setting_auth.rb +29 -0
- data/lib/logstash/util/cloud_setting_id.rb +41 -0
- data/lib/logstash/util/modules_setting_array.rb +28 -0
- data/lib/logstash/util/wrapped_acked_queue.rb +5 -6
- data/lib/logstash/util/wrapped_synchronous_queue.rb +14 -9
- data/lib/logstash/version.rb +1 -1
- data/locales/en.yml +16 -0
- data/spec/logstash/agent/converge_spec.rb +6 -7
- data/spec/logstash/config/source/multi_local_spec.rb +11 -0
- data/spec/logstash/filter_delegator_spec.rb +20 -8
- data/spec/logstash/legacy_ruby_event_spec.rb +4 -4
- data/spec/logstash/modules/scaffold_spec.rb +2 -7
- data/spec/logstash/modules/settings_merger_spec.rb +111 -0
- data/spec/logstash/output_delegator_spec.rb +15 -5
- data/spec/logstash/pipeline_spec.rb +39 -7
- data/spec/logstash/runner_spec.rb +4 -1
- data/spec/logstash/settings/modules_spec.rb +115 -0
- metadata +10 -2
@@ -50,12 +50,14 @@ module LogStash module Modules class KibanaClient
|
|
50
50
|
|
51
51
|
@client = Manticore::Client.new(client_options)
|
52
52
|
@host = @settings.fetch("var.kibana.host", "localhost:5601")
|
53
|
-
username = @settings["var.kibana.username"]
|
54
|
-
password = @settings["var.kibana.password"]
|
55
|
-
|
56
53
|
@scheme = @settings.fetch("var.kibana.scheme", "http")
|
57
54
|
@http_options = {:headers => {'Content-Type' => 'application/json'}}
|
55
|
+
username = @settings["var.kibana.username"]
|
58
56
|
if username
|
57
|
+
password = @settings["var.kibana.password"]
|
58
|
+
if password.is_a?(LogStash::Util::Password)
|
59
|
+
password = password.value
|
60
|
+
end
|
59
61
|
@http_options[:headers]['Authorization'] = 'Basic ' + Base64.encode64( "#{username}:#{password}" ).chomp
|
60
62
|
end
|
61
63
|
|
@@ -11,7 +11,6 @@ module LogStash module Modules class KibanaConfig
|
|
11
11
|
include LogStash::Util::Loggable
|
12
12
|
|
13
13
|
ALLOWED_DIRECTORIES = ["search", "visualization"]
|
14
|
-
METRICS_MAX_BUCKETS = (24 * 60 * 60).freeze # 24 hours of events/sec buckets.
|
15
14
|
attr_reader :index_name # not used when importing via kibana but for BWC with ElastsearchConfig
|
16
15
|
|
17
16
|
# We name it `modul` here because `module` has meaning in Ruby.
|
@@ -21,10 +20,8 @@ module LogStash module Modules class KibanaConfig
|
|
21
20
|
@settings = settings
|
22
21
|
@index_name = "kibana"
|
23
22
|
@pattern_name = "#{@name}-*"
|
24
|
-
@metrics_max_buckets = @settings.fetch("dashboards.metrics_max_buckets", METRICS_MAX_BUCKETS).to_i
|
25
23
|
@kibana_settings = [
|
26
|
-
KibanaSettings::Setting.new("defaultIndex", @pattern_name)
|
27
|
-
KibanaSettings::Setting.new("metrics:max_buckets", @metrics_max_buckets)
|
24
|
+
KibanaSettings::Setting.new("defaultIndex", @pattern_name)
|
28
25
|
]
|
29
26
|
end
|
30
27
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/namespace"
|
3
3
|
require "logstash/logging"
|
4
|
+
require "logstash/util/loggable"
|
4
5
|
require "erb"
|
5
6
|
|
6
7
|
require_relative "elasticsearch_config"
|
@@ -17,6 +18,7 @@ module LogStash module Modules class Scaffold
|
|
17
18
|
@module_name = name
|
18
19
|
@directory = directory # this is the 'configuration folder in the GEM root.'
|
19
20
|
@kibana_version_parts = "6.0.0".split('.') # this is backup in case kibana client fails to connect
|
21
|
+
logger.info("Initializing module", :module_name => name, :directory => directory)
|
20
22
|
end
|
21
23
|
|
22
24
|
def add_kibana_version(version_parts)
|
@@ -1,8 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/namespace"
|
3
|
+
require "logstash/util"
|
4
|
+
require "logstash/util/loggable"
|
3
5
|
|
4
|
-
module LogStash module Modules
|
5
|
-
|
6
|
+
module LogStash module Modules module SettingsMerger
|
7
|
+
include LogStash::Util::Loggable
|
8
|
+
extend self
|
9
|
+
|
10
|
+
def merge(cli_settings, yml_settings)
|
6
11
|
# both args are arrays of hashes, e.g.
|
7
12
|
# [{"name"=>"mod1", "var.input.tcp.port"=>"3333"}, {"name"=>"mod2"}]
|
8
13
|
# [{"name"=>"mod1", "var.input.tcp.port"=>2222, "var.kibana.username"=>"rupert", "var.kibana.password"=>"fotherington"}, {"name"=>"mod3", "var.input.tcp.port"=>4445}]
|
@@ -11,13 +16,56 @@ module LogStash module Modules class SettingsMerger
|
|
11
16
|
# union will also coalesce identical hashes
|
12
17
|
union_of_settings = (cli_settings | yml_settings)
|
13
18
|
grouped_by_name = union_of_settings.group_by{|e| e["name"]}
|
14
|
-
grouped_by_name.each do |
|
19
|
+
grouped_by_name.each do |_, array|
|
15
20
|
if array.size == 2
|
16
|
-
merged << array.
|
21
|
+
merged << array.last.merge(array.first)
|
17
22
|
else
|
18
23
|
merged.concat(array)
|
19
24
|
end
|
20
25
|
end
|
21
26
|
merged
|
22
27
|
end
|
28
|
+
|
29
|
+
def merge_cloud_settings(module_settings, logstash_settings)
|
30
|
+
cloud_id = logstash_settings.get("cloud.id")
|
31
|
+
cloud_auth = logstash_settings.get("cloud.auth")
|
32
|
+
if cloud_id.nil?
|
33
|
+
if cloud_auth.nil?
|
34
|
+
return # user did not specify cloud settings
|
35
|
+
else
|
36
|
+
raise ArgumentError.new("Cloud Auth without Cloud Id")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
if logger.debug?
|
40
|
+
settings_copy = LogStash::Util.deep_clone(module_settings)
|
41
|
+
end
|
42
|
+
|
43
|
+
module_settings["var.kibana.scheme"] = "https"
|
44
|
+
module_settings["var.kibana.host"] = cloud_id.kibana_host
|
45
|
+
module_settings["var.elasticsearch.hosts"] = cloud_id.elasticsearch_host
|
46
|
+
unless cloud_auth.nil?
|
47
|
+
module_settings["var.elasticsearch.username"] = cloud_auth.username
|
48
|
+
module_settings["var.elasticsearch.password"] = cloud_auth.password
|
49
|
+
module_settings["var.kibana.username"] = cloud_auth.username
|
50
|
+
module_settings["var.kibana.password"] = cloud_auth.password
|
51
|
+
end
|
52
|
+
if logger.debug?
|
53
|
+
format_module_settings(settings_copy, module_settings).each {|line| logger.debug(line)}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def format_module_settings(settings_before, settings_after)
|
58
|
+
output = []
|
59
|
+
output << "-------- Module Settings ---------"
|
60
|
+
settings_after.each do |setting_name, setting|
|
61
|
+
setting_before = settings_before.fetch(setting_name, "")
|
62
|
+
line = "#{setting_name}: '#{setting}'"
|
63
|
+
if setting_before != setting
|
64
|
+
line.concat(", was: '#{setting_before}'")
|
65
|
+
end
|
66
|
+
output << line
|
67
|
+
end
|
68
|
+
output << "-------- Module Settings ---------"
|
69
|
+
output
|
70
|
+
end
|
23
71
|
end end end
|
@@ -19,7 +19,9 @@ module LogStash class OutputDelegator
|
|
19
19
|
@namespaced_metric = metric.namespace(id.to_sym)
|
20
20
|
@namespaced_metric.gauge(:name, config_name)
|
21
21
|
@metric_events = @namespaced_metric.namespace(:events)
|
22
|
-
|
22
|
+
@in_counter = @metric_events.counter(:in)
|
23
|
+
@out_counter = @metric_events.counter(:out)
|
24
|
+
@time_metric = @metric_events.counter(:duration_in_millis)
|
23
25
|
@strategy = strategy_registry.
|
24
26
|
class_for(self.concurrency).
|
25
27
|
new(@logger, @output_class, @namespaced_metric, execution_context, plugin_args)
|
@@ -42,11 +44,11 @@ module LogStash class OutputDelegator
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def multi_receive(events)
|
45
|
-
@
|
46
|
-
|
47
|
+
@in_counter.increment(events.length)
|
48
|
+
start_time = java.lang.System.current_time_millis
|
47
49
|
@strategy.multi_receive(events)
|
48
|
-
|
49
|
-
@
|
50
|
+
@time_metric.increment(java.lang.System.current_time_millis - start_time)
|
51
|
+
@out_counter.increment(events.length)
|
50
52
|
end
|
51
53
|
|
52
54
|
def do_close
|
data/lib/logstash/pipeline.rb
CHANGED
@@ -38,7 +38,7 @@ module LogStash; class BasePipeline
|
|
38
38
|
|
39
39
|
def initialize(pipeline_config, namespaced_metric = nil, agent = nil)
|
40
40
|
@logger = self.logger
|
41
|
-
|
41
|
+
@mutex = Mutex.new
|
42
42
|
@ephemeral_id = SecureRandom.uuid
|
43
43
|
|
44
44
|
@pipeline_config = pipeline_config
|
@@ -107,16 +107,27 @@ module LogStash; class BasePipeline
|
|
107
107
|
LogStash::Compiler.compile_sources(sources_with_metadata, @settings)
|
108
108
|
end
|
109
109
|
|
110
|
-
def plugin(plugin_type, name, *args)
|
110
|
+
def plugin(plugin_type, name, line, column, *args)
|
111
111
|
@plugin_counter += 1
|
112
112
|
|
113
113
|
# Collapse the array of arguments into a single merged hash
|
114
114
|
args = args.reduce({}, &:merge)
|
115
115
|
|
116
|
-
|
117
|
-
|
116
|
+
if plugin_type == "codec"
|
117
|
+
id = SecureRandom.uuid # codecs don't really use their IDs for metrics, so we can use anything here
|
118
118
|
else
|
119
|
-
|
119
|
+
# Pull the ID from LIR to keep IDs consistent between the two representations
|
120
|
+
id = lir.graph.vertices.filter do |v|
|
121
|
+
v.source_with_metadata &&
|
122
|
+
v.source_with_metadata.line == line &&
|
123
|
+
v.source_with_metadata.column == column
|
124
|
+
end.findFirst.get.id
|
125
|
+
end
|
126
|
+
|
127
|
+
args["id"] = id # some code pulls the id out of the args
|
128
|
+
|
129
|
+
if !id
|
130
|
+
raise ConfigurationError, "Could not determine ID for #{plugin_type}/#{plugin_name}"
|
120
131
|
end
|
121
132
|
|
122
133
|
raise ConfigurationError, "Two plugins have the id '#{id}', please fix this conflict" if @plugins_by_id[id]
|
@@ -231,6 +242,7 @@ module LogStash; class Pipeline < BasePipeline
|
|
231
242
|
@running = Concurrent::AtomicBoolean.new(false)
|
232
243
|
@flushing = Concurrent::AtomicReference.new(false)
|
233
244
|
@force_shutdown = Concurrent::AtomicBoolean.new(false)
|
245
|
+
@outputs_registered = Concurrent::AtomicBoolean.new(false)
|
234
246
|
end # def initialize
|
235
247
|
|
236
248
|
def ready?
|
@@ -392,9 +404,9 @@ module LogStash; class Pipeline < BasePipeline
|
|
392
404
|
|
393
405
|
def start_workers
|
394
406
|
@worker_threads.clear # In case we're restarting the pipeline
|
407
|
+
@outputs_registered.make_false
|
395
408
|
begin
|
396
|
-
|
397
|
-
register_plugins(@filters)
|
409
|
+
maybe_setup_out_plugins
|
398
410
|
|
399
411
|
pipeline_workers = safe_pipeline_worker_count
|
400
412
|
batch_size = @settings.get("pipeline.batch.size")
|
@@ -460,16 +472,17 @@ module LogStash; class Pipeline < BasePipeline
|
|
460
472
|
shutdown_requested |= signal.shutdown? # latch on shutdown signal
|
461
473
|
|
462
474
|
batch = @filter_queue_client.read_batch # metrics are started in read_batch
|
463
|
-
if
|
475
|
+
if batch.size > 0
|
464
476
|
@events_consumed.increment(batch.size)
|
465
477
|
filter_batch(batch)
|
466
|
-
|
478
|
+
end
|
479
|
+
flush_filters_to_batch(batch, :final => false) if signal.flush?
|
480
|
+
if batch.size > 0
|
467
481
|
output_batch(batch)
|
468
482
|
unless @force_shutdown.true? # ack the current batch
|
469
483
|
@filter_queue_client.close_batch(batch)
|
470
484
|
end
|
471
485
|
end
|
472
|
-
|
473
486
|
# keep break at end of loop, after the read_batch operation, some pipeline specs rely on this "final read_batch" before shutdown.
|
474
487
|
break if (shutdown_requested && !draining_queue?) || @force_shutdown.true?
|
475
488
|
end
|
@@ -652,11 +665,11 @@ module LogStash; class Pipeline < BasePipeline
|
|
652
665
|
# for backward compatibility in devutils for the rspec helpers, this method is not used
|
653
666
|
# in the pipeline anymore.
|
654
667
|
def filter(event, &block)
|
668
|
+
maybe_setup_out_plugins
|
655
669
|
# filter_func returns all filtered events, including cancelled ones
|
656
|
-
filter_func(event).each {
|
670
|
+
filter_func(event).each {|e| block.call(e)}
|
657
671
|
end
|
658
672
|
|
659
|
-
|
660
673
|
# perform filters flush and yield flushed event to the passed block
|
661
674
|
# @param options [Hash]
|
662
675
|
# @option options [Boolean] :final => true to signal a final shutdown flush
|
@@ -791,9 +804,16 @@ module LogStash; class Pipeline < BasePipeline
|
|
791
804
|
|
792
805
|
private
|
793
806
|
|
807
|
+
def maybe_setup_out_plugins
|
808
|
+
if @outputs_registered.make_true
|
809
|
+
register_plugins(@outputs)
|
810
|
+
register_plugins(@filters)
|
811
|
+
end
|
812
|
+
end
|
813
|
+
|
794
814
|
def default_logging_keys(other_keys = {})
|
795
815
|
keys = super
|
796
|
-
keys[:thread]
|
816
|
+
keys[:thread] ||= thread.inspect if thread
|
797
817
|
keys
|
798
818
|
end
|
799
819
|
|
@@ -802,6 +822,9 @@ module LogStash; class Pipeline < BasePipeline
|
|
802
822
|
end
|
803
823
|
|
804
824
|
def wrapped_write_client(plugin)
|
805
|
-
|
825
|
+
#need to ensure that metrics are initialized one plugin at a time, else a race condition can exist.
|
826
|
+
@mutex.synchronize do
|
827
|
+
LogStash::Instrument::WrappedWriteClient.new(@input_queue_client, self, metric, plugin)
|
828
|
+
end
|
806
829
|
end
|
807
830
|
end; end
|
@@ -12,8 +12,10 @@ module LogStash
|
|
12
12
|
"config.reload.interval",
|
13
13
|
"config.string",
|
14
14
|
"dead_letter_queue.enable",
|
15
|
+
"dead_letter_queue.max_bytes",
|
15
16
|
"metric.collect",
|
16
17
|
"path.config",
|
18
|
+
"path.dead_letter_queue",
|
17
19
|
"path.queue",
|
18
20
|
"pipeline.batch.delay",
|
19
21
|
"pipeline.batch.size",
|
data/lib/logstash/runner.rb
CHANGED
@@ -74,6 +74,19 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
74
74
|
:multivalued => true,
|
75
75
|
:attribute_name => "modules_variable_list"
|
76
76
|
|
77
|
+
option ["--setup"], :flag,
|
78
|
+
I18n.t("logstash.runner.flag.modules_setup"),
|
79
|
+
:default => LogStash::SETTINGS.get_default("modules_setup"),
|
80
|
+
:attribute_name => "modules_setup"
|
81
|
+
|
82
|
+
option ["--cloud.id"], "CLOUD_ID",
|
83
|
+
I18n.t("logstash.runner.flag.cloud_id"),
|
84
|
+
:attribute_name => "cloud.id"
|
85
|
+
|
86
|
+
option ["--cloud.auth"], "CLOUD_AUTH",
|
87
|
+
I18n.t("logstash.runner.flag.cloud_auth"),
|
88
|
+
:attribute_name => "cloud.auth"
|
89
|
+
|
77
90
|
# Pipeline settings
|
78
91
|
option ["-w", "--pipeline.workers"], "COUNT",
|
79
92
|
I18n.t("logstash.runner.flag.pipeline-workers"),
|
@@ -468,8 +481,7 @@ class LogStash::Runner < Clamp::StrictCommand
|
|
468
481
|
Stud::trap("INT") do
|
469
482
|
if @interrupted_once
|
470
483
|
logger.fatal(I18n.t("logstash.agent.forced_sigint"))
|
471
|
-
|
472
|
-
exit
|
484
|
+
exit(1)
|
473
485
|
else
|
474
486
|
logger.warn(I18n.t("logstash.agent.sigint"))
|
475
487
|
Thread.new(logger) {|lg| sleep 5; lg.warn(I18n.t("logstash.agent.slow_shutdown")) }
|
data/lib/logstash/settings.rb
CHANGED
@@ -255,6 +255,7 @@ module LogStash
|
|
255
255
|
@default = default
|
256
256
|
end
|
257
257
|
end
|
258
|
+
|
258
259
|
def set(value)
|
259
260
|
coerced_value = coerce(value)
|
260
261
|
validate(coerced_value)
|
@@ -557,7 +558,32 @@ module LogStash
|
|
557
558
|
end
|
558
559
|
end
|
559
560
|
end
|
561
|
+
|
562
|
+
class Modules < Coercible
|
563
|
+
def initialize(name, klass, default = nil)
|
564
|
+
super(name, klass, default, false)
|
565
|
+
end
|
566
|
+
|
567
|
+
def set(value)
|
568
|
+
@value = coerce(value)
|
569
|
+
@value_is_set = true
|
570
|
+
@value
|
571
|
+
end
|
572
|
+
|
573
|
+
def coerce(value)
|
574
|
+
if value.is_a?(@klass)
|
575
|
+
return value
|
576
|
+
end
|
577
|
+
@klass.new(value)
|
578
|
+
end
|
579
|
+
|
580
|
+
protected
|
581
|
+
def validate(value)
|
582
|
+
coerce(value)
|
583
|
+
end
|
584
|
+
end
|
560
585
|
end
|
561
586
|
|
587
|
+
|
562
588
|
SETTINGS = Settings.new
|
563
589
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/util/password"
|
4
|
+
|
5
|
+
module LogStash module Util class CloudSettingAuth
|
6
|
+
attr_reader :original, :username, :password
|
7
|
+
|
8
|
+
def initialize(value)
|
9
|
+
return if value.nil?
|
10
|
+
|
11
|
+
unless value.is_a?(String)
|
12
|
+
raise ArgumentError.new("Cloud Auth must be String. Received: #{value.class}")
|
13
|
+
end
|
14
|
+
@original = value
|
15
|
+
@username, sep, password = @original.partition(":")
|
16
|
+
if @username.empty? || sep.empty? || password.empty?
|
17
|
+
raise ArgumentError.new("Cloud Auth username and password format should be \"<username>:<password>\".")
|
18
|
+
end
|
19
|
+
@password = LogStash::Util::Password.new(password)
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"#{@username}:#{@password}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def inspect
|
27
|
+
to_s
|
28
|
+
end
|
29
|
+
end end end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "base64"
|
4
|
+
|
5
|
+
module LogStash module Util class CloudSettingId
|
6
|
+
attr_reader :original, :decoded, :label, :elasticsearch_host, :kibana_host
|
7
|
+
|
8
|
+
def initialize(value)
|
9
|
+
return if value.nil?
|
10
|
+
|
11
|
+
unless value.is_a?(String)
|
12
|
+
raise ArgumentError.new("Cloud Id must be String. Received: #{value.class}")
|
13
|
+
end
|
14
|
+
@original = value
|
15
|
+
@label, sep, last = value.partition(":")
|
16
|
+
if last.empty?
|
17
|
+
@decoded = Base64.urlsafe_decode64(@label) rescue ""
|
18
|
+
@label = ""
|
19
|
+
else
|
20
|
+
@decoded = Base64.urlsafe_decode64(last) rescue ""
|
21
|
+
end
|
22
|
+
unless @decoded.count("$") == 2
|
23
|
+
raise ArgumentError.new("Cloud Id does not decode. Received: \"#{@original}\".")
|
24
|
+
end
|
25
|
+
parts = @decoded.split("$")
|
26
|
+
if parts.any?(&:empty?)
|
27
|
+
raise ArgumentError.new("Cloud Id, after decoding, is invalid. Format: '<part1>$<part2>$<part3>'. Received: \"#{@decoded}\".")
|
28
|
+
end
|
29
|
+
cloud_host, es_server, kb_server = parts
|
30
|
+
@elasticsearch_host = sprintf("%s.%s:443", es_server, cloud_host)
|
31
|
+
@kibana_host = sprintf("%s.%s:443", kb_server, cloud_host)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
@original.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def inspect
|
39
|
+
to_s
|
40
|
+
end
|
41
|
+
end end end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/namespace"
|
3
|
+
require "logstash/util/password"
|
4
|
+
|
5
|
+
module LogStash module Util class ModulesSettingArray
|
6
|
+
extend Forwardable
|
7
|
+
DELEGATED_METHODS = [].public_methods.reject{|symbol| symbol.to_s.end_with?('__')}
|
8
|
+
|
9
|
+
def_delegators :@original, *DELEGATED_METHODS
|
10
|
+
|
11
|
+
attr_reader :original
|
12
|
+
def initialize(value)
|
13
|
+
unless value.is_a?(Array)
|
14
|
+
raise ArgumentError.new("Module Settings must be an Array. Received: #{value.class}")
|
15
|
+
end
|
16
|
+
@original = value
|
17
|
+
# wrap passwords
|
18
|
+
@original.each do |hash|
|
19
|
+
hash.keys.select{|key| key.to_s.end_with?('password')}.each do |key|
|
20
|
+
hash[key] = LogStash::Util::Password.new(hash[key])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def __class__
|
26
|
+
LogStash::Util::ModulesSettingArray
|
27
|
+
end
|
28
|
+
end end end
|