ensure jackson overrides are available to static initializers (#16719) (#16756)

Moves the application of jackson defaults overrides into pure java, and
applies them statically _before_ the `org.logstash.ObjectMappers` has a chance
to start initializing object mappers that rely on the defaults.

We replace the runner's invocation (which was too late to be fully applied) with
a _verification_ that the configured defaults have been applied.

(cherry picked from commit 202d07cbbf)

Co-authored-by: Ry Biesemeyer <yaauie@users.noreply.github.com>
This commit is contained in:
github-actions[bot] 2024-12-06 11:09:19 -05:00 committed by GitHub
parent 1d82e377ff
commit 5b3e62e52d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 389 additions and 186 deletions

View file

@ -353,8 +353,8 @@ class LogStash::Runner < Clamp::StrictCommand
# Add local modules to the registry before everything else
LogStash::Modules::Util.register_local_modules(LogStash::Environment::LOGSTASH_HOME)
# Set up the Jackson defaults
LogStash::Util::Jackson.set_jackson_defaults(logger)
# Verify the Jackson defaults
LogStash::Util::Jackson.verify_jackson_overrides
@dispatcher = LogStash::EventDispatcher.new(self)
LogStash::PLUGIN_REGISTRY.hooks.register_emitter(self.class, @dispatcher)

View file

@ -18,76 +18,13 @@
module LogStash
module Util
module Jackson
def self.set_jackson_defaults(logger)
JacksonStreamReadConstraintsDefaults.new(logger).configure
def self.verify_jackson_overrides
java_import org.logstash.ObjectMappers
ObjectMappers::getConfiguredStreamReadConstraints().validateIsGlobalDefault()
end
class JacksonStreamReadConstraintsDefaults
java_import com.fasterxml.jackson.core.StreamReadConstraints
PROPERTY_MAX_STRING_LENGTH = 'logstash.jackson.stream-read-constraints.max-string-length'.freeze
PROPERTY_MAX_NUMBER_LENGTH = 'logstash.jackson.stream-read-constraints.max-number-length'.freeze
PROPERTY_MAX_NESTING_DEPTH = 'logstash.jackson.stream-read-constraints.max-nesting-depth'.freeze
def initialize(logger)
@logger = logger
end
public
def configure
max_string_len = get_default_value_override!(PROPERTY_MAX_STRING_LENGTH)
max_num_len = get_default_value_override!(PROPERTY_MAX_NUMBER_LENGTH)
max_nesting_depth = get_default_value_override!(PROPERTY_MAX_NESTING_DEPTH)
if max_string_len || max_num_len || max_nesting_depth
begin
override_default_stream_read_constraints(max_string_len, max_num_len, max_nesting_depth)
rescue java.lang.IllegalArgumentException => e
raise LogStash::ConfigurationError, "Invalid `logstash.jackson.*` system properties configuration: #{e.message}"
end
end
end
private
def get_default_value_override!(property)
value = get_property_value(property)
return if value.nil?
begin
int_value = java.lang.Integer.parseInt(value)
if int_value < 1
raise LogStash::ConfigurationError, "System property '#{property}' must be bigger than zero. Received: #{int_value}"
end
@logger.info("Jackson default value override `#{property}` configured to `#{int_value}`")
int_value
rescue java.lang.NumberFormatException => _e
raise LogStash::ConfigurationError, "System property '#{property}' must be a positive integer value. Received: #{value}"
end
end
def get_property_value(name)
java.lang.System.getProperty(name)
end
def override_default_stream_read_constraints(max_string_len, max_num_len, max_nesting_depth)
builder = new_stream_read_constraints_builder
builder.maxStringLength(max_string_len) if max_string_len
builder.maxNumberLength(max_num_len) if max_num_len
builder.maxNestingDepth(max_nesting_depth) if max_nesting_depth
StreamReadConstraints.overrideDefaultStreamReadConstraints(builder.build)
end
def new_stream_read_constraints_builder
StreamReadConstraints::builder
end
end
end
end
end

View file

@ -571,8 +571,8 @@ describe LogStash::Runner do
subject { LogStash::Runner.new("") }
let(:args) { ["-e", "input {} output {}"] }
it 'should be set' do
expect(LogStash::Util::Jackson).to receive(:set_jackson_defaults)
it 'should be verified' do
expect(LogStash::Util::Jackson).to receive(:verify_jackson_overrides)
subject.run(args)
end
end

View file

@ -1,113 +0,0 @@
# 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.
require 'spec_helper'
describe LogStash::Util::Jackson do
it 'configures the read constraints defaults' do
read_constraints_defaults = double('read_constraints_defaults')
expect(read_constraints_defaults).to receive(:configure)
expect(LogStash::Util::Jackson::JacksonStreamReadConstraintsDefaults).to receive(:new).and_return(read_constraints_defaults)
LogStash::Util::Jackson.set_jackson_defaults(double('logger').as_null_object)
end
end
describe LogStash::Util::Jackson::JacksonStreamReadConstraintsDefaults do
let(:logger) { double('logger') }
subject { described_class.new(logger) }
shared_examples 'stream read constraint property' do |property|
let(:property) { property }
let(:value) { nil }
let(:builder) { double('builder') }
let(:builder_set_value_method) { expected_builder_set_value_method(property) }
before(:each) do
allow(logger).to receive(:info)
allow(builder).to receive(:build).and_return(com.fasterxml.jackson.core.StreamReadConstraints::builder.build)
allow(builder).to receive(builder_set_value_method).with(value.to_i)
allow(subject).to receive(:new_stream_read_constraints_builder).and_return(builder)
allow(subject).to receive(:get_property_value) do |name|
if name == property
value.to_s
else
nil
end
end
end
context 'with valid number' do
let(:value) { '10' }
it 'does not raises an error and set value' do
expect { subject.configure }.to_not raise_error
expect(builder).to have_received(builder_set_value_method).with(value.to_i)
end
end
context 'with non-number value' do
let(:value) { 'foo' }
it 'raises an error and does not set value' do
expect { subject.configure }.to raise_error(LogStash::ConfigurationError, /System property '#{property}' must be a positive integer value. Received: #{value}/)
expect(builder).to_not have_received(builder_set_value_method)
end
end
context 'with zeroed value' do
let(:value) { '0' }
it 'raises an error and does not set value' do
expect { subject.configure }.to raise_error(LogStash::ConfigurationError, /System property '#{property}' must be bigger than zero. Received: #{value}/)
expect(builder).to_not have_received(builder_set_value_method)
end
end
context 'with zeroed value' do
let(:value) { '-1' }
it 'raises an error and does not set value' do
expect { subject.configure }.to raise_error(LogStash::ConfigurationError, /System property '#{property}' must be bigger than zero. Received: #{value}/)
expect(builder).to_not have_received(builder_set_value_method)
end
end
def expected_builder_set_value_method(property)
case property
when LogStash::Util::Jackson::JacksonStreamReadConstraintsDefaults::PROPERTY_MAX_STRING_LENGTH
return :maxStringLength
when LogStash::Util::Jackson::JacksonStreamReadConstraintsDefaults::PROPERTY_MAX_NUMBER_LENGTH
return :maxNumberLength
when LogStash::Util::Jackson::JacksonStreamReadConstraintsDefaults::PROPERTY_MAX_NESTING_DEPTH
return :maxNestingDepth
else
raise 'Invalid system property value'
end
end
end
[
LogStash::Util::Jackson::JacksonStreamReadConstraintsDefaults::PROPERTY_MAX_STRING_LENGTH,
LogStash::Util::Jackson::JacksonStreamReadConstraintsDefaults::PROPERTY_MAX_NUMBER_LENGTH,
LogStash::Util::Jackson::JacksonStreamReadConstraintsDefaults::PROPERTY_MAX_NESTING_DEPTH,
].each { |system_property|
context "#{system_property}" do
it_behaves_like "stream read constraint property", system_property
end
}
end

View file

@ -42,6 +42,7 @@ import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import org.apache.logging.log4j.core.jackson.Log4jJsonObjectMapper;
import org.jruby.RubyBignum;
import org.jruby.RubyBoolean;
@ -52,12 +53,27 @@ import org.jruby.RubyString;
import org.jruby.RubySymbol;
import org.jruby.ext.bigdecimal.RubyBigDecimal;
import org.logstash.ext.JrubyTimestampExtLibrary;
import org.logstash.jackson.StreamReadConstraintsUtil;
import org.logstash.log.RubyBasicObjectSerializer;
public final class ObjectMappers {
static final String RUBY_SERIALIZERS_MODULE_ID = "RubySerializers";
static final StreamReadConstraintsUtil CONFIGURED_STREAM_READ_CONSTRAINTS;
static {
// The StreamReadConstraintsUtil needs to load the configured constraints from system
// properties and apply them _statically_, before any object mappers are initialized.
CONFIGURED_STREAM_READ_CONSTRAINTS = StreamReadConstraintsUtil.fromSystemProperties();
CONFIGURED_STREAM_READ_CONSTRAINTS.applyAsGlobalDefault();
}
public static StreamReadConstraintsUtil getConfiguredStreamReadConstraints() {
return CONFIGURED_STREAM_READ_CONSTRAINTS;
}
private static final SimpleModule RUBY_SERIALIZERS =
new SimpleModule(RUBY_SERIALIZERS_MODULE_ID)
.addSerializer(RubyString.class, new RubyStringSerializer())

View file

@ -0,0 +1,134 @@
package org.logstash.jackson;
import com.fasterxml.jackson.core.StreamReadConstraints;
import com.google.common.collect.Sets;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
public class StreamReadConstraintsUtil {
private final Map<String,String> propertyOverrides;
private final Logger logger;
private StreamReadConstraints configuredStreamReadConstraints;
enum Override {
MAX_STRING_LENGTH(StreamReadConstraints.Builder::maxStringLength, StreamReadConstraints::getMaxStringLength),
MAX_NUMBER_LENGTH(StreamReadConstraints.Builder::maxNumberLength, StreamReadConstraints::getMaxNumberLength),
MAX_NESTING_DEPTH(StreamReadConstraints.Builder::maxNestingDepth, StreamReadConstraints::getMaxNestingDepth),
;
static final String PROP_PREFIX = "logstash.jackson.stream-read-constraints.";
final String propertyName;
private final IntValueApplicator applicator;
private final IntValueObserver observer;
Override(final IntValueApplicator applicator,
final IntValueObserver observer) {
this.propertyName = PROP_PREFIX + this.name().toLowerCase().replace('_', '-');
this.applicator = applicator;
this.observer = observer;
}
@FunctionalInterface
interface IntValueObserver extends Function<StreamReadConstraints, Integer> {}
@FunctionalInterface
interface IntValueApplicator extends BiFunction<StreamReadConstraints.Builder, Integer, StreamReadConstraints.Builder> {}
}
/**
* @return an instance configured by {@code System.getProperties()}
*/
public static StreamReadConstraintsUtil fromSystemProperties() {
return new StreamReadConstraintsUtil(System.getProperties());
}
StreamReadConstraintsUtil(final Properties properties) {
this(properties, null);
}
StreamReadConstraintsUtil(final Properties properties,
final Logger logger) {
this(extractProperties(properties), logger);
}
static private Map<String,String> extractProperties(final Properties properties) {
return properties.stringPropertyNames().stream()
.filter(propName -> propName.startsWith(Override.PROP_PREFIX))
.map(propName -> Map.entry(propName, properties.getProperty(propName)))
.filter(entry -> entry.getValue() != null)
.collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue));
}
private StreamReadConstraintsUtil(final Map<String,String> propertyOverrides,
final Logger logger) {
this.propertyOverrides = Map.copyOf(propertyOverrides);
this.logger = Objects.requireNonNullElseGet(logger, () -> LogManager.getLogger(StreamReadConstraintsUtil.class));
}
StreamReadConstraints get() {
if (configuredStreamReadConstraints == null) {
final StreamReadConstraints.Builder builder = StreamReadConstraints.defaults().rebuild();
eachOverride((override, value) -> override.applicator.apply(builder, value));
this.configuredStreamReadConstraints = builder.build();
}
return configuredStreamReadConstraints;
}
public void applyAsGlobalDefault() {
StreamReadConstraints.overrideDefaultStreamReadConstraints(get());
}
public void validateIsGlobalDefault() {
validate(StreamReadConstraints.defaults());
}
private void validate(final StreamReadConstraints streamReadConstraints) {
final List<String> fatalIssues = new ArrayList<>();
eachOverride((override, specifiedValue) -> {
final Integer effectiveValue = override.observer.apply(streamReadConstraints);
if (Objects.equals(specifiedValue, effectiveValue)) {
logger.info("Jackson default value override `{}` configured to `{}`", override.propertyName, specifiedValue);
} else {
fatalIssues.add(String.format("`%s` (expected: `%s`, actual: `%s`)", override.propertyName, specifiedValue, effectiveValue));
}
});
for (String unsupportedProperty : getUnsupportedProperties()) {
logger.warn("Jackson default value override `{}` is unknown and has been ignored", unsupportedProperty);
}
if (!fatalIssues.isEmpty()) {
throw new IllegalStateException(String.format("Jackson default values not applied: %s", String.join(",", fatalIssues)));
}
}
void eachOverride(BiConsumer<Override,Integer> overrideIntegerBiConsumer) {
for (Override override : Override.values()) {
final String propValue = this.propertyOverrides.get(override.propertyName);
if (propValue != null) {
try {
int intValue = Integer.parseInt(propValue);
overrideIntegerBiConsumer.accept(override, intValue);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(String.format("System property `%s` must be positive integer value. Received: `%s`", override.propertyName, propValue), e);
}
}
}
}
Set<String> getUnsupportedProperties() {
Set<String> supportedProps = Arrays.stream(Override.values()).map(p -> p.propertyName).collect(Collectors.toSet());
Set<String> providedProps = this.propertyOverrides.keySet();
return Sets.difference(providedProps, supportedProps);
}
}

View file

@ -0,0 +1,213 @@
package org.logstash.jackson;
import com.fasterxml.jackson.core.StreamReadConstraints;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.junit.LoggerContextRule;
import org.apache.logging.log4j.test.appender.ListAppender;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.function.BiConsumer;
import org.apache.logging.log4j.Level;
import static org.assertj.core.api.Assertions.*;
import static org.logstash.jackson.StreamReadConstraintsUtil.Override.*;
public class StreamReadConstraintsUtilTest {
@ClassRule
public static final LoggerContextRule LOGGER_CONTEXT_RULE = new LoggerContextRule("log4j2-log-stream-read-constraints.xml");
private ListAppender listAppender;
private Logger observedLogger;
@Before
public void setUpLoggingListAppender() {
int i = 1+16;
this.observedLogger = LOGGER_CONTEXT_RULE.getLogger(StreamReadConstraintsUtil.class);
this.listAppender = LOGGER_CONTEXT_RULE.getListAppender("EventListAppender").clear();
}
@Test
public void configuresDefaultsByDefault() {
StreamReadConstraintsUtil.fromSystemProperties().validateIsGlobalDefault();
}
@Test
public void configuresMaxStringLength() {
final Properties properties = new Properties();
properties.setProperty(MAX_STRING_LENGTH.propertyName, "10101");
fromProperties(properties, (configuredUtil, defaults) -> {
final StreamReadConstraints configuredConstraints = configuredUtil.get();
assertThat(configuredConstraints).returns(10101, from(StreamReadConstraints::getMaxStringLength));
assertThat(configuredConstraints).as("inherited defaults")
.returns(defaults.getMaxDocumentLength(), from(StreamReadConstraints::getMaxDocumentLength))
.returns(defaults.getMaxNameLength(), from(StreamReadConstraints::getMaxNameLength))
.returns(defaults.getMaxNestingDepth(), from(StreamReadConstraints::getMaxNestingDepth))
.returns(defaults.getMaxNumberLength(), from(StreamReadConstraints::getMaxNumberLength));
assertThatThrownBy(configuredUtil::validateIsGlobalDefault).isInstanceOf(IllegalStateException.class).hasMessageContaining(MAX_STRING_LENGTH.propertyName);
configuredUtil.applyAsGlobalDefault();
assertThatCode(configuredUtil::validateIsGlobalDefault).doesNotThrowAnyException();
});
}
@Test
public void configuresMaxStringLengthInvalid() {
final Properties properties = new Properties();
properties.setProperty(MAX_STRING_LENGTH.propertyName, "NaN");
fromProperties(properties, (configuredUtil, defaults) -> assertThatThrownBy(configuredUtil::get)
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(MAX_STRING_LENGTH.propertyName));
}
@Test
public void configuresMaxStringLengthNegative() {
final Properties properties = new Properties();
properties.setProperty(MAX_STRING_LENGTH.propertyName, "-1000");
fromProperties(properties, (configuredUtil, defaults) -> assertThatThrownBy(configuredUtil::get)
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(MAX_STRING_LENGTH.propertyName));
}
@Test
public void configuresMaxNumberLength() {
final Properties properties = new Properties();
properties.setProperty(MAX_NUMBER_LENGTH.propertyName, "101");
fromProperties(properties, (configuredUtil, defaults) -> {
final StreamReadConstraints configuredConstraints = configuredUtil.get();
assertThat(configuredConstraints).returns(101, from(StreamReadConstraints::getMaxNumberLength));
assertThat(configuredConstraints).as("inherited defaults")
.returns(defaults.getMaxDocumentLength(), from(StreamReadConstraints::getMaxDocumentLength))
.returns(defaults.getMaxNameLength(), from(StreamReadConstraints::getMaxNameLength))
.returns(defaults.getMaxNestingDepth(), from(StreamReadConstraints::getMaxNestingDepth))
.returns(defaults.getMaxStringLength(), from(StreamReadConstraints::getMaxStringLength));
assertThatThrownBy(configuredUtil::validateIsGlobalDefault).isInstanceOf(IllegalStateException.class).hasMessageContaining(MAX_NUMBER_LENGTH.propertyName);
configuredUtil.applyAsGlobalDefault();
assertThatCode(configuredUtil::validateIsGlobalDefault).doesNotThrowAnyException();
});
}
@Test
public void configuresMaxNumberLengthInvalid() {
final Properties properties = new Properties();
properties.setProperty(MAX_NUMBER_LENGTH.propertyName, "NaN");
fromProperties(properties, (configuredUtil, defaults) -> assertThatThrownBy(configuredUtil::get)
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(MAX_NUMBER_LENGTH.propertyName));
}
@Test
public void configuresMaxNumberLengthNegative() {
final Properties properties = new Properties();
properties.setProperty(MAX_NUMBER_LENGTH.propertyName, "-1000");
fromProperties(properties, (configuredUtil, defaults) -> assertThatThrownBy(configuredUtil::get)
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(MAX_NUMBER_LENGTH.propertyName));
}
@Test
public void configuresMaxNestingDepth() {
final Properties properties = new Properties();
properties.setProperty(MAX_NESTING_DEPTH.propertyName, "101");
fromProperties(properties, (configuredUtil, defaults) -> {
final StreamReadConstraints configuredConstraints = configuredUtil.get();
assertThat(configuredConstraints).returns(101, from(StreamReadConstraints::getMaxNestingDepth));
assertThat(configuredConstraints).as("inherited defaults")
.returns(defaults.getMaxDocumentLength(), from(StreamReadConstraints::getMaxDocumentLength))
.returns(defaults.getMaxNameLength(), from(StreamReadConstraints::getMaxNameLength))
.returns(defaults.getMaxStringLength(), from(StreamReadConstraints::getMaxStringLength))
.returns(defaults.getMaxNumberLength(), from(StreamReadConstraints::getMaxNumberLength));
assertThatThrownBy(configuredUtil::validateIsGlobalDefault).isInstanceOf(IllegalStateException.class).hasMessageContaining(MAX_NESTING_DEPTH.propertyName);
configuredUtil.applyAsGlobalDefault();
assertThatCode(configuredUtil::validateIsGlobalDefault).doesNotThrowAnyException();
});
}
@Test
public void configuresMaxNestingDepthInvalid() {
final Properties properties = new Properties();
properties.setProperty(MAX_NESTING_DEPTH.propertyName, "NaN");
fromProperties(properties, (configuredUtil, defaults) -> assertThatThrownBy(configuredUtil::get)
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(MAX_NESTING_DEPTH.propertyName));
}
@Test
public void configuresMaxNestingDepthNegative() {
final Properties properties = new Properties();
properties.setProperty(MAX_NESTING_DEPTH.propertyName, "-1000");
fromProperties(properties, (configuredUtil, defaults) -> assertThatThrownBy(configuredUtil::get)
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(MAX_NESTING_DEPTH.propertyName));
}
@Test
public void validatesApplication() {
final Properties properties = new Properties();
properties.setProperty(PROP_PREFIX + "unsupported-option1", "100");
properties.setProperty(PROP_PREFIX + "unsupported-option2", "100");
properties.setProperty(MAX_NESTING_DEPTH.propertyName, "1010");
properties.setProperty(MAX_STRING_LENGTH.propertyName, "1011");
properties.setProperty(MAX_NUMBER_LENGTH.propertyName, "1110");
System.out.format("START%n");
fromProperties(properties, (configuredUtil, defaults) -> {
configuredUtil.applyAsGlobalDefault();
configuredUtil.validateIsGlobalDefault();
});
System.out.format("OK%n");
assertLogObserved(Level.INFO, "override `" + MAX_NESTING_DEPTH.propertyName + "` configured to `1010`");
assertLogObserved(Level.INFO, "override `" + MAX_STRING_LENGTH.propertyName + "` configured to `1011`");
assertLogObserved(Level.INFO, "override `" + MAX_NUMBER_LENGTH.propertyName + "` configured to `1110`");
assertLogObserved(Level.WARN, "override `" + PROP_PREFIX + "unsupported-option1` is unknown and has been ignored");
assertLogObserved(Level.WARN, "override `" + PROP_PREFIX + "unsupported-option1` is unknown and has been ignored");
}
private void assertLogObserved(final Level level, final String... messageFragments) {
List<LogEvent> logEvents = listAppender.getEvents();
assertThat(logEvents)
.withFailMessage("Expected %s to contain a %s-level log event containing %s", logEvents, level, Arrays.toString(messageFragments))
.filteredOn(logEvent -> logEvent.getLevel().equals(level))
.anySatisfy(logEvent -> assertThat(logEvent.getMessage().getFormattedMessage()).contains(messageFragments));
}
private synchronized void fromProperties(final Properties properties, BiConsumer<StreamReadConstraintsUtil, StreamReadConstraints> defaultsConsumer) {
final StreamReadConstraints defaults = StreamReadConstraints.defaults();
try {
final StreamReadConstraintsUtil util = new StreamReadConstraintsUtil(properties, this.observedLogger);
defaultsConsumer.accept(util, defaults);
} finally {
StreamReadConstraints.overrideDefaultStreamReadConstraints(defaults);
}
}
}

View file

@ -59,6 +59,7 @@ public class LogstashConfigurationFactoryTest {
ThreadContext.putAll(dumpedLog4jThreadContext);
snapshotHelper.restoreSnapshot("log4j.configurationFile", "ls.log.format", "ls.logs",
LogstashConfigurationFactory.PIPELINE_SEPARATE_LOGS);
forceLog4JContextRefresh();
}
@Before
@ -123,7 +124,7 @@ public class LogstashConfigurationFactoryTest {
assertNull("No routing appender should be present", routingApp);
}
private void forceLog4JContextRefresh() {
private static void forceLog4JContextRefresh() {
LoggerContext context = LoggerContext.getContext(false);
context.reconfigure();
}

View file

@ -48,6 +48,7 @@ public class PluginDeprecationLoggerTest {
public static void afterClass() {
snapshotHelper.restoreSnapshot("log4j.configurationFile", "ls.log.format", "ls.logs",
LogstashConfigurationFactory.PIPELINE_SEPARATE_LOGS);
LogTestUtils.reloadLogConfiguration();
}
@Before

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="ALL" name="LoggerTest">
<Appenders>
<List name="EventListAppender" /><!-- No pattern layout enables whole event capture-->
</Appenders>
<Loggers>
<Root level="all">
<AppenderRef ref="EventListAppender"/>
</Root>
</Loggers>
</Configuration>