mirror of
https://github.com/elastic/logstash.git
synced 2025-06-28 01:37:28 -04:00
[Spacetime] Reimplement config Setting classe in java (#15679)
Reimplement the root Ruby Setting class in Java and use it from the Ruby one moving the original Ruby class to a shell wrapping the Java instance. In particular create a new symmetric hierarchy (at the time just for `Setting`, `Coercible` and `Boolean` classes) to the Ruby one, moving also the feature for setting deprecation. In this way the new `org.logstash.settings.Boolean` is syntactically and semantically equivalent to the old Ruby Boolean class, which replaces.
This commit is contained in:
parent
8368c00367
commit
61de60fe26
12 changed files with 797 additions and 76 deletions
|
@ -154,7 +154,7 @@ appender.deprecation_rolling.policies.size.size = 100MB
|
||||||
appender.deprecation_rolling.strategy.type = DefaultRolloverStrategy
|
appender.deprecation_rolling.strategy.type = DefaultRolloverStrategy
|
||||||
appender.deprecation_rolling.strategy.max = 30
|
appender.deprecation_rolling.strategy.max = 30
|
||||||
|
|
||||||
logger.deprecation.name = org.logstash.deprecation, deprecation
|
logger.deprecation.name = org.logstash.deprecation
|
||||||
logger.deprecation.level = WARN
|
logger.deprecation.level = WARN
|
||||||
logger.deprecation.appenderRef.deprecation_rolling.ref = deprecation_plain_rolling
|
logger.deprecation.appenderRef.deprecation_rolling.ref = deprecation_plain_rolling
|
||||||
logger.deprecation.additivity = false
|
logger.deprecation.additivity = false
|
||||||
|
|
|
@ -86,7 +86,10 @@ module LogStash
|
||||||
end
|
end
|
||||||
|
|
||||||
def register(setting)
|
def register(setting)
|
||||||
return setting.map { |s| register(s) } if setting.kind_of?(Array)
|
# Method #with_deprecated_alias returns collection containing couple of other settings.
|
||||||
|
# In case the method is implemented in Ruby returns an Array while for the Java implementation
|
||||||
|
# return a List, so the following type checking before going deep by one layer.
|
||||||
|
return setting.map { |s| register(s) } if setting.kind_of?(Array) || setting.kind_of?(java.util.List)
|
||||||
|
|
||||||
if @settings.key?(setting.name)
|
if @settings.key?(setting.name)
|
||||||
raise ArgumentError.new("Setting \"#{setting.name}\" has already been registered as #{setting.inspect}")
|
raise ArgumentError.new("Setting \"#{setting.name}\" has already been registered as #{setting.inspect}")
|
||||||
|
@ -244,54 +247,73 @@ module LogStash
|
||||||
class Setting
|
class Setting
|
||||||
include LogStash::Settings::LOGGABLE_PROXY
|
include LogStash::Settings::LOGGABLE_PROXY
|
||||||
|
|
||||||
attr_reader :name, :default
|
attr_reader :wrapped_setting
|
||||||
|
|
||||||
def initialize(name, klass, default = nil, strict = true, &validator_proc)
|
def initialize(name, klass, default = nil, strict = true, &validator_proc)
|
||||||
@name = name
|
|
||||||
unless klass.is_a?(Class)
|
unless klass.is_a?(Class)
|
||||||
raise ArgumentError.new("Setting \"#{@name}\" must be initialized with a class (received #{klass})")
|
raise ArgumentError.new("Setting \"#{name}\" must be initialized with a class (received #{klass})")
|
||||||
end
|
end
|
||||||
|
setting_builder = Java::org.logstash.settings.BaseSetting.create(name)
|
||||||
|
.defaultValue(default)
|
||||||
|
.strict(strict)
|
||||||
|
if validator_proc
|
||||||
|
setting_builder = setting_builder.validator(validator_proc)
|
||||||
|
end
|
||||||
|
|
||||||
|
@wrapped_setting = setting_builder.build()
|
||||||
|
|
||||||
@klass = klass
|
@klass = klass
|
||||||
@validator_proc = validator_proc
|
@validator_proc = validator_proc
|
||||||
@value = nil
|
|
||||||
@value_is_set = false
|
|
||||||
@strict = strict
|
|
||||||
|
|
||||||
validate(default) if @strict
|
validate(default) if strict?
|
||||||
@default = default
|
end
|
||||||
|
|
||||||
|
def default
|
||||||
|
@wrapped_setting.default
|
||||||
|
end
|
||||||
|
|
||||||
|
def name
|
||||||
|
@wrapped_setting.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_copy(original)
|
||||||
|
@wrapped_setting = original.wrapped_setting.clone
|
||||||
|
end
|
||||||
|
|
||||||
|
# To be used only internally
|
||||||
|
def update_wrapper(wrapped_setting)
|
||||||
|
@wrapped_setting = wrapped_setting
|
||||||
end
|
end
|
||||||
|
|
||||||
def value
|
def value
|
||||||
@value_is_set ? @value : default
|
@wrapped_setting.value()
|
||||||
end
|
end
|
||||||
|
|
||||||
def set?
|
def set?
|
||||||
@value_is_set
|
@wrapped_setting.set?
|
||||||
end
|
end
|
||||||
|
|
||||||
def strict?
|
def strict?
|
||||||
@strict
|
@wrapped_setting.strict?
|
||||||
end
|
end
|
||||||
|
|
||||||
def set(value)
|
def set(value)
|
||||||
validate(value) if @strict
|
validate(value) if strict?
|
||||||
@value = value
|
@wrapped_setting.set(value)
|
||||||
@value_is_set = true
|
@wrapped_setting.value
|
||||||
@value
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset
|
def reset
|
||||||
@value = nil
|
@wrapped_setting.reset
|
||||||
@value_is_set = false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_hash
|
def to_hash
|
||||||
{
|
{
|
||||||
"name" => @name,
|
"name" => @wrapped_setting.name,
|
||||||
"klass" => @klass,
|
"klass" => @klass,
|
||||||
"value" => @value,
|
"value" => @wrapped_setting.value,
|
||||||
"value_is_set" => @value_is_set,
|
"value_is_set" => @wrapped_setting.set?,
|
||||||
"default" => @default,
|
"default" => @wrapped_setting.default,
|
||||||
# Proc#== will only return true if it's the same obj
|
# Proc#== will only return true if it's the same obj
|
||||||
# so no there's no point in comparing it
|
# so no there's no point in comparing it
|
||||||
# also thereś no use case atm to return the proc
|
# also thereś no use case atm to return the proc
|
||||||
|
@ -301,7 +323,7 @@ module LogStash
|
||||||
end
|
end
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
"<#{self.class.name}(#{name}): #{value.inspect}" + (@value_is_set ? '' : ' (DEFAULT)') + ">"
|
"<#{self.class.name}(#{name}): #{value.inspect}" + (@wrapped_setting.set? ? '' : ' (DEFAULT)') + ">"
|
||||||
end
|
end
|
||||||
|
|
||||||
def ==(other)
|
def ==(other)
|
||||||
|
@ -323,58 +345,65 @@ module LogStash
|
||||||
end
|
end
|
||||||
|
|
||||||
def format(output)
|
def format(output)
|
||||||
effective_value = self.value
|
@wrapped_setting.format(output)
|
||||||
default_value = self.default
|
|
||||||
setting_name = self.name
|
|
||||||
|
|
||||||
if default_value == value # print setting and its default value
|
|
||||||
output << "#{setting_name}: #{effective_value.inspect}" unless effective_value.nil?
|
|
||||||
elsif default_value.nil? # print setting and warn it has been set
|
|
||||||
output << "*#{setting_name}: #{effective_value.inspect}"
|
|
||||||
elsif effective_value.nil? # default setting not set by user
|
|
||||||
output << "#{setting_name}: #{default_value.inspect}"
|
|
||||||
else # print setting, warn it has been set, and show default value
|
|
||||||
output << "*#{setting_name}: #{effective_value.inspect} (default: #{default_value.inspect})"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def clone(*args)
|
||||||
|
copy = self.dup
|
||||||
|
copy.update_wrapper(@wrapped_setting.clone())
|
||||||
|
copy
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def validate(input)
|
def validate(input)
|
||||||
if !input.is_a?(@klass)
|
if !input.is_a?(@klass)
|
||||||
raise ArgumentError.new("Setting \"#{@name}\" must be a #{@klass}. Received: #{input} (#{input.class})")
|
raise ArgumentError.new("Setting \"#{@wrapped_setting.name}\" must be a #{@klass}. Received: #{input} (#{input.class})")
|
||||||
end
|
end
|
||||||
|
|
||||||
if @validator_proc && !@validator_proc.call(input)
|
if @validator_proc && !@validator_proc.call(input)
|
||||||
raise ArgumentError.new("Failed to validate setting \"#{@name}\" with value: #{input}")
|
raise ArgumentError.new("Failed to validate setting \"#{@wrapped_setting.name}\" with value: #{input}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Coercible < Setting
|
class Coercible < Setting
|
||||||
def initialize(name, klass, default = nil, strict = true, &validator_proc)
|
def initialize(name, klass, default = nil, strict = true, &validator_proc)
|
||||||
@name = name
|
|
||||||
unless klass.is_a?(Class)
|
unless klass.is_a?(Class)
|
||||||
raise ArgumentError.new("Setting \"#{@name}\" must be initialized with a class (received #{klass})")
|
raise ArgumentError.new("Setting \"#{name}\" must be initialized with a class (received #{klass})")
|
||||||
end
|
end
|
||||||
|
|
||||||
@klass = klass
|
@klass = klass
|
||||||
@validator_proc = validator_proc
|
@validator_proc = validator_proc
|
||||||
@value = nil
|
|
||||||
@value_is_set = false
|
# needed to have the name method accessible when invoking validate
|
||||||
|
@wrapped_setting = Java::org.logstash.settings.BaseSetting.create(name)
|
||||||
|
.defaultValue(default)
|
||||||
|
.strict(strict)
|
||||||
|
.build()
|
||||||
|
|
||||||
if strict
|
if strict
|
||||||
coerced_default = coerce(default)
|
coerced_default = coerce(default)
|
||||||
validate(coerced_default)
|
validate(coerced_default)
|
||||||
@default = coerced_default
|
updated_default = coerced_default
|
||||||
else
|
else
|
||||||
@default = default
|
updated_default = default
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# default value must be coerced to the right type before being set
|
||||||
|
setting_builder = Java::org.logstash.settings.BaseSetting.create(name)
|
||||||
|
.defaultValue(updated_default)
|
||||||
|
.strict(strict)
|
||||||
|
if validator_proc
|
||||||
|
setting_builder = setting_builder.validator(validator_proc)
|
||||||
|
end
|
||||||
|
|
||||||
|
@wrapped_setting = setting_builder.build()
|
||||||
end
|
end
|
||||||
|
|
||||||
def set(value)
|
def set(value)
|
||||||
coerced_value = coerce(value)
|
coerced_value = coerce(value)
|
||||||
validate(coerced_value)
|
validate(coerced_value)
|
||||||
@value = coerce(coerced_value)
|
@wrapped_setting.set(coerced_value)
|
||||||
@value_is_set = true
|
coerced_value
|
||||||
@value
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def coerce(value)
|
def coerce(value)
|
||||||
|
@ -383,22 +412,7 @@ module LogStash
|
||||||
end
|
end
|
||||||
### Specific settings #####
|
### Specific settings #####
|
||||||
|
|
||||||
class Boolean < Coercible
|
java_import org.logstash.settings.Boolean
|
||||||
def initialize(name, default, strict = true, &validator_proc)
|
|
||||||
super(name, Object, default, strict, &validator_proc)
|
|
||||||
end
|
|
||||||
|
|
||||||
def coerce(value)
|
|
||||||
case value
|
|
||||||
when TrueClass, "true"
|
|
||||||
true
|
|
||||||
when FalseClass, "false"
|
|
||||||
false
|
|
||||||
else
|
|
||||||
raise ArgumentError.new("could not coerce #{value} into a boolean")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Numeric < Coercible
|
class Numeric < Coercible
|
||||||
def initialize(name, default = nil, strict = true)
|
def initialize(name, default = nil, strict = true)
|
||||||
|
@ -733,15 +747,15 @@ module LogStash
|
||||||
protected
|
protected
|
||||||
def validate(input)
|
def validate(input)
|
||||||
if !input.is_a?(@klass)
|
if !input.is_a?(@klass)
|
||||||
raise ArgumentError.new("Setting \"#{@name}\" must be a #{@klass}. Received: #{input} (#{input.class})")
|
raise ArgumentError.new("Setting \"#{@wrapped_setting.name}\" must be a #{@klass}. Received: #{input} (#{input.class})")
|
||||||
end
|
end
|
||||||
|
|
||||||
unless input.all? {|el| el.kind_of?(@element_class) }
|
unless input.all? {|el| el.kind_of?(@element_class) }
|
||||||
raise ArgumentError.new("Values of setting \"#{@name}\" must be #{@element_class}. Received: #{input.map(&:class)}")
|
raise ArgumentError.new("Values of setting \"#{@wrapped_setting.name}\" must be #{@element_class}. Received: #{input.map(&:class)}")
|
||||||
end
|
end
|
||||||
|
|
||||||
if @validator_proc && !@validator_proc.call(input)
|
if @validator_proc && !@validator_proc.call(input)
|
||||||
raise ArgumentError.new("Failed to validate setting \"#{@name}\" with value: #{input}")
|
raise ArgumentError.new("Failed to validate setting \"#{@wrapped_setting.name}\" with value: #{input}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -782,7 +796,7 @@ module LogStash
|
||||||
return unless invalid_value.any?
|
return unless invalid_value.any?
|
||||||
|
|
||||||
raise ArgumentError,
|
raise ArgumentError,
|
||||||
"Failed to validate the setting \"#{@name}\" value(s): #{invalid_value.inspect}. Valid options are: #{@possible_strings.inspect}"
|
"Failed to validate the setting \"#{@wrapped_setting.name}\" value(s): #{invalid_value.inspect}. Valid options are: #{@possible_strings.inspect}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -792,9 +806,9 @@ module LogStash
|
||||||
end
|
end
|
||||||
|
|
||||||
def set(value)
|
def set(value)
|
||||||
@value = coerce(value)
|
coerced_value = coerce(value)
|
||||||
@value_is_set = true
|
@wrapped_setting.set(coerced_value)
|
||||||
@value
|
coerced_value
|
||||||
end
|
end
|
||||||
|
|
||||||
def coerce(value)
|
def coerce(value)
|
||||||
|
@ -839,8 +853,7 @@ module LogStash
|
||||||
@canonical_proxy = canonical_proxy
|
@canonical_proxy = canonical_proxy
|
||||||
|
|
||||||
clone = @canonical_proxy.canonical_setting.clone
|
clone = @canonical_proxy.canonical_setting.clone
|
||||||
clone.instance_variable_set(:@name, alias_name)
|
clone.update_wrapper(clone.wrapped_setting.deprecate(alias_name))
|
||||||
clone.instance_variable_set(:@default, nil)
|
|
||||||
|
|
||||||
super(clone)
|
super(clone)
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.logstash.settings;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Root class for all setting definitions.
|
||||||
|
* */
|
||||||
|
public class BaseSetting<T> implements Setting<T> {
|
||||||
|
|
||||||
|
private String name; // not final because can be updated by deprecate
|
||||||
|
T defaultValue;
|
||||||
|
private T value = null;
|
||||||
|
private final boolean strict;
|
||||||
|
private final Predicate<T> validator;
|
||||||
|
private boolean valueIsSet = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public BaseSetting<T> clone() {
|
||||||
|
try {
|
||||||
|
BaseSetting<T> clone = (BaseSetting<T>) super.clone();
|
||||||
|
// copy mutable state here, so the clone can't change the internals of the original
|
||||||
|
clone.value = value;
|
||||||
|
clone.valueIsSet = valueIsSet;
|
||||||
|
return clone;
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Builder<T> {
|
||||||
|
private final String name;
|
||||||
|
private boolean strict = true;
|
||||||
|
private T defaultValue = null;
|
||||||
|
private Predicate<T> validator = noValidator();
|
||||||
|
|
||||||
|
public Builder(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> defaultValue(T defaultValue) {
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> strict(boolean strict) {
|
||||||
|
this.strict = strict;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> validator(Predicate<T> validator) {
|
||||||
|
this.validator = validator;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseSetting<T> build() {
|
||||||
|
return new BaseSetting<>(name, defaultValue, strict, validator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Builder<T> create(String name) {
|
||||||
|
return new Builder<>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifically used by Coercible subclass to initialize doing validation in a second phase.
|
||||||
|
* */
|
||||||
|
protected BaseSetting(String name, boolean strict, Predicate<T> validator) {
|
||||||
|
Objects.requireNonNull(name);
|
||||||
|
Objects.requireNonNull(validator);
|
||||||
|
this.name = name;
|
||||||
|
this.strict = strict;
|
||||||
|
this.validator = validator;
|
||||||
|
}
|
||||||
|
protected BaseSetting(String name, T defaultValue, boolean strict, Predicate<T> validator) {
|
||||||
|
Objects.requireNonNull(name);
|
||||||
|
Objects.requireNonNull(validator);
|
||||||
|
this.name = name;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
this.strict = strict;
|
||||||
|
this.validator = validator;
|
||||||
|
if (strict) {
|
||||||
|
validate(defaultValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a copy of the setting with the original name to deprecate
|
||||||
|
* */
|
||||||
|
protected BaseSetting<T> deprecate(String deprecatedName) {
|
||||||
|
// this force to get a copy of the original Setting, in case of a BooleanSetting it retains also all of its
|
||||||
|
// coercing mechanisms
|
||||||
|
BaseSetting<T> clone = this.clone();
|
||||||
|
clone.updateName(deprecatedName);
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateName(String deprecatedName) {
|
||||||
|
this.name = deprecatedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static <T> Predicate<T> noValidator() {
|
||||||
|
return t -> true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(T input) throws IllegalArgumentException {
|
||||||
|
if (!validator.test(input)) {
|
||||||
|
throw new IllegalArgumentException("Failed to validate setting " + this.name + " with value: " + input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T value() {
|
||||||
|
if (valueIsSet) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSet() {
|
||||||
|
return this.valueIsSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStrict() {
|
||||||
|
return strict;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSafely(T newValue) {
|
||||||
|
if (strict) {
|
||||||
|
validate(newValue);
|
||||||
|
}
|
||||||
|
this.value = newValue;
|
||||||
|
this.valueIsSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
this.value = null;
|
||||||
|
this.valueIsSet = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateValue() {
|
||||||
|
validate(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getDefault() {
|
||||||
|
return this.defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void format(List<String> output) {
|
||||||
|
T effectiveValue = this.value;
|
||||||
|
String settingName = this.name;
|
||||||
|
|
||||||
|
if (effectiveValue != null && effectiveValue.equals(defaultValue)) {
|
||||||
|
// print setting and its default value
|
||||||
|
output.add(String.format("%s: %s", settingName, effectiveValue));
|
||||||
|
} else if (defaultValue == null) {
|
||||||
|
// print setting and warn it has been set
|
||||||
|
output.add(String.format("*%s: %s", settingName, effectiveValue));
|
||||||
|
} else if (effectiveValue == null) {
|
||||||
|
// default setting not set by user
|
||||||
|
output.add(String.format("%s: %s", settingName, defaultValue));
|
||||||
|
} else {
|
||||||
|
// print setting, warn it has been set, and show default value
|
||||||
|
output.add(String.format("*%s: %s (default: %s)", settingName, effectiveValue, defaultValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Setting<T>> withDeprecatedAlias(String deprecatedAlias) {
|
||||||
|
return SettingWithDeprecatedAlias.wrap(this, deprecatedAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Setting<T> nullable() {
|
||||||
|
return new NullableSetting<>(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.logstash.settings;
|
||||||
|
|
||||||
|
public class Boolean extends Coercible<java.lang.Boolean> {
|
||||||
|
|
||||||
|
public Boolean(String name, boolean defaultValue) {
|
||||||
|
super(name, defaultValue, true, noValidator());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean(String name, boolean defaultValue, boolean strict) {
|
||||||
|
super(name, defaultValue, strict, noValidator());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.lang.Boolean coerce(Object obj) {
|
||||||
|
if (obj instanceof String) {
|
||||||
|
switch((String) obj) {
|
||||||
|
case "true": return true;
|
||||||
|
case "false": return false;
|
||||||
|
default: throw new IllegalArgumentException(coercionFailureMessage(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (obj instanceof java.lang.Boolean) {
|
||||||
|
return (java.lang.Boolean) obj;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(coercionFailureMessage(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String coercionFailureMessage(Object obj) {
|
||||||
|
return String.format("Cannot coerce `%s` to boolean (%s)", obj, getName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.logstash.settings;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public abstract class Coercible<T> extends BaseSetting<T> {
|
||||||
|
public Coercible(String name, T defaultValue, boolean strict, Predicate<T> validator) {
|
||||||
|
super(name, strict, validator);
|
||||||
|
|
||||||
|
if (strict) {
|
||||||
|
T coercedDefault = coerce(defaultValue);
|
||||||
|
validate(coercedDefault);
|
||||||
|
this.defaultValue = coercedDefault;
|
||||||
|
} else {
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(Object value) {
|
||||||
|
T coercedValue = coerce(value);
|
||||||
|
validate(coercedValue);
|
||||||
|
super.setSafely(coercedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSafely(T value) {
|
||||||
|
this.set(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract T coerce(Object obj);
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.logstash.settings;
|
||||||
|
|
||||||
|
import co.elastic.logstash.api.DeprecationLogger;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.logstash.log.DefaultDeprecationLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A <code>DeprecatedAlias</code> provides a deprecated alias for a setting, and is meant
|
||||||
|
* to be used exclusively through @see org.logstash.settings.SettingWithDeprecatedAlias#wrap()
|
||||||
|
* */
|
||||||
|
public final class DeprecatedAlias<T> extends SettingDelegator<T> {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
|
private static final DeprecationLogger DEPRECATION_LOGGER = new DefaultDeprecationLogger(LOGGER);
|
||||||
|
|
||||||
|
private SettingWithDeprecatedAlias<T> canonicalProxy;
|
||||||
|
|
||||||
|
DeprecatedAlias(SettingWithDeprecatedAlias<T> canonicalProxy, String aliasName) {
|
||||||
|
super(canonicalProxy.getCanonicalSetting().deprecate(aliasName));
|
||||||
|
this.canonicalProxy = canonicalProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Because loggers are configure after the Settings declaration, this method is intended for lazy-logging
|
||||||
|
// check https://github.com/elastic/logstash/pull/16339
|
||||||
|
public void observePostProcess() {
|
||||||
|
if (isSet()) {
|
||||||
|
DEPRECATION_LOGGER.deprecated("The setting `{}` is a deprecated alias for `{}` and will be removed in a " +
|
||||||
|
"future release of Logstash. Please use `{}` instead", getName(), canonicalProxy.getName(), canonicalProxy.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T value() {
|
||||||
|
LOGGER.warn("The value of setting `{}` has been queried by its deprecated alias `{}`. " +
|
||||||
|
"Code should be updated to query `{}` instead", canonicalProxy.getName(), getName(), canonicalProxy.getName());
|
||||||
|
return super.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateValue() {
|
||||||
|
// bypass deprecation warning
|
||||||
|
if (isSet()) {
|
||||||
|
getDelegate().validateValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.logstash.settings;
|
||||||
|
|
||||||
|
public class NullableSetting<T> extends SettingDelegator<T> {
|
||||||
|
|
||||||
|
NullableSetting(BaseSetting<T> delegate) {
|
||||||
|
super(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate(T input) throws IllegalArgumentException {
|
||||||
|
if (input == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getDelegate().validate(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent delegate from intercepting
|
||||||
|
@Override
|
||||||
|
public void validateValue() {
|
||||||
|
validate(value());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.logstash.settings;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface Setting<T> extends Cloneable {
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
T value();
|
||||||
|
|
||||||
|
boolean isSet();
|
||||||
|
|
||||||
|
boolean isStrict();
|
||||||
|
|
||||||
|
void setSafely(T newValue);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
default void set(Object newValue) {
|
||||||
|
//this could throw a class cast error
|
||||||
|
setSafely((T) newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void validateValue();
|
||||||
|
|
||||||
|
void validate(T input);
|
||||||
|
|
||||||
|
T getDefault();
|
||||||
|
|
||||||
|
void format(List<String> output);
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.logstash.settings;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
abstract class SettingDelegator<T> implements Setting<T> {
|
||||||
|
private BaseSetting<T> delegate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this constructor to wrap another setting.
|
||||||
|
* */
|
||||||
|
SettingDelegator(BaseSetting<T> delegate) {
|
||||||
|
Objects.requireNonNull(delegate);
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseSetting<T> getDelegate() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return delegate.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T value() {
|
||||||
|
return delegate.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSet() {
|
||||||
|
return delegate.isSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStrict() {
|
||||||
|
return delegate.isStrict();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSafely(T newValue) {
|
||||||
|
delegate.setSafely(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
delegate.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateValue() {
|
||||||
|
delegate.validateValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T getDefault() {
|
||||||
|
return delegate.getDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void format(List<String> output) {
|
||||||
|
delegate.format(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate(T input) {
|
||||||
|
delegate.validate(input);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.logstash.settings;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A <code>SettingWithDeprecatedAlias</code> wraps any <code>Setting</code> to provide a deprecated
|
||||||
|
* alias, and hooks @see org.logstash.settings.Setting#validate_value() to ensure that a deprecation
|
||||||
|
* warning is fired when the setting is provided by its deprecated alias,
|
||||||
|
* or to produce an error when both the canonical name and deprecated
|
||||||
|
* alias are used together.
|
||||||
|
* */
|
||||||
|
// This class is public else the getDeprecatedAlias method can't be seen from setting_with_deprecated_alias_spec.rb
|
||||||
|
public class SettingWithDeprecatedAlias<T> extends SettingDelegator<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the provided setting, returning a pair of connected settings
|
||||||
|
* including the canonical setting and a deprecated alias.
|
||||||
|
* @param canonicalSetting the setting to wrap
|
||||||
|
* @param deprecatedAliasName the name for the deprecated alias
|
||||||
|
*
|
||||||
|
* @return List of [SettingWithDeprecatedAlias, DeprecatedAlias]
|
||||||
|
* */
|
||||||
|
static <T> List<Setting<T>> wrap(BaseSetting<T> canonicalSetting, String deprecatedAliasName) {
|
||||||
|
final SettingWithDeprecatedAlias<T> settingProxy = new SettingWithDeprecatedAlias<>(canonicalSetting, deprecatedAliasName);
|
||||||
|
return Arrays.asList(settingProxy, settingProxy.deprecatedAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeprecatedAlias<T> deprecatedAlias;
|
||||||
|
|
||||||
|
protected SettingWithDeprecatedAlias(BaseSetting<T> canonicalSetting, String deprecatedAliasName) {
|
||||||
|
super(canonicalSetting);
|
||||||
|
|
||||||
|
this.deprecatedAlias = new DeprecatedAlias<T>(this, deprecatedAliasName);
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseSetting<T> getCanonicalSetting() {
|
||||||
|
return getDelegate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeprecatedAlias<T> getDeprecatedAlias() {
|
||||||
|
return deprecatedAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSafely(T value) {
|
||||||
|
getCanonicalSetting().setSafely(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T value() {
|
||||||
|
if (getCanonicalSetting().isSet()) {
|
||||||
|
return super.value();
|
||||||
|
}
|
||||||
|
// bypass warning by querying the wrapped setting's value
|
||||||
|
if (deprecatedAlias.isSet()) {
|
||||||
|
return deprecatedAlias.getDelegate().value();
|
||||||
|
}
|
||||||
|
return getDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSet() {
|
||||||
|
return getCanonicalSetting().isSet() || deprecatedAlias.isSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void format(List<String> output) {
|
||||||
|
if (!(deprecatedAlias.isSet() && !getCanonicalSetting().isSet())) {
|
||||||
|
super.format(output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
output.add(String.format("*%s: %s (via deprecated `%s`; default: %s)",
|
||||||
|
getName(), value(), deprecatedAlias.getName(), getDefault()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateValue() {
|
||||||
|
if (deprecatedAlias.isSet() && getCanonicalSetting().isSet()) {
|
||||||
|
throw new IllegalStateException(String.format("Both `%s` and its deprecated alias `%s` have been set.\n" +
|
||||||
|
"Please only set `%s`", getCanonicalSetting().getName(), deprecatedAlias.getName(), getCanonicalSetting().getName()));
|
||||||
|
}
|
||||||
|
super.validateValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package org.logstash.settings;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
public class BooleanTest {
|
||||||
|
|
||||||
|
|
||||||
|
private Boolean sut;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
sut = new Boolean("api.enabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLiteralBooleanStringValueWhenCoercedToBooleanValueThenIsValidBooleanSetting() {
|
||||||
|
sut.set("false");
|
||||||
|
|
||||||
|
Assert.assertFalse(sut.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenBooleanInstanceWhenCoercedThenReturnValidBooleanSetting() {
|
||||||
|
sut.set(java.lang.Boolean.FALSE);
|
||||||
|
|
||||||
|
Assert.assertFalse(sut.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInvalidStringLiteralForBooleanValueWhenCoercedThenThrowsAnError() {
|
||||||
|
IllegalArgumentException exception = Assert.assertThrows(IllegalArgumentException.class, () -> sut.set("bananas"));
|
||||||
|
assertThat(exception.getMessage(), equalTo("Cannot coerce `bananas` to boolean (api.enabled)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInvalidTypeInstanceForBooleanValueWhenCoercedThenThrowsAnError() {
|
||||||
|
IllegalArgumentException exception = Assert.assertThrows(IllegalArgumentException.class, () -> sut.set(1));
|
||||||
|
assertThat(exception.getMessage(), equalTo("Cannot coerce `1` to boolean (api.enabled)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -389,14 +389,14 @@ describe "Test Monitoring API" do
|
||||||
end
|
end
|
||||||
|
|
||||||
#default
|
#default
|
||||||
logging_get_assert logstash_service, "INFO", "TRACE",
|
logging_get_assert logstash_service, ["WARN", "INFO"], "TRACE",
|
||||||
skip: 'logstash.licensechecker.licensereader' #custom (ERROR) level to start with
|
skip: 'logstash.licensechecker.licensereader' #custom (ERROR) level to start with
|
||||||
|
|
||||||
#root logger - does not apply to logger.slowlog
|
#root logger - does not apply to logger.slowlog
|
||||||
logging_put_assert logstash_service.monitoring_api.logging_put({"logger." => "WARN"})
|
logging_put_assert logstash_service.monitoring_api.logging_put({"logger." => "WARN"})
|
||||||
logging_get_assert logstash_service, "WARN", "TRACE"
|
logging_get_assert logstash_service, "WARN", "TRACE"
|
||||||
logging_put_assert logstash_service.monitoring_api.logging_put({"logger." => "INFO"})
|
logging_put_assert logstash_service.monitoring_api.logging_put({"logger." => "INFO"})
|
||||||
logging_get_assert logstash_service, "INFO", "TRACE"
|
logging_get_assert logstash_service, ["WARN", "INFO"], "TRACE"
|
||||||
|
|
||||||
#package logger
|
#package logger
|
||||||
logging_put_assert logstash_service.monitoring_api.logging_put({"logger.logstash.agent" => "DEBUG"})
|
logging_put_assert logstash_service.monitoring_api.logging_put({"logger.logstash.agent" => "DEBUG"})
|
||||||
|
@ -422,7 +422,7 @@ describe "Test Monitoring API" do
|
||||||
|
|
||||||
# all log levels should be reset to original values
|
# all log levels should be reset to original values
|
||||||
logging_put_assert logstash_service.monitoring_api.logging_reset
|
logging_put_assert logstash_service.monitoring_api.logging_reset
|
||||||
logging_get_assert logstash_service, "INFO", "TRACE"
|
logging_get_assert logstash_service, ["WARN", "INFO"], "TRACE"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -433,7 +433,15 @@ describe "Test Monitoring API" do
|
||||||
result["loggers"].each do |k, v|
|
result["loggers"].each do |k, v|
|
||||||
next if !k.empty? && k.eql?(skip)
|
next if !k.empty? && k.eql?(skip)
|
||||||
if k.start_with? "logstash", "org.logstash" #logstash is the ruby namespace, and org.logstash for java
|
if k.start_with? "logstash", "org.logstash" #logstash is the ruby namespace, and org.logstash for java
|
||||||
|
if logstash_level.is_a?(Array)
|
||||||
|
if logstash_level.size == 1
|
||||||
|
expect(v).to eq(logstash_level[0]), "logstash logger '#{k}' has logging level: #{v} expected: #{logstash_level[0]}"
|
||||||
|
else
|
||||||
|
expect(logstash_level).to include(v), "logstash logger '#{k}' has logging level: #{v} expected to be one of: #{logstash_level}"
|
||||||
|
end
|
||||||
|
else
|
||||||
expect(v).to eq(logstash_level), "logstash logger '#{k}' has logging level: #{v} expected: #{logstash_level}"
|
expect(v).to eq(logstash_level), "logstash logger '#{k}' has logging level: #{v} expected: #{logstash_level}"
|
||||||
|
end
|
||||||
elsif k.start_with? "slowlog"
|
elsif k.start_with? "slowlog"
|
||||||
expect(v).to eq(slowlog_level), "slowlog logger '#{k}' has logging level: #{v} expected: #{slowlog_level}"
|
expect(v).to eq(slowlog_level), "slowlog logger '#{k}' has logging level: #{v} expected: #{slowlog_level}"
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue