You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过编程配置Log4J时日志文件为空的原因及解决方法

Log4J编程配置:日志文件创建但为空的问题排查与解决

问题场景

在Zorin 17.1 Core系统搭配OpenJDK 22环境下,通过编程方式配置Log4J,期望日志同时输出到控制台和日志文件,但控制台输出正常,日志文件虽已创建却始终为空。

最小可运行示例代码

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;

public class Main {
    public static void main(String[] args) {
        Level level = Level.WARN;

        ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
        builder.setStatusLevel(level);
        builder.setConfigurationName("BuilderTest");

        AppenderComponentBuilder appenderBuilder =
            builder.newAppender("Stdout", "CONSOLE")
                .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT)
                .add(builder.newLayout("PatternLayout")
                .addAttribute("pattern", "xxxxx %d [%t] %-5level: %msg%n%throwable"))
                .add(builder.newFilter("MarkerFilter", Filter.Result.DENY, Filter.Result.NEUTRAL)
                .addAttribute("marker", "FLOW"));

        builder.add(appenderBuilder);

        appenderBuilder =
            builder.newAppender("File", "File")
            .addAttribute("fileName", "logs/main.log")
            .addAttribute("append", true)
            .addAttribute("locking", false)
            .addAttribute("immediateFlush", true)
            .add(builder.newLayout("PatternLayout")
            .addAttribute("pattern", "xxxxxx %d [%t] %-5level: %msg%n%throwable"));

        builder.add(appenderBuilder);

        builder
            .add(builder.newLogger("org.apache.logging.log4j", level)
            .add(builder.newAppenderRef("Stdout"))
            .addAttribute("additivity", false));

        builder.add(
            builder
                .newRootLogger(level)
                .add(builder.newAppenderRef("Stdout"))
        );

        Configurator.reconfigure(builder.build());
        LoggerConfig loggerConfig = new LoggerConfig(Main.class.getPackageName(), level, false);
        Configurator.setLevel(Main.class.getPackageName(), level);

        LogManager.getRootLogger().error("setLoggingLevel(): Logging level set to %s.".formatted(level));
    }
}

控制台输出

xxxxx 2024-08-30 01:43:22,830 [main] ERROR: setLoggingLevel(): Logging level set to WARN.

原pom.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example.log4j-test</groupId>
    <artifactId>log4j-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>22</maven.compiler.source>
        <maven.compiler.target>22</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.3.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>3.0.0-beta2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>3.0.0-beta2</version>
        </dependency>
    </dependencies>
</project>

问题原因

  1. File Appender未关联到日志记录器:代码中仅为Root Logger添加了控制台Appender的引用,没有将创建好的File Appender关联到Root Logger或自定义Logger,导致日志不会写入文件。
  2. 依赖版本冲突:pom.xml中同时引入了Log4J 1.2.x和Log4J 2.x(3.0.0-beta2)两个不兼容的版本,会引发类加载混乱,可能导致部分配置逻辑失效。
  3. 自定义Logger配置无效:代码中创建了LoggerConfig实例但未将其添加到Log4J的配置中,仅调用Configurator.setLevel无法让自定义Logger生效,也不会关联File Appender。

解决方案

1. 清理冲突依赖

移除Log4J 1.2.17和commons-logging依赖(若项目无需兼容旧代码),仅保留Log4J 2.x的api和core依赖,避免版本冲突。

2. 关联File Appender到Root Logger

在构建Root Logger时,添加File Appender的引用,确保日志会同时输出到控制台和文件。

3. (可选)正确配置自定义Logger

如果需要针对特定包配置日志,应通过ConfigurationBuilder添加自定义Logger,并关联所需的Appender,而非单独创建LoggerConfig实例。

修正后的代码

修正后的Main.java

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;

public class Main {
    public static void main(String[] args) {
        Level level = Level.WARN;

        ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
        builder.setStatusLevel(level);
        builder.setConfigurationName("BuilderTest");

        // 配置控制台Appender
        AppenderComponentBuilder appenderBuilder =
            builder.newAppender("Stdout", "CONSOLE")
                .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT)
                .add(builder.newLayout("PatternLayout")
                .addAttribute("pattern", "xxxxx %d [%t] %-5level: %msg%n%throwable"))
                .add(builder.newFilter("MarkerFilter", Filter.Result.DENY, Filter.Result.NEUTRAL)
                .addAttribute("marker", "FLOW"));

        builder.add(appenderBuilder);

        // 配置文件Appender
        appenderBuilder =
            builder.newAppender("File", "File")
            .addAttribute("fileName", "logs/main.log")
            .addAttribute("append", true)
            .addAttribute("locking", false)
            .addAttribute("immediateFlush", true)
            .add(builder.newLayout("PatternLayout")
            .addAttribute("pattern", "xxxxxx %d [%t] %-5level: %msg%n%throwable"));

        builder.add(appenderBuilder);

        // 配置org.apache.logging.log4j包的Logger
        builder
            .add(builder.newLogger("org.apache.logging.log4j", level)
            .add(builder.newAppenderRef("Stdout"))
            .addAttribute("additivity", false));

        // 配置Root Logger,同时关联控制台和文件Appender
        builder.add(
            builder
                .newRootLogger(level)
                .add(builder.newAppenderRef("Stdout"))
                .add(builder.newAppenderRef("File")) // 新增File Appender引用
        );

        // 应用配置
        Configurator.reconfigure(builder.build());
        // 若需要针对当前包设置日志级别,直接通过Configurator设置即可
        Configurator.setLevel(Main.class.getPackageName(), level);

        LogManager.getRootLogger().error("setLoggingLevel(): Logging level set to %s.".formatted(level));
    }
}

修正后的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example.log4j-test</groupId>
    <artifactId>log4j-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>22</maven.compiler.source>
        <maven.compiler.target>22</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- 使用稳定版Log4J 2.x,beta版本可能存在未知问题 -->
        <log4j.version>2.23.1</log4j.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>
    </dependencies>
</project>

验证效果

运行修正后的代码,控制台会输出原有日志,同时logs/main.log文件中会写入对应的日志内容,格式与配置的PatternLayout一致。

内容的提问来源于stack exchange,提问作者Pixelcode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 21:54:58