ConcurrentLoggingWithJsonLayoutTest is failing for me. I don’t understand why.
2017-01-09 21:41:06,174 main DEBUG Starting
LoggerContext[name=org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest]
from configuration at log4j2-json-layout.xml
2017-01-09 21:41:06,176 main DEBUG Starting
LoggerContext[name=org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest,
org.apache.logging.log4j.core.LoggerContext@14acaea5] with configuration
XmlConfiguration[location=/Users/rgoers/projects/apache/logging/log4j/log4j2/current/log4j-core/target/test-classes/log4j2-json-layout.xml]...
2017-01-09 21:41:06,177 main DEBUG Shutdown hook enabled. Registering a new one.
2017-01-09 21:41:06,187 main DEBUG Initializing configuration
XmlConfiguration[location=/Users/rgoers/projects/apache/logging/log4j/log4j2/current/log4j-core/target/test-classes/log4j2-json-layout.xml]
2017-01-09 21:41:06,193 main DEBUG Installed script engines
2017-01-09 21:41:06,208 main DEBUG Groovy Scripting Engine Version: 2.0,
Language: Groovy, Threading: MULTITHREADED, Compile: true, Names: {groovy,
Groovy}
2017-01-09 21:41:06,499 main DEBUG Oracle Nashorn Version: 1.8.0_65, Language:
ECMAScript, Threading: Not Thread Safe, Compile: true, Names: {nashorn,
Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript}
2017-01-09 21:41:06,538 main DEBUG BeanShell Engine Version: 1.0, Language:
BeanShell, Threading: MULTITHREADED, Compile: true, Names: {beanshell, bsh,
java}
2017-01-09 21:41:06,539 main DEBUG PluginManager 'Core' found 121 plugins
2017-01-09 21:41:06,539 main DEBUG PluginManager 'Level' found 1 plugins
2017-01-09 21:41:06,543 main DEBUG PluginManager 'Lookup' found 13 plugins
2017-01-09 21:41:06,545 main DEBUG Building Plugin[name=layout,
class=org.apache.logging.log4j.core.layout.JsonLayout].
2017-01-09 21:41:06,556 main DEBUG PluginManager 'TypeConverter' found 26
plugins
2017-01-09 21:41:06,575 main DEBUG JsonLayout$Builder(locationInfo="null",
properties="null", propertiesAsList="null", includeStacktrace="null",
eventEol="true", compact="true", complete="null", charset="null",
footerSerializer=null, headerSerializer=null,
Configuration(/Users/rgoers/projects/apache/logging/log4j/log4j2/current/log4j-core/target/test-classes/log4j2-json-layout.xml),
footer="null", header="null")
2017-01-09 21:41:06,710 main DEBUG PluginManager 'Converter' found 41 plugins
2017-01-09 21:41:06,710 main DEBUG Building Plugin[name=appender,
class=org.apache.logging.log4j.core.appender.FileAppender].
2017-01-09 21:41:06,718 main DEBUG
FileAppender$Builder(fileName="target/test-json-layout.log", append="false",
locking="null", advertise="null", advertiseUri="null", createOnDemand="null",
bufferedIo="null", bufferSize="null", immediateFlush="null",
ignoreExceptions="false",
JsonLayout(org.apache.logging.log4j.core.layout.JsonLayout@37654521),
name="stdout",
Configuration(/Users/rgoers/projects/apache/logging/log4j/log4j2/current/log4j-core/target/test-classes/log4j2-json-layout.xml),
Filter=null)
2017-01-09 21:41:06,719 main DEBUG Starting FileManager
target/test-json-layout.log
2017-01-09 21:41:06,720 main DEBUG Building Plugin[name=appenders,
class=org.apache.logging.log4j.core.config.AppendersPlugin].
2017-01-09 21:41:06,721 main DEBUG createAppenders(={stdout})
2017-01-09 21:41:06,722 main DEBUG Building Plugin[name=AppenderRef,
class=org.apache.logging.log4j.core.config.AppenderRef].
2017-01-09 21:41:06,725 main DEBUG createAppenderRef(ref="stdout",
level="null", Filter=null)
2017-01-09 21:41:06,726 main DEBUG Building Plugin[name=root,
class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger].
2017-01-09 21:41:06,727 main DEBUG createLogger(additivity="null",
level="INFO", includeLocation="null", ={stdout}, ={},
Configuration(/Users/rgoers/projects/apache/logging/log4j/log4j2/current/log4j-core/target/test-classes/log4j2-json-layout.xml),
Filter=null)
2017-01-09 21:41:06,729 main DEBUG Building Plugin[name=loggers,
class=org.apache.logging.log4j.core.config.LoggersPlugin].
2017-01-09 21:41:06,729 main DEBUG createLoggers(={root})
2017-01-09 21:41:06,730 main DEBUG Configuration
XmlConfiguration[location=/Users/rgoers/projects/apache/logging/log4j/log4j2/current/log4j-core/target/test-classes/log4j2-json-layout.xml]
initialized
2017-01-09 21:41:06,730 main DEBUG Starting configuration
XmlConfiguration[location=/Users/rgoers/projects/apache/logging/log4j/log4j2/current/log4j-core/target/test-classes/log4j2-json-layout.xml]
2017-01-09 21:41:06,731 main DEBUG Started configuration
XmlConfiguration[location=/Users/rgoers/projects/apache/logging/log4j/log4j2/current/log4j-core/target/test-classes/log4j2-json-layout.xml]
OK.
2017-01-09 21:41:06,732 main DEBUG Shutting down OutputStreamManager
SYSTEM_OUT.false.false-1
2017-01-09 21:41:06,732 main DEBUG Shut down OutputStreamManager
SYSTEM_OUT.false.false-1, all resources released: true
2017-01-09 21:41:06,732 main DEBUG Stopped
org.apache.logging.log4j.core.config.DefaultConfiguration@66d2e7d9 OK
2017-01-09 21:41:06,784 main DEBUG Registering MBean
org.apache.logging.log4j2:type=org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest
2017-01-09 21:41:06,786 main DEBUG Registering MBean
org.apache.logging.log4j2:type=org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest,component=StatusLogger
2017-01-09 21:41:06,787 main DEBUG Registering MBean
org.apache.logging.log4j2:type=org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest,component=ContextSelector
2017-01-09 21:41:06,789 main DEBUG Registering MBean
org.apache.logging.log4j2:type=org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest,component=Loggers,name=
2017-01-09 21:41:06,790 main DEBUG Registering MBean
org.apache.logging.log4j2:type=org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest,component=Appenders,name=stdout
2017-01-09 21:41:06,791 main DEBUG
LoggerContext[name=org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest,
org.apache.logging.log4j.core.LoggerContext@14acaea5] started OK with
configuration
XmlConfiguration[location=/Users/rgoers/projects/apache/logging/log4j/log4j2/current/log4j-core/target/test-classes/log4j2-json-layout.xml].
Running org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest
2017-01-09 21:41:06,976 main DEBUG Stopping
LoggerContext[name=org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest,
org.apache.logging.log4j.core.LoggerContext@14acaea5]...
2017-01-09 21:41:06,978 main DEBUG Shutting down FileManager
target/test-json-layout.log
2017-01-09 21:41:06,980 main DEBUG Shut down FileManager
target/test-json-layout.log, all resources released: true
2017-01-09 21:41:06,980 main DEBUG Stopped
XmlConfiguration[location=/Users/rgoers/projects/apache/logging/log4j/log4j2/current/log4j-core/target/test-classes/log4j2-json-layout.xml]
OK
2017-01-09 21:41:06,981 main DEBUG Stopped
LoggerContext[name=org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest,
org.apache.logging.log4j.core.LoggerContext@14acaea5]...
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.187 sec <<<
FAILURE! - in
org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest
testConcurrentLogging(org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest)
Time elapsed: 0.182 sec <<< ERROR!
java.nio.file.NoSuchFileException: target/test-json-layout.log
at
org.apache.logging.log4j.core.layout.ConcurrentLoggingWithJsonLayoutTest.testConcurrentLogging(ConcurrentLoggingWithJsonLayoutTest.java:86)
Results :
Tests in error:
ConcurrentLoggingWithJsonLayoutTest.testConcurrentLogging:86 » NoSuchFile
targ...
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0
Ralph
> On Jan 7, 2017, at 6:51 AM, [email protected] wrote:
>
> Repository: logging-log4j2
> Updated Branches:
> refs/heads/master 9397da66f -> 34a41236f
>
>
> Fixed concurrency issue affecting all layouts except PatternLayout and
> GelfLayout, which caused scrambled output and exceptions when logging
> synchronously from multiple threads.
>
>
> Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
> Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/2f8b6651
> Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/2f8b6651
> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/2f8b6651
>
> Branch: refs/heads/master
> Commit: 2f8b66510747a1d485cfd3597ea34c9071e1384a
> Parents: 0bca4ca
> Author: rpopma <[email protected]>
> Authored: Sat Jan 7 22:51:24 2017 +0900
> Committer: rpopma <[email protected]>
> Committed: Sat Jan 7 22:51:24 2017 +0900
>
> ----------------------------------------------------------------------
> .../log4j/core/layout/AbstractLayout.java | 24 ++--
> .../ConcurrentLoggingWithJsonLayoutTest.java | 115 +++++++++++++++++++
> src/changes/changes.xml | 3 +
> 3 files changed, 131 insertions(+), 11 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2f8b6651/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
> ----------------------------------------------------------------------
> diff --git
> a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
>
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
> index e1e419d..393f8c1 100644
> ---
> a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
> +++
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractLayout.java
> @@ -49,7 +49,7 @@ public abstract class AbstractLayout<T extends
> Serializable> implements Layout<T
>
> @PluginBuilderAttribute
> private byte[] footer;
> -
> +
> @PluginBuilderAttribute
> private byte[] header;
>
> @@ -222,15 +222,17 @@ public abstract class AbstractLayout<T extends
> Serializable> implements Layout<T
> */
> public static void writeTo(final byte[] data, int offset, int length,
> final ByteBufferDestination destination) {
> int chunk = 0;
> - ByteBuffer buffer = destination.getByteBuffer();
> - do {
> - if (length > buffer.remaining()) {
> - buffer = destination.drain(buffer);
> - }
> - chunk = Math.min(length, buffer.remaining());
> - buffer.put(data, offset, chunk);
> - offset += chunk;
> - length -= chunk;
> - } while (length > 0);
> + synchronized (destination) {
> + ByteBuffer buffer = destination.getByteBuffer();
> + do {
> + if (length > buffer.remaining()) {
> + buffer = destination.drain(buffer);
> + }
> + chunk = Math.min(length, buffer.remaining());
> + buffer.put(data, offset, chunk);
> + offset += chunk;
> + length -= chunk;
> + } while (length > 0);
> + }
> }
> }
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2f8b6651/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/ConcurrentLoggingWithJsonLayoutTest.java
> ----------------------------------------------------------------------
> diff --git
> a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/ConcurrentLoggingWithJsonLayoutTest.java
>
> b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/ConcurrentLoggingWithJsonLayoutTest.java
> new file mode 100644
> index 0000000..7b4bb4c
> --- /dev/null
> +++
> b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/ConcurrentLoggingWithJsonLayoutTest.java
> @@ -0,0 +1,115 @@
> +/*
> + * 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.core.layout;
> +
> +import java.io.File;
> +import java.nio.charset.Charset;
> +import java.nio.file.Files;
> +import java.nio.file.Paths;
> +import java.util.ArrayList;
> +import java.util.Collections;
> +import java.util.HashSet;
> +import java.util.List;
> +import java.util.Set;
> +
> +import org.apache.logging.log4j.Logger;
> +import org.apache.logging.log4j.junit.LoggerContextRule;
> +import org.junit.Before;
> +import org.junit.ClassRule;
> +import org.junit.Test;
> +
> +import static org.hamcrest.CoreMatchers.*;
> +
> +import static org.junit.Assert.*;
> +
> +/**
> + * Test for LOG4J2-1769.
> + *
> + * @since 2.8
> + */
> +public class ConcurrentLoggingWithJsonLayoutTest {
> + @ClassRule
> + public static LoggerContextRule context = new
> LoggerContextRule("log4j2-json-layout.xml");
> + private static final String PATH = "target/test-json-layout.log";
> +
> + @Before
> + public void before() {
> + new File(PATH).delete();
> + }
> +
> + @Test
> + public void testConcurrentLogging() throws Throwable {
> + final Logger log =
> context.getLogger(ConcurrentLoggingWithJsonLayoutTest.class);
> + final Set<Thread> threads = Collections.synchronizedSet(new
> HashSet<Thread>());
> + final List<Throwable> thrown = Collections.synchronizedList(new
> ArrayList<Throwable>());
> +
> + for (int x = 0; x < Runtime.getRuntime().availableProcessors() * 2;
> x++) {
> + final Thread t = new LoggingThread(threads, log);
> + threads.add(t);
> +
> + // Appender is configured with ignoreExceptions="false";
> + // any exceptions are propagated to the caller, so we can catch
> them here.
> + t.setUncaughtExceptionHandler(new
> Thread.UncaughtExceptionHandler() {
> + @Override
> + public void uncaughtException(final Thread t, final
> Throwable e) {
> + thrown.add(e);
> + }
> + });
> + t.start();
> + }
> +
> + while (!threads.isEmpty()) {
> + log.info("not done going to sleep...");
> + Thread.sleep(10);
> + }
> +
> + // if any error occurred, fail this test
> + if (!thrown.isEmpty()) {
> + throw thrown.get(0);
> + }
> +
> + // simple test to ensure content is not corrupted
> + final List<String> lines = Files.readAllLines(Paths.get(PATH),
> Charset.defaultCharset());
> + for (final String line : lines) {
> + assertThat(line, startsWith("{\"timeMillis\":"));
> + assertThat(line, endsWith("\"threadPriority\":5}"));
> + }
> + }
> +
> + private class LoggingThread extends Thread {
> + private final Set<Thread> threads;
> + private final Logger log;
> +
> + LoggingThread(final Set<Thread> threads, final Logger log) {
> + this.threads = threads;
> + this.log = log;
> + }
> +
> + @Override
> + public void run() {
> + log.info(threads.size());
> + try {
> + for (int i = 0; i < 64; i++) {
> + log.info("First message.");
> + log.info("Second message.");
> + }
> + } finally {
> + threads.remove(this);
> + }
> + }
> + }
> +}
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2f8b6651/src/changes/changes.xml
> ----------------------------------------------------------------------
> diff --git a/src/changes/changes.xml b/src/changes/changes.xml
> index bfefc24..789882c 100644
> --- a/src/changes/changes.xml
> +++ b/src/changes/changes.xml
> @@ -24,6 +24,9 @@
> </properties>
> <body>
> <release version="2.8" date="2017-MM-DD" description="GA Release 2.8">
> + <action issue="LOG4J2-1769" dev="rpopma" type="fix" due-to="Brandon
> Goodin">
> + Fixed concurrency issue affecting all layouts except PatternLayout
> and GelfLayout, which caused scrambled output and exceptions when logging
> synchronously from multiple threads.
> + </action>
> <action issue="LOG4J2-1724" dev="mikes" type="fix" due-to="Alexander K">
> Using variables in GelfLayout's additional fields at runtime.
> </action>
>
>