当前位置: 首页 > 知识库问答 >
问题:

混合同步和异步记录器不工作-log4j2

农存
2023-03-14

使用log4j2,我很难让同步记录器和异步记录器一起工作。

从这里以Apache文档(标题为混合同步和异步记录器)为例,运行下面的应用程序将简单地创建日志文件,但不向其写入任何内容。我也不确定添加两个记录器指向同一个appender,但它的Apache留档,所以我假设这是好的。

LOG4J2配置

<?xml version="1.0" encoding="UTF-8"?>

<!-- No need to set system property "Log4jContextSelector" to any value
     when using <asyncLogger> or <asyncRoot>. -->

<Configuration status="WARN">
    <Appenders>
        <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
        <RandomAccessFile name="RandomAccessFile" fileName="asyncWithLocation.log"
                          immediateFlush="false" append="false">
            <PatternLayout>
                <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern>
            </PatternLayout>
        </RandomAccessFile>
    </Appenders>
    <Loggers>
        <!-- pattern layout actually uses location, so we need to include it -->
        <AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">
            <AppenderRef ref="RandomAccessFile"/>
        </AsyncLogger>
        <Root level="info" includeLocation="true">
            <AppenderRef ref="RandomAccessFile"/>
        </Root>
    </Loggers>
</Configuration>

pom.xml

<dependencies>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>com.lmax</groupId>
        <artifactId>disruptor</artifactId>
        <version>3.3.6</version>
    </dependency>
</dependencies>

应用

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

public class Main {
    public static void main(String[] args) {
        Logger logger = LogManager.getLogger("HelloWorld");
        for(int i = 0; i < 20; i++){
            logger.trace(String.format("Hello number %d", i));
        }
        LogManager.shutdown();
    }
}

但是,如果我更改log4j2配置并修改loggers元素以读取以下内容,我将在日志文件中获得预期的输出。

<Loggers>
    <AsyncRoot name="com.foo.Bar" level="trace" includeLocation="true">
        <AppenderRef ref="RandomAccessFile"/>
    </AsyncRoot>
</Loggers>

我需要什么

理想情况下,我希望下面这样的工作。但是,此配置只会将行打印到控制台并创建日志文件,而不会将内容写入其中。我错过了什么?

<?xml version="1.0" encoding="UTF-8"?>

<!-- No need to set system property "Log4jContextSelector" to any value
     when using <asyncLogger> or <asyncRoot>. -->

<Configuration status="WARN">
    <Appenders>
        <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
        <RandomAccessFile name="RandomAccessFile" fileName="asyncWithLocation.log"
                          immediateFlush="false" append="false">
            <PatternLayout>
                <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern>
            </PatternLayout>
        </RandomAccessFile>

        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level - %msg%n"/>
        </Console>

    </Appenders>
    <Loggers>
        <!--write to file - i dont care when it happens-->
        <AsyncLogger level="trace" includeLocation="true">
            <AppenderRef ref="RandomAccessFile"/>
        </AsyncLogger>

        <!--Async so the console messages appear in the order expected-->
        <Root level="trace">
            <AppenderRef ref="Console"/>
        </Root>

    </Loggers>
</Configuration>

共有1个答案

梁昊天
2023-03-14

因为在第一个LOG4J2配置中,根记录器的级别是“info”。而在main方法中,您正在执行记录器。trace()。参考文件:https://logging.apache.org/log4j/2.0/manual/architecture.html

在这里,它们表示级别命令。

如果Asyncroot您将级别更改为“跟踪”。这就是它起作用的原因。同样,当您将appender添加为控制台时,您将拥有level=“trace”。

您正在获取根记录器,因为没有记录器名称“HelloWorld”,默认情况下,它将为您提供根记录器。

尝试使用记录器。info()。

 类似资料:
  • 我正在尝试设置log4j2以使用异步记录器将所有消息记录到滚动文件中。 是否有一种方法可以创建另一个记录程序来捕获所有事件?还有别的想法吗? 下面是我的log4j2.xml:

  • 基于https://logging.apache.org/log4j/2.x/manual/async.html我想使用混合同步和异步记录器的方法,以便从所有同步记录器的性能改进中获益。 基准代码: Log4j2配置正是文档中的配置(https://logging.apache.org/log4j/2.x/manual/async.html): 使用这种混合的同步/异步记录器配置,我可以每秒获得大

  • 在这个msdn页面上,我读到: 应用程序不能为特定请求混合同步和异步方法。如果调用BeginGetRequestStream方法,则必须使用BeginGetResponse方法检索响应。 反之亦然吗?如果调用异步读取响应,是否还应该使用编写请求? 我的请求很小(100-1000个字符),响应可以很大。Jeffrey Richter的这篇文章似乎是说,在小负载的情况下,它可以同步完成(并且不需要设置

  • 问题内容: 现在在我的应用程序中,某些时候我们正在将一些繁重的工作记录到日志文件中。 基本上仅用于日志记录,我们先创建可用数据的JSON,然后登录到Log文件。这是以JSON格式记录数据的业务要求。 现在从可用数据创建JSON,然后登录到FILE需要花费大量时间,并影响原始请求的返回时间。现在的想法是改善环境。 我们讨论的一件事是使用以下方法创建线程池 在我们的代码中,然后向其提交任务,该任务会将

  • 请参阅代码。 > 当我调用方法@Async loadMarkUpPCT()时,数据没有提交到表中。它表现得好像是非牵引的。 当我从loadMarkUpPCT(类1)中删除@Async(即非异步)时,数据被提交并按预期正常:事务性) 我希望@Async和@Transactional的结果是一样的,但事实并非如此。请解释一下,我做错了什么? 编辑:我刚编辑过代码日志 流程方面:AppDataLoade

  • 这个练习直接来自SCJP,由凯西·塞拉和伯特·贝茨完成 同步代码块 在这个练习中,我们将尝试同步一个代码块。在该代码块中,我们将获得对象的锁,以便其他线程在代码块执行时无法修改它。我们将创建三个线程,它们都将尝试操作同一对象。每个线程将输出一个字母100次,然后将该字母递增一次。我们将使用的对象是StringBuffer。 我们可以在一个String对象上进行同步,但是字符串一旦创建就不能被修改,