在Log4J中,为什么ConversionPattern中的%C与AsyncAppender一起打印出'?'(问号)?[英] In Log4J, why %C in ConversionPattern prints '?' (question mark) with AsyncAppender?

本文是小编为大家收集整理的关于在Log4J中,为什么ConversionPattern中的%C与AsyncAppender一起打印出'?'(问号)?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我在使用asyncappender中使用%c时遇到麻烦.

我的LO4J配置是:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy/MM/dd HH:mm:ss,SSS} %C{1} - %m%n" />
        </layout>
    </appender>
    <appender name="async_console" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="1000" />
        <appender-ref ref="console" />
    </appender>
    <root>
        <level value="debug" />
        <!--
        <appender-ref ref="console" />
        -->
        <appender-ref ref="async_console" />
    </root>
</log4j:configuration>

我的测试代码是:

@Test
public void testAsync() {
    DOMConfigurator
            .configure("src/test/resources/learningtest/log4j/log4j_test_async.xml");
    Logger log = Logger.getLogger(getClass());
    log.debug("Hello, world!");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

测试代码的结果是:

2012/03/15 11:51:22,570? - 你好,世界!

没有asynappender,它可以正常工作:

2012/03/15 11:51:06,002 log4jtest-你好,世界!

使用%c(类别),它也可以.

我缺少什么?

请让我知道.

预先感谢: - )

参考:

/org/apache/log4j/patternlayout.html

推荐答案

使用"%c"或"%m"时,log4j使用thflow.getStackTrace获取stacktrace并使用此信息来获取呼叫者类和方法. 问题在于,使用asyncappender时,抛出可在另一个线程中创建,并且stacktrace不包含呼叫者方法.

本文地址:https://www.itbaoku.cn/post/1574760.html

问题描述

I have a trouble when using %C in ConversionPattern with AsyncAppender.

My Lo4J configuration is:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy/MM/dd HH:mm:ss,SSS} %C{1} - %m%n" />
        </layout>
    </appender>
    <appender name="async_console" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="1000" />
        <appender-ref ref="console" />
    </appender>
    <root>
        <level value="debug" />
        <!--
        <appender-ref ref="console" />
        -->
        <appender-ref ref="async_console" />
    </root>
</log4j:configuration>

And my test code is:

@Test
public void testAsync() {
    DOMConfigurator
            .configure("src/test/resources/learningtest/log4j/log4j_test_async.xml");
    Logger log = Logger.getLogger(getClass());
    log.debug("Hello, world!");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

The result of the test code is:

2012/03/15 11:51:22,570 ? - Hello, world!

Without AsynAppender, it works fine:

2012/03/15 11:51:06,002 Log4jTest - Hello, world!

With %c (category), it works fine, too.

What am I missing?

Please let me know.

Thanks in advance :-)

Reference:

http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html

推荐答案

When using "%C" or "%M", log4J uses Throwable.getStackTrace to get the stackTrace and use this information to get the caller class and method. The problem is that when using an AsyncAppender, the Throwable is created in another thread and the stackTrace does not contain the caller method.