This is an automated email from the ASF dual-hosted git repository. vy pushed a commit to branch release-2.x in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 5410ff51ba9556e7e8d200f255be0ff2d44a6fba Author: Volkan Yazici <[email protected]> AuthorDate: Fri Feb 18 11:35:21 2022 +0100 LOG4J2-2368 Test JsonTemplateLayout's ThreadLocalRecycler against nested logging. --- .../json/ThreadLocalRecyclerNestedLoggingTest.java | 84 ++++++++++++++++++++++ .../resources/threadLocalRecyclerNestedLogging.xml | 38 ++++++++++ 2 files changed, 122 insertions(+) diff --git a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/ThreadLocalRecyclerNestedLoggingTest.java b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/ThreadLocalRecyclerNestedLoggingTest.java new file mode 100644 index 0000000..fb4a841 --- /dev/null +++ b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/ThreadLocalRecyclerNestedLoggingTest.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.apache.logging.log4j.layout.template.json; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.layout.AbstractStringLayout; +import org.apache.logging.log4j.junit.LoggerContextSource; +import org.apache.logging.log4j.junit.Named; +import org.apache.logging.log4j.layout.template.json.util.ThreadLocalRecycler; +import org.apache.logging.log4j.test.appender.ListAppender; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Tests if logging while trying to encode an event causes {@link ThreadLocalRecycler} to incorrectly share buffers and end up overriding layout's earlier encoding work. + * + * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-2368">LOG4J2-2368</a> + */ +public class ThreadLocalRecyclerNestedLoggingTest { + + private static final class ThrowableLoggingInGetMessage extends RuntimeException { + + private final Logger logger; + + private ThrowableLoggingInGetMessage(Logger logger) { + this.logger = logger; + } + + @Override + public String getMessage() { + logger.info("B"); + return "C"; + } + + } + + @Test + @LoggerContextSource("threadLocalRecyclerNestedLogging.xml") + public void nested_logging_should_not_pollute_thread_local( + final LoggerContext loggerContext, + final @Named(value = "List1") ListAppender appender1, + final @Named(value = "List2") ListAppender appender2) { + final Logger logger = loggerContext.getLogger(ThreadLocalRecyclerNestedLoggingTest.class); + logger.error("A", new ThrowableLoggingInGetMessage(logger)); + final List<String> messages1 = readAppendedMessages(appender1); + final List<String> messages2 = readAppendedMessages(appender2); + Assertions + .assertThat(messages1) + .containsExactlyInAnyOrderElementsOf(messages2) + .containsExactlyInAnyOrderElementsOf(Stream + .of("['B',null]", "['A','C']") + .map(json -> json.replaceAll("'", "\"")) + .collect(Collectors.toList())); + } + + private static List<String> readAppendedMessages(final ListAppender appender) { + return appender + .getData() + .stream() + .map(messageBytes -> new String(messageBytes, StandardCharsets.UTF_8)) + .collect(Collectors.toList()); + } + +} diff --git a/log4j-layout-template-json/src/test/resources/threadLocalRecyclerNestedLogging.xml b/log4j-layout-template-json/src/test/resources/threadLocalRecyclerNestedLogging.xml new file mode 100644 index 0000000..1b58ad1 --- /dev/null +++ b/log4j-layout-template-json/src/test/resources/threadLocalRecyclerNestedLogging.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF 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. +--> +<Configuration status="OFF" name="NestedLoggingFromThrowableMessageTest"> + <Properties> + <Property name="eventTemplate">[{"$resolver": "message", "stringified": true}, {"$resolver": "exception", "field": "message"}]</Property> + </Properties> + <Appenders> + <List name="List1" raw="true"> + <JsonTemplateLayout eventTemplate="${eventTemplate}" recyclerFactory="threadLocal" eventDelimiter=""/> + </List> + <List name="List2" raw="true"> + <JsonTemplateLayout eventTemplate="${eventTemplate}" recyclerFactory="threadLocal" eventDelimiter=""/> + </List> + </Appenders> + <Loggers> + <Root level="trace"> + <AppenderRef ref="List1"/> + </Root> + <Logger name="org" level="trace"> + <AppenderRef ref="List2"/> + </Logger> + </Loggers> +</Configuration>
