Spring Boot 调用时,Log4j 不会输出到文件(但在命令行上调用时会输出)

Log4j does not output to file when called by Spring Boot (but it does when called on command line)

问题总结

我有一个可以通过两个入口点调用的服务:控制台应用程序的 main() 和休息端点。

该服务应该通过 SL4J 记录器记录到一个文件。

当我通过命令行 (java -jar myArtifact.jar <some execution parameters>) 调用应用程序时,它工作正常,文件已正确填充。

当我通过 Spring 休息端点发出请求时,我在保持 REST 服务正常运行的过程中看到我的记录器的输出:

(箭头指示的行是我的记录器记录的第一行)。

我觉得 Spring 中的某些配置正在清除我的 log4j 配置。

任何人都可以指出正确的方向让我的记录器正确地登录到我想要的文件吗?

设置

我有一个项目有一个 TaskService 其中包含一个静态 Logger (org.sl4j).

可以通过两种方式调用此服务:


三个classes的相关部分:

TaskService.java

public final class TaskService {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(TaskService.class);

}

TaskCommandLineApp.java

public static void main(String[] args) {
    //...
    TaskRequest taskRequest = ... (coming from input);
    TaskService taskService = new TaskService();
    taskService.run(taskRequest);
    //...
}

TaskController.java

@RestController
@RequestMapping("/task")
public final class TaskController {

    @Autowired
    private final TaskService taskService;
    
    @RequestMapping(value = "/tasks", method = RequestMethod.POST)
    public ResponseEntity<?> postTask(@RequestBody TaskRequest taskRequest) {
        //...
        taskRequest.run(taskRequest);
        //...
    }
}

log4j2.xml 配置文件位于声明 TaskService 的模块的 src/main/resources 文件夹中(使用记录器的 class),它包含以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <File name="File" fileName="task.log" immediateFlush="true" append="false">
            <PatternLayout>
                <pattern>%d %p %C{1.} [%t] %m%n</pattern>
            </PatternLayout>
        </File>
    </Appenders>
    <Loggers>
        <!-- additivity=false ensures summary log data only goes to the summary log file -->
        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="File"/>
        </Root>
    </Loggers>
</Configuration>

有关信息,这是我正在使用的依赖项:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.14.1</version>
</dependency>

...这是我的 Spring 引导应用程序的父 pom:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
    <relativePath/>
</parent>

默认情况下 spring 将使用不同的日志记录机制“spring-boot-starter-logging”

如果你想让 log4j/log4j2 工作,那么你应该排除默认依赖并添加 log4j 相关依赖。由于您已经配置了该配置,我想排除默认配置就足够了。我通过在 pom.xml 文件

中添加排除子句来为我的“spring-boot-starter-web”项目这样做
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>