logstash-core 5.5.3-java → 5.6.0-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/api/commands/node.rb +2 -2
- data/lib/logstash/api/commands/stats.rb +2 -2
- data/lib/logstash/config/config_ast.rb +24 -1
- data/lib/logstash/config/modules_common.rb +47 -15
- data/lib/logstash/config/source/modules.rb +55 -0
- data/lib/logstash/config/string_escape.rb +27 -0
- data/lib/logstash/elasticsearch_client.rb +24 -2
- data/lib/logstash/environment.rb +2 -0
- data/lib/logstash/filter_delegator.rb +9 -6
- data/lib/logstash/instrument/collector.rb +7 -5
- data/lib/logstash/instrument/metric_store.rb +11 -11
- 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/periodic_poller/dlq.rb +19 -0
- data/lib/logstash/instrument/periodic_pollers.rb +3 -1
- data/lib/logstash/instrument/wrapped_write_client.rb +33 -24
- data/lib/logstash/logging/logger.rb +26 -19
- data/lib/logstash/modules/{importer.rb → elasticsearch_importer.rb} +3 -3
- data/lib/logstash/modules/kibana_base.rb +24 -0
- data/lib/logstash/modules/kibana_client.rb +124 -0
- data/lib/logstash/modules/kibana_config.rb +29 -28
- data/lib/logstash/modules/kibana_dashboards.rb +36 -0
- data/lib/logstash/modules/kibana_importer.rb +17 -0
- data/lib/logstash/modules/kibana_settings.rb +40 -0
- data/lib/logstash/modules/logstash_config.rb +89 -17
- data/lib/logstash/modules/resource_base.rb +6 -5
- data/lib/logstash/modules/scaffold.rb +11 -3
- data/lib/logstash/modules/settings_merger.rb +23 -0
- data/lib/logstash/modules/util.rb +17 -0
- data/lib/logstash/output_delegator.rb +7 -5
- data/lib/logstash/pipeline.rb +34 -2
- data/lib/logstash/runner.rb +8 -13
- data/lib/logstash/settings.rb +20 -1
- data/lib/logstash/util/wrapped_acked_queue.rb +5 -24
- data/lib/logstash/util/wrapped_synchronous_queue.rb +14 -24
- data/lib/logstash/version.rb +1 -1
- data/locales/en.yml +11 -4
- data/spec/logstash/agent_spec.rb +19 -6
- data/spec/logstash/api/modules/node_spec.rb +2 -1
- data/spec/logstash/config/config_ast_spec.rb +47 -8
- data/spec/logstash/config/string_escape_spec.rb +24 -0
- data/spec/logstash/event_spec.rb +9 -0
- data/spec/logstash/filter_delegator_spec.rb +21 -7
- data/spec/logstash/instrument/periodic_poller/dlq_spec.rb +17 -0
- data/spec/logstash/instrument/periodic_poller/jvm_spec.rb +1 -1
- data/spec/logstash/legacy_ruby_event_spec.rb +4 -4
- data/spec/logstash/modules/logstash_config_spec.rb +56 -0
- data/spec/logstash/modules/scaffold_spec.rb +234 -0
- data/spec/logstash/output_delegator_spec.rb +15 -5
- data/spec/logstash/pipeline_spec.rb +76 -26
- data/spec/logstash/runner_spec.rb +46 -25
- data/spec/logstash/settings/splittable_string_array_spec.rb +51 -0
- data/spec/logstash/util/wrapped_synchronous_queue_spec.rb +0 -22
- metadata +22 -4
- data/lib/logstash/modules/kibana_base_resource.rb +0 -10
- data/lib/logstash/program.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0f19e6dd83b6582139637f263865a2249965e84
|
4
|
+
data.tar.gz: d80ae0275d1526e640468e236b7b809fd90f9577
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbdbb0a428571a5409bdadb6cb100f2b494d513a2a8a6b0b8d40a90bd3f046956a5feeee71f64eea7ea0f5a1f63584e599e9cc8325839baa541e7309de3c1def
|
7
|
+
data.tar.gz: d1c50059807f9a8fc6b87a65d713c659261356106a7097523561688e86fb9d592c069a35ae89fda59a66d0ce082f91030811296d8ac779e9557ead6c64821093
|
Binary file
|
@@ -20,8 +20,8 @@ module LogStash
|
|
20
20
|
def pipeline(pipeline_id = LogStash::SETTINGS.get("pipeline.id").to_sym)
|
21
21
|
stats = extract_metrics(
|
22
22
|
[:stats, :pipelines, pipeline_id, :config],
|
23
|
-
:workers, :batch_size, :batch_delay, :config_reload_automatic, :config_reload_interval
|
24
|
-
)
|
23
|
+
:workers, :batch_size, :batch_delay, :config_reload_automatic, :config_reload_interval, :dead_letter_queue_enabled, :dead_letter_queue_path
|
24
|
+
).reject{|_, v|v.nil?}
|
25
25
|
stats.merge(:id => pipeline_id)
|
26
26
|
end
|
27
27
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'logstash/errors'
|
3
|
+
require "logstash/config/string_escape"
|
3
4
|
require "treetop"
|
4
5
|
|
5
6
|
class Treetop::Runtime::SyntaxNode
|
@@ -9,6 +10,18 @@ class Treetop::Runtime::SyntaxNode
|
|
9
10
|
return elements.collect(&:compile).reject(&:empty?).join("")
|
10
11
|
end
|
11
12
|
|
13
|
+
def get_meta(key)
|
14
|
+
@ast_metadata ||= {}
|
15
|
+
return @ast_metadata[key] if @ast_metadata[key]
|
16
|
+
return self.parent.get_meta(key) if self.parent
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_meta(key, value)
|
21
|
+
@ast_metadata ||= {}
|
22
|
+
@ast_metadata[key] = value
|
23
|
+
end
|
24
|
+
|
12
25
|
# Traverse the syntax tree recursively.
|
13
26
|
# The order should respect the order of the configuration file as it is read
|
14
27
|
# and written by humans (and the order in which it is parsed).
|
@@ -59,6 +72,7 @@ end
|
|
59
72
|
|
60
73
|
|
61
74
|
module LogStash; module Config; module AST
|
75
|
+
PROCESS_ESCAPE_SEQUENCES = :process_escape_sequences
|
62
76
|
|
63
77
|
def self.deferred_conditionals=(val)
|
64
78
|
@deferred_conditionals = val
|
@@ -91,6 +105,11 @@ module LogStash; module Config; module AST
|
|
91
105
|
end
|
92
106
|
|
93
107
|
class Config < Node
|
108
|
+
def process_escape_sequences=(val)
|
109
|
+
set_meta(PROCESS_ESCAPE_SEQUENCES, val)
|
110
|
+
end
|
111
|
+
|
112
|
+
|
94
113
|
def compile
|
95
114
|
LogStash::Config::AST.deferred_conditionals = []
|
96
115
|
LogStash::Config::AST.deferred_conditionals_index = 0
|
@@ -333,7 +352,11 @@ module LogStash; module Config; module AST
|
|
333
352
|
end
|
334
353
|
class String < Value
|
335
354
|
def compile
|
336
|
-
|
355
|
+
if get_meta(PROCESS_ESCAPE_SEQUENCES)
|
356
|
+
Unicode.wrap(LogStash::Config::StringEscape.process_escapes(text_value[1...-1]))
|
357
|
+
else
|
358
|
+
Unicode.wrap(text_value[1...-1])
|
359
|
+
end
|
337
360
|
end
|
338
361
|
end
|
339
362
|
class RegExp < Value
|
@@ -1,18 +1,33 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "logstash/util/loggable"
|
3
3
|
require "logstash/elasticsearch_client"
|
4
|
-
require "logstash/modules/
|
4
|
+
require "logstash/modules/kibana_client"
|
5
|
+
require "logstash/modules/elasticsearch_importer"
|
6
|
+
require "logstash/modules/kibana_importer"
|
7
|
+
require "logstash/modules/settings_merger"
|
5
8
|
require "logstash/errors"
|
6
9
|
|
7
10
|
module LogStash module Config
|
8
11
|
class ModulesCommon # extracted here for bwc with 5.x
|
9
12
|
include LogStash::Util::Loggable
|
10
13
|
|
14
|
+
MODULES_MAX_PIPELINES = 1
|
15
|
+
|
11
16
|
def self.pipeline_configs(settings)
|
12
17
|
pipelines = []
|
13
18
|
plugin_modules = LogStash::PLUGIN_REGISTRY.plugins_with_type(:modules)
|
14
19
|
|
15
|
-
|
20
|
+
cli_settings = settings.get("modules.cli")
|
21
|
+
yml_settings = settings.get("modules")
|
22
|
+
|
23
|
+
modules_array = if !(cli_settings.empty? && yml_settings.empty?)
|
24
|
+
LogStash::Modules::SettingsMerger.merge(cli_settings, yml_settings)
|
25
|
+
elsif cli_settings.empty?
|
26
|
+
yml_settings
|
27
|
+
else
|
28
|
+
cli_settings
|
29
|
+
end
|
30
|
+
|
16
31
|
if modules_array.empty?
|
17
32
|
# no specifed modules
|
18
33
|
return pipelines
|
@@ -20,6 +35,11 @@ module LogStash module Config
|
|
20
35
|
logger.debug("Specified modules", :modules_array => modules_array.to_s)
|
21
36
|
|
22
37
|
module_names = modules_array.collect {|module_hash| module_hash["name"]}
|
38
|
+
if module_names.size > MODULES_MAX_PIPELINES
|
39
|
+
error_message = I18n.t("logstash.modules.configuration.modules-too-many-specified", :max => MODULES_MAX_PIPELINES, :specified_modules => module_names.join(', '))
|
40
|
+
raise LogStash::ConfigLoadingError, error_message
|
41
|
+
end
|
42
|
+
|
23
43
|
if module_names.length > module_names.uniq.length
|
24
44
|
duplicate_modules = module_names.group_by(&:to_s).select { |_,v| v.size > 1 }.keys
|
25
45
|
raise LogStash::ConfigLoadingError, I18n.t("logstash.modules.configuration.modules-must-be-unique", :duplicate_modules => duplicate_modules)
|
@@ -36,29 +56,41 @@ module LogStash module Config
|
|
36
56
|
specified_and_available_names.each do |module_name|
|
37
57
|
connect_fail_args = {}
|
38
58
|
begin
|
59
|
+
module_settings = settings.clone
|
60
|
+
|
39
61
|
module_hash = modules_array.find {|m| m["name"] == module_name}
|
40
62
|
current_module = plugin_modules.find { |allmodules| allmodules.module_name == module_name }
|
41
63
|
|
42
64
|
alt_name = "module-#{module_name}"
|
43
65
|
pipeline_id = alt_name
|
44
|
-
|
66
|
+
module_settings.set("pipeline.id", pipeline_id)
|
45
67
|
current_module.with_settings(module_hash)
|
46
|
-
esclient = LogStash::ElasticsearchClient.build(module_hash)
|
47
68
|
config_test = settings.get("config.test_and_exit")
|
48
|
-
|
49
|
-
|
50
|
-
|
69
|
+
modul_setup = settings.get("modules_setup")
|
70
|
+
# Only import data if it's not a config test and --setup is true
|
71
|
+
if !config_test && modul_setup
|
72
|
+
esclient = LogStash::ElasticsearchClient.build(module_hash)
|
73
|
+
kbnclient = LogStash::Modules::KibanaClient.new(module_hash)
|
74
|
+
esconnected = esclient.can_connect?
|
75
|
+
kbnconnected = kbnclient.can_connect?
|
76
|
+
if esconnected && kbnconnected
|
77
|
+
current_module.add_kibana_version(kbnclient.version_parts)
|
78
|
+
current_module.import(
|
79
|
+
LogStash::Modules::ElasticsearchImporter.new(esclient),
|
80
|
+
LogStash::Modules::KibanaImporter.new(kbnclient)
|
81
|
+
)
|
82
|
+
else
|
83
|
+
connect_fail_args[:module_name] = module_name
|
84
|
+
connect_fail_args[:elasticsearch_hosts] = esclient.host_settings
|
85
|
+
connect_fail_args[:kibana_hosts] = kbnclient.host_settings
|
51
86
|
end
|
52
|
-
|
53
|
-
config_string = current_module.config_string
|
54
|
-
|
55
|
-
pipelines << {"pipeline_id" => pipeline_id, "alt_name" => alt_name, "config_string" => config_string, "settings" => settings}
|
56
|
-
else
|
57
|
-
connect_fail_args[:module_name] = module_name
|
58
|
-
connect_fail_args[:hosts] = esclient.host_settings
|
59
87
|
end
|
88
|
+
config_string = current_module.config_string
|
89
|
+
pipelines << {"pipeline_id" => pipeline_id, "alt_name" => alt_name, "config_string" => config_string, "settings" => module_settings}
|
60
90
|
rescue => e
|
61
|
-
|
91
|
+
new_error = LogStash::ConfigLoadingError.new(I18n.t("logstash.modules.configuration.parse-failed", :error => e.message))
|
92
|
+
new_error.set_backtrace(e.backtrace)
|
93
|
+
raise new_error
|
62
94
|
end
|
63
95
|
|
64
96
|
if !connect_fail_args.empty?
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/config/source/base"
|
3
|
+
require "logstash/config/modules_common"
|
4
|
+
require "logstash/config/pipeline_config"
|
5
|
+
require "logstash/util/loggable"
|
6
|
+
require "logstash/errors"
|
7
|
+
|
8
|
+
module LogStash module Config module Source
|
9
|
+
class Modules < Base
|
10
|
+
include LogStash::Util::Loggable
|
11
|
+
def pipeline_configs
|
12
|
+
if config_conflict? # double check
|
13
|
+
raise ConfigurationError, @conflict_messages.join(", ")
|
14
|
+
end
|
15
|
+
|
16
|
+
pipelines = LogStash::Config::ModulesCommon.pipeline_configs(@settings)
|
17
|
+
pipelines.map do |hash|
|
18
|
+
PipelineConfig.new(self, hash["pipeline_id"].to_sym,
|
19
|
+
org.logstash.common.SourceWithMetadata.new("module", hash["alt_name"], 0, 0, hash["config_string"]),
|
20
|
+
hash["settings"])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def match?
|
25
|
+
# see basic settings predicates and getters defined in the base class
|
26
|
+
(modules_cli? || modules?) && !(config_string? || config_path?) && !automatic_reload_with_modules?
|
27
|
+
end
|
28
|
+
|
29
|
+
def config_conflict?
|
30
|
+
@conflict_messages.clear
|
31
|
+
# Make note that if modules are configured in both cli and logstash.yml that cli module
|
32
|
+
# settings will overwrite the logstash.yml modules settings
|
33
|
+
if modules_cli? && modules?
|
34
|
+
logger.info(I18n.t("logstash.runner.cli-module-override"))
|
35
|
+
end
|
36
|
+
|
37
|
+
if automatic_reload_with_modules?
|
38
|
+
@conflict_messages << I18n.t("logstash.runner.reload-with-modules")
|
39
|
+
end
|
40
|
+
|
41
|
+
# Check if config (-f or -e) and modules are configured
|
42
|
+
if (modules_cli? || modules?) && (config_string? || config_path?)
|
43
|
+
@conflict_messages << I18n.t("logstash.runner.config-module-exclusive")
|
44
|
+
end
|
45
|
+
|
46
|
+
@conflict_messages.any?
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def automatic_reload_with_modules?
|
52
|
+
(modules_cli? || modules?) && config_reload_automatic?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end end end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module LogStash; module Config; module StringEscape
|
4
|
+
class << self
|
5
|
+
def process_escapes(input)
|
6
|
+
input.gsub(/\\./) do |value|
|
7
|
+
process(value)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def process(value)
|
13
|
+
case value[1]
|
14
|
+
when '"', "'", "\\"
|
15
|
+
value[1]
|
16
|
+
when "n"
|
17
|
+
"\n"
|
18
|
+
when "r"
|
19
|
+
"\r"
|
20
|
+
when "t"
|
21
|
+
"\t"
|
22
|
+
else
|
23
|
+
value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end end end
|
@@ -26,6 +26,24 @@ module LogStash class ElasticsearchClient
|
|
26
26
|
@settings = settings
|
27
27
|
@logger = logger
|
28
28
|
@client_args = client_args
|
29
|
+
|
30
|
+
ssl_options = {}
|
31
|
+
|
32
|
+
if @settings["var.elasticsearch.ssl.enabled"] == "true"
|
33
|
+
ssl_options[:verify] = @settings.fetch("var.elasticsearch.ssl.verification_mode", true)
|
34
|
+
ssl_options[:ca_file] = @settings.fetch("var.elasticsearch.ssl.certificate_authority", nil)
|
35
|
+
ssl_options[:client_cert] = @settings.fetch("var.elasticsearch.ssl.certificate", nil)
|
36
|
+
ssl_options[:client_key] = @settings.fetch("var.elasticsearch.ssl.key", nil)
|
37
|
+
end
|
38
|
+
|
39
|
+
@client_args[:ssl] = ssl_options
|
40
|
+
|
41
|
+
username = @settings["var.elasticsearch.username"]
|
42
|
+
password = @settings["var.elasticsearch.password"]
|
43
|
+
if username
|
44
|
+
@client_args[:transport_options] = { :headers => { "Authorization" => 'Basic ' + Base64.encode64( "#{username}:#{password}" ).chomp } }
|
45
|
+
end
|
46
|
+
|
29
47
|
@client = Elasticsearch::Client.new(@client_args)
|
30
48
|
end
|
31
49
|
|
@@ -90,7 +108,11 @@ module LogStash class ElasticsearchClient
|
|
90
108
|
end
|
91
109
|
|
92
110
|
def unpack_hosts
|
93
|
-
@settings.fetch("var.
|
111
|
+
setting = @settings.fetch("var.elasticsearch.hosts", "localhost:9200")
|
112
|
+
if setting.is_a?(String)
|
113
|
+
return setting.split(',').map(&:strip)
|
114
|
+
end
|
115
|
+
setting
|
94
116
|
end
|
95
117
|
end
|
96
118
|
|
@@ -117,4 +139,4 @@ module LogStash class ElasticsearchClient
|
|
117
139
|
def host_settings
|
118
140
|
@client.host_settings
|
119
141
|
end
|
120
|
-
end end
|
142
|
+
end end
|
data/lib/logstash/environment.rb
CHANGED
@@ -22,8 +22,10 @@ module LogStash
|
|
22
22
|
Setting::NullableString.new("config.string", nil, false),
|
23
23
|
Setting.new("modules.cli", Array, []),
|
24
24
|
Setting.new("modules", Array, []),
|
25
|
+
Setting::Boolean.new("modules_setup", false),
|
25
26
|
Setting::Boolean.new("config.test_and_exit", false),
|
26
27
|
Setting::Boolean.new("config.reload.automatic", false),
|
28
|
+
Setting::Boolean.new("config.support_escapes", false),
|
27
29
|
Setting::Numeric.new("config.reload.interval", 3), # in seconds
|
28
30
|
Setting::Boolean.new("metric.collect", true),
|
29
31
|
Setting::String.new("pipeline.id", "main"),
|
@@ -26,6 +26,9 @@ module LogStash
|
|
26
26
|
@filter.execution_context = execution_context
|
27
27
|
|
28
28
|
@metric_events = namespaced_metric.namespace(:events)
|
29
|
+
@metric_events_in = @metric_events.counter(:in)
|
30
|
+
@metric_events_out = @metric_events.counter(:out)
|
31
|
+
@metric_events_time = @metric_events.counter(:duration_in_millis)
|
29
32
|
namespaced_metric.gauge(:name, config_name)
|
30
33
|
|
31
34
|
# Not all the filters will do bufferings
|
@@ -37,19 +40,19 @@ module LogStash
|
|
37
40
|
end
|
38
41
|
|
39
42
|
def multi_filter(events)
|
40
|
-
@
|
43
|
+
@metric_events_in.increment(events.size)
|
41
44
|
|
42
|
-
|
45
|
+
start_time = java.lang.System.current_time_millis
|
43
46
|
new_events = @filter.multi_filter(events)
|
44
|
-
|
47
|
+
@metric_events_time.increment(java.lang.System.current_time_millis - start_time)
|
45
48
|
|
46
49
|
# There is no guarantee in the context of filter
|
47
50
|
# that EVENTS_INT == EVENTS_OUT, see the aggregates and
|
48
51
|
# the split filter
|
49
52
|
c = new_events.count { |event| !event.cancelled? }
|
50
|
-
@metric_events.increment(:out, c) if c > 0
|
51
53
|
|
52
|
-
|
54
|
+
@metric_events_out.increment(c) if c > 0
|
55
|
+
new_events
|
53
56
|
end
|
54
57
|
|
55
58
|
private
|
@@ -61,7 +64,7 @@ module LogStash
|
|
61
64
|
|
62
65
|
# Filter plugins that does buffering or spooling of events like the
|
63
66
|
# `Logstash-filter-aggregates` can return `NIL` and will flush on the next flush ticks.
|
64
|
-
@
|
67
|
+
@metric_events_out.increment(new_events.size) if new_events && new_events.size > 0
|
65
68
|
new_events
|
66
69
|
end
|
67
70
|
end
|
@@ -33,11 +33,7 @@ module LogStash module Instrument
|
|
33
33
|
#
|
34
34
|
def push(namespaces_path, key, type, *metric_type_params)
|
35
35
|
begin
|
36
|
-
|
37
|
-
LogStash::Instrument::MetricType.create(type, namespaces_path, key)
|
38
|
-
end
|
39
|
-
|
40
|
-
metric.execute(*metric_type_params)
|
36
|
+
get(namespaces_path, key, type).execute(*metric_type_params)
|
41
37
|
rescue MetricStore::NamespacesExpectedError => e
|
42
38
|
logger.error("Collector: Cannot record metric", :exception => e)
|
43
39
|
rescue NameError => e
|
@@ -51,6 +47,12 @@ module LogStash module Instrument
|
|
51
47
|
end
|
52
48
|
end
|
53
49
|
|
50
|
+
def get(namespaces_path, key, type)
|
51
|
+
@metric_store.fetch_or_store(namespaces_path, key) do
|
52
|
+
LogStash::Instrument::MetricType.create(type, namespaces_path, key)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
54
56
|
# Snapshot the current Metric Store and return it immediately,
|
55
57
|
# This is useful if you want to get access to the current metric store without
|
56
58
|
# waiting for a periodic call.
|
@@ -41,26 +41,26 @@ module LogStash module Instrument
|
|
41
41
|
# @param [Symbol] The metric key
|
42
42
|
# @return [Object] Return the new_value of the retrieve object in the tree
|
43
43
|
def fetch_or_store(namespaces, key, default_value = nil)
|
44
|
-
provided_value = block_given? ? yield(key) : default_value
|
45
44
|
|
46
45
|
# We first check in the `@fast_lookup` store to see if we have already see that metrics before,
|
47
46
|
# This give us a `o(1)` access, which is faster than searching through the structured
|
48
47
|
# data store (Which is a `o(n)` operation where `n` is the number of element in the namespace and
|
49
|
-
# the value of the key). If the metric is already present in the `@fast_lookup`,
|
50
|
-
#
|
48
|
+
# the value of the key). If the metric is already present in the `@fast_lookup`, then that value is sent
|
49
|
+
# back directly to the caller.
|
51
50
|
#
|
52
|
-
# BUT. If the value is not present in the `@fast_lookup` the value will be inserted and
|
53
|
-
# `#puf_if_absent` will return nil. With this returned value of nil we assume that we don't
|
51
|
+
# BUT. If the value is not present in the `@fast_lookup` the value will be inserted and we assume that we don't
|
54
52
|
# have it in the `@metric_store` for structured search so we add it there too.
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
|
54
|
+
value = @fast_lookup.get(namespaces.dup << key)
|
55
|
+
if value.nil?
|
56
|
+
value = block_given? ? yield(key) : default_value
|
57
|
+
@fast_lookup.put(namespaces.dup << key, value)
|
58
58
|
@structured_lookup_mutex.synchronize do
|
59
|
-
|
60
|
-
fetch_or_store_namespaces(namespaces).fetch_or_store(key,
|
59
|
+
# If we cannot find the value this mean we need to save it in the store.
|
60
|
+
fetch_or_store_namespaces(namespaces).fetch_or_store(key, value)
|
61
61
|
end
|
62
|
-
return provided_value
|
63
62
|
end
|
63
|
+
return value;
|
64
64
|
end
|
65
65
|
|
66
66
|
# This method allow to retrieve values for a specific path,
|