logstash-core 6.0.0.beta1-java → 6.0.0.beta2-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 +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
|