Springboot配置log4j2爬坑

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Version Springboot 2.11.1 logging.config参数 logging.config 配置在application.yml中有效,指定路径有效 log4j2 log4j2官网支持多种自动配置方式,自动扫描: 系统属性(Log4j.

Version Springboot 2.11.1

logging.config参数

logging.config 配置在application.yml中有效,指定路径有效

log4j2

log4j2官网支持多种自动配置方式,自动扫描:

系统属性(Log4j.configuration) -> classpath中的(log4j2-test.properties)
-> classpath中的(log4j2-test.yml/yaml/json/jsn/xml)
-> classpath中的(log4j2.yml/yaml/json/jsn/xml) -> 默认配置

Log4j获取ConfigurationFactory
// 按照测试前缀log4j2-test 和 LoggerContext上下文实例获取ConfigurationFactory
Configuration config = getConfiguration(loggerContext, true, name);
if (config == null) {
    // 按照测试前缀log4j2-test 获取ConfigurationFactory
    config = getConfiguration(loggerContext, true, null);
    if (config == null) {
        // 按照前缀log4j2 和LoggerContext上下文实例获取ConfigurationFactory
        config = getConfiguration(loggerContext, false, name);
        if (config == null) {
            // 按照前缀log4j2 获取ConfigurationFactory
            // Springboot 加载Log4j2的工厂实例在这里获取,指向Springboot包log4j2.springboot中的SpringBootConfigurationFactory
            config = getConfiguration(loggerContext, false, null);
        }
    }
}
log4j2

核心代码如下:


String ALL_TYPES = "*";
for (final ConfigurationFactory factory : getFactories()) {
    final String[] types = factory.getSupportedTypes();
    if (types != null) {
        for (final String type : types) {
            // 只有 XmlConfigurationFactory 符合条件
            if (type.equals(ALL_TYPES)) {
                final Configuration config = factory.getConfiguration(loggerContext, name, configLocation);
                if (config != null) {
                    return config;
                }
            }
        }
    }
}
springboot logging

springboot使用Common logging组件加载日志模块,提供了Java Util、Log4J2和Logback日志的默认配置,预先配置了控制台输出,还提供可选的文件输出。

springboot默认日志配置文件

Logging System Customization
Logback logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties
Springboot log4j2配置工厂

log4j2 加载log4j-core中的ConfigurationFactory继承类,排序如下:

  • PropertiesConfigurationFactory
  • YamlConfigurationFactory
  • JsonConfigurationFactory
  • XmlConfigurationFactory
  • SpringBootConfigurationFactory (匹配.springboot)

springboot 中修改了log4j2.xml的名称后不生效

log4j2.xml文件修改名称为log4j2_dev.xml同时在appliaction_dev.yml配置文件中指定了logging.config路径,但是结果还是走spring默认配置。(不生效原因是,应该为appliaction-dev.yml)

原因解释
  1. springboot log4j2读取顺序:logging.config —> classpath(log4j2-spring.xml or log4j2.xml) —> spring-boot包下的logging.log4j.log4j2.xml
  2. springBoot项目中默认有一份日志配置文件,项目启动时先读取到了默认日志配置文件,没有读取resource目录中的配置文件,需要自定义日志信息的话需要在Springboot配置文件中指定读取自定义的配置文件
不能读取Yml配置原因
  1. 在Log4J2装载时,会检查jackson中的ObjectMapper、JsonNode、JsonParser和YAMLFactory,装载YAMLFactory会失败,所以无法解析yml配置的yml文件,导致失败
public class YamlConfigurationFactory extends ConfigurationFactory {

    /**
     * The file extensions supported by this factory.
     */
    private static final String[] SUFFIXES = new String[] {".yml", ".yaml"};

    private static final String[] dependencies = new String[] {
            "com.fasterxml.jackson.databind.ObjectMapper",
            "com.fasterxml.jackson.databind.JsonNode",
            "com.fasterxml.jackson.core.JsonParser",
            "com.fasterxml.jackson.dataformat.yaml.YAMLFactory"
    };

    private final boolean isActive;

    public YamlConfigurationFactory() {
        for (final String dependency : dependencies) {
            if (!Loader.isClassAvailable(dependency)) {
                LOGGER.debug("Missing dependencies for Yaml support, ConfigurationFactory {} is inactive", getClass().getName());
                isActive = false;
                return;
            }
        }
        isActive = true;
    }
测试过程中

将logging.config配置写入application.yml中发现可以读取配置位置


public class LoggingApplicationListener{
    // logFile 指定日志文件输出位置
    private void initializeSystem(ConfigurableEnvironment environment,
                LoggingSystem system, LogFile logFile) {
            LoggingInitializationContext initializationContext = new LoggingInitializationContext(
                    environment);
            // 可以读取到配置
            String logConfig = environment.getProperty(CONFIG_PROPERTY);
            if (ignoreLogConfig(logConfig)) {
                system.initialize(initializationContext, null, logFile);
            }
            ...
        }
}
Spring支持Log4j2默认配置的代码
public abstract class AbstractLoggingSystem extends LoggingSystem {
    // Log4j 初始化
    public void initialize(LoggingInitializationContext initializationContext,
            String configLocation, LogFile logFile) {
        if (StringUtils.hasLength(configLocation)) {
            
            initializeWithSpecificConfig(initializationContext, configLocation, logFile);
            return;
        }
        // 无配置,调用默认配置
        initializeWithConventions(initializationContext, logFile);
    }



    private String[] getCurrentlySupportedConfigLocations() {
        List<String> supportedConfigLocations = new ArrayList<>();
        if (isClassAvailable("com.fasterxml.jackson.dataformat.yaml.YAMLParser")) {
            Collections.addAll(supportedConfigLocations, "log4j2.yaml", "log4j2.yml");
        }
        if (isClassAvailable("com.fasterxml.jackson.databind.ObjectMapper")) {
            Collections.addAll(supportedConfigLocations, "log4j2.json", "log4j2.jsn");
        }
        supportedConfigLocations.add("log4j2.xml");
        return StringUtils.toStringArray(supportedConfigLocations);
    }
    
    protected String[] getSpringConfigLocations() {
        String[] locations = getStandardConfigLocations();
        for (int i = 0; i < locations.length; i++) {
            String extension = StringUtils.getFilenameExtension(locations[i]);
            locations[i] = locations[i].substring(0,
                    locations[i].length() - extension.length() - 1) + "-spring."
                    + extension;
        }
        return locations;
    }
}
Spring最终配置文件位置

Spring通过默认配置查找,classpath路径下的配置文件,如果没有找到,就会加载spring-boot包下的logging.log4j.log4j2.xml,如果配置了日志输出位置,则为log4j2-file.xml

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
22天前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
166 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
19天前
|
Java 中间件
SpringBoot入门(6)- 添加Logback日志
SpringBoot入门(6)- 添加Logback日志
64 5
|
15天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
36 0
|
2月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
38 0
|
1天前
|
存储 Prometheus 监控
Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行
本文深入探讨了在Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行。
13 5
|
19天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
29 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
9天前
|
存储 前端开发 JavaScript
springboot中路径默认配置与重定向/转发所存在的域对象
Spring Boot 提供了简便的路径默认配置和强大的重定向/转发机制,通过合理使用这些功能,可以实现灵活的请求处理和数据传递。理解并掌握不同域对象的生命周期和使用场景,是构建高效、健壮 Web 应用的关键。通过上述详细介绍和示例,相信读者能够更好地应用这些知识,优化自己的 Spring Boot 应用。
22 3
|
11天前
|
Java 中间件
SpringBoot入门(6)- 添加Logback日志
SpringBoot入门(6)- 添加Logback日志
22 1
|
18天前
|
Java 数据库连接
SpringBoot配置多数据源实战
第四届光学与机器视觉国际学术会议(ICOMV 2025) 2025 4th International Conference on Optics and Machine Vision
46 8
|
15天前
|
Java 数据库连接 数据库
springboot启动配置文件-bootstrap.yml常用基本配置
以上是一些常用的基本配置项,在实际应用中可能会根据需求有所变化。通过合理配置 `bootstrap.yml`文件,可以确保应用程序在启动阶段加载正确的配置,并顺利启动运行。
34 2