【问题标题】:How to use log4j2 FileAppender with SLF4J API如何将 log4j2 FileAppender 与 SLF4J API 一起使用
【发布时间】:2022-02-02 07:09:32
【问题描述】:

我一直在尝试按照本网站和其他网站上的食谱来了解如何将 log4j2 FileAppender 实例添加到使用 SLF4J API 进行整体日志记录的类中,但我运气不佳。有人可以告诉我以下代码有什么问题吗?

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.FileAppender;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FileAppenderTest {

    private static final Logger log = LoggerFactory.getLogger(FileAppenderTest.class);

    private final Layout<?> taskLogLayout = PatternLayout.newBuilder()
        .withPattern("%d %-5p [%t:%C{1}.%M] %m%n")
        .build();

    @Test
    public void testFileAppender() throws IOException {

        File appenderFile = new File("build/test", "file-appender.log");

        FileAppender taskLog = FileAppender.newBuilder()
            .withFileName(appenderFile.getAbsolutePath())
            .setName("file-appender.log")
            .setLayout(taskLogLayout)
            .build();
        taskLog.start();

        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
        Configuration c = ctx.getConfiguration();
        LoggerConfig lc = c.getLoggerConfig("");
        lc.addAppender(taskLog, Level.ALL, null);

        log.info("Here is a test message with INFO level");
        log.warn("Here is a test message with WARN level");

        lc.removeAppender("file-appender.log");

        assertTrue(appenderFile.exists());

        List<String> logLines = FileUtils.readLines(appenderFile, (Charset) null);
        assertEquals(2, logLines.size());

    }

}

assertTrue 语句通过,因此文件由 FileAppender 创建,但 assertEquals 失败,因为 logLines 的长度为零(即日志文件没有内容)。

有什么想法吗?

【问题讨论】:

  • 你的类路径上有 SLF4J-to-Log4j2 (log4j-slf4j-impl) 绑定吗?你用的是什么版本的 SLF4J 和 Log4j2?
  • 我在类路径上有 log4j-slf4j-impl-2.15.0。另外:slf4j-api-1.7.32; log4j-over-slf4j-1.7.32; log4j-api-2.15.0; log4j-core-2.15.0.
  • 我删除了 log4j-over-slf4j 并需要清理一些遗留代码使用 log4j 1.x API 的地方。没有解决问题。

标签: java logging log4j slf4j


【解决方案1】:

发现问题:

在上面的代码中,请注意 Logger 是在应用任何日志记录配置设置之前从 LoggerFactory 获得的。这会导致记录器具有默认级别的 ERROR。因此,即使 APPENDER 具有 INFO 级别,LOGGER 也具有 ERROR 级别,并且在 INFO 和 WARN 消息到达 appender 之前就拒绝它们!

以下代码将通过所有测试。请注意,Logger 不再是静态成员,并且在获取 Logger 之前将配置设置为具有 ANY 级别。

package gov.nasa.ziggy.worker;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.FileAppender;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FileAppenderTest {

    private final Layout<?> taskLogLayout = PatternLayout.newBuilder()
        .withPattern("%d %-5p [%t:%C{1}.%M] %m%n")
        .build();

    @Test
    public void testFileAppender() throws IOException {

        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
        Configuration c = ctx.getConfiguration();
        LoggerConfig lc = c.getLoggerConfig("");
        lc.setLevel(Level.ALL);

        Logger log = LoggerFactory.getLogger(FileAppenderTest.class);
        File appenderFile = new File("build/test", "file-appender.log");

        FileAppender taskLog = FileAppender.newBuilder()
            .withFileName(appenderFile.getAbsolutePath())
            .setName("file-appender.log")
            .setLayout(taskLogLayout)
            .build();
        taskLog.start();

        lc.addAppender(taskLog, Level.ALL, null);

        log.info("Here is a test message with INFO level");
        log.warn("Here is a test message with WARN level");

        lc.removeAppender("file-appender.log");

        assertTrue(appenderFile.exists());

        List<String> logLines = FileUtils.readLines(appenderFile, (Charset) null);
        assertEquals(2, logLines.size());

    }

}

【讨论】:

    猜你喜欢
    • 2014-09-25
    • 2015-11-28
    • 2021-02-18
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多