You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by vy...@apache.org on 2022/02/18 10:37:34 UTC

[logging-log4j2] 02/02: LOG4J2-2368 Test JsonTemplateLayout's ThreadLocalRecycler against nested logging.

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 <vo...@yazi.ci>
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>