diff --git a/logstash-core/lib/logstash/config/mixin.rb b/logstash-core/lib/logstash/config/mixin.rb index fd2d71e85..a93cac08b 100644 --- a/logstash-core/lib/logstash/config/mixin.rb +++ b/logstash-core/lib/logstash/config/mixin.rb @@ -38,8 +38,7 @@ module LogStash::Config::Mixin PLUGIN_VERSION_1_0_0 = LogStash::Util::PluginVersion.new(1, 0, 0) PLUGIN_VERSION_0_9_0 = LogStash::Util::PluginVersion.new(0, 9, 0) - ENV_PLACEHOLDER_REGEX = Regexp.new(/\$\w+|\$\{\w+(\:[^}]*)?\}/) - + ENV_PLACEHOLDER_REGEX = /\$(?\w+)|\$\{(?\w+)(\:(?[^}]*))?\}/ # This method is called when someone does 'include LogStash::Config' def self.included(base) @@ -149,37 +148,24 @@ module LogStash::Config::Mixin # Replace all environment variable references in 'value' param by environment variable value and return updated value # Process following patterns : $VAR, ${VAR}, ${VAR:defaultValue} def replace_env_placeholders(value) - if (value.is_a?(String)) - while value =~ ENV_PLACEHOLDER_REGEX - valueParts = value.partition(ENV_PLACEHOLDER_REGEX) - placeHolder = valueParts[1] - if placeHolder.start_with?("${") - envVarName = placeHolder.slice(2..placeHolder.length - 2) - else - envVarName = placeHolder.slice(1..placeHolder.length - 1) - end - if envVarName.include?(':') - placeHolderParts = envVarName.split(':') - envVarName = placeHolderParts[0] - defaultValue = placeHolderParts[1] || "" - else - defaultValue = "" - end + return value unless value.is_a?(String) + #raise ArgumentError, "Cannot replace ENV placeholders on non-strings. Got #{value.class}" if !value.is_a?(String) - envVarValue = ENV[envVarName] - if envVarValue.nil? - envVarValue = defaultValue - if defaultValue.empty? - @logger.warn("In plugin '#{self.class.config_name}', " + - "referenced environment variable '#{envVarName}' does not exist. " + - "This reference has been replaced by empty string.") - end - end - value = valueParts[0] << envVarValue << valueParts[2] - @logger.info("Replacing config environment variable '#{placeHolder}' with #{envVarValue}") - end + value.gsub(ENV_PLACEHOLDER_REGEX) do |placeholder| + # Note: Ruby docs claim[1] Regexp.last_match is thread-local and scoped to + # the call, so this should be thread-safe. + # + # [1] http://ruby-doc.org/core-2.1.1/Regexp.html#method-c-last_match + name = Regexp.last_match(:name) + default = Regexp.last_match(:default) + + replacement = ENV.fetch(name, default) + #if replacement.nil? + #raise LogStash::ConfigurationError, "Cannot evaluate `#{placeholder}`. Environment variable `#{name}` is not set and there is no default value given." + #end + @logger.info? && @logger.info("Replacing config environment variable '#{placeholder}' with `#{replacement}`") + replacement end - return value end # def replace_env_placeholders module DSL