Skip to content

日志框架集成配置

Java 日志框架用于记录应用程序运行时的信息,帮助开发人员调试和监控应用。以下是几种常用的 Java 日志框架:

  • Log4j 特点:由 Apache 开发,功能强大且灵活,支持多种输出方式(如文件、控制台、数据库等)。 配置:通过 XML 或属性文件进行配置,易于管理和调整。 版本:目前有 Log4j 1.x 和 Log4j 2.x 两个主要版本,推荐使用 Log4j 2.x,因为其性能更好,且修复了 Log4j 1.x 中的一些安全问题。
  • SLF4J (Simple Logging Facade for Java) 特点:不是一个具体的日志实现,而是一个抽象层,允许在部署时选择实际的日志框架(如 Logback, Log4j 等)。 优势:提供了一种统一的日志接口,减少了因更换日志框架而导致的代码修改。
  • Logback 特点:由 SLF4J 的创始人设计,是 SLF4J 的原生实现。 性能:相比其他日志框架,Logback 在性能上具有优势。 配置:支持 XML 配置文件,提供了丰富的配置选项。
  • java.util.logging (JUL) 特点:Java 标准库自带的日志框架,无需额外依赖。 简单:适合小型项目或对日志需求不高的场景。 局限性:相对于其他框架,功能较为简单,配置不够灵活。
  • Commons Logging 特点:Apache 提供的一个日志抽象层,类似于 SLF4J。 兼容性:可以与多种日志框架(如 Log4j, JUL 等)集成。 局限性:在某些情况下可能会导致类加载问题。
  • 选择建议 对于新项目:推荐使用 SLF4J + Logback 组合,既灵活又高效。 对于已有项目:如果已经在使用 Log4j 1.x,建议升级到 Log4j 2.x 或迁移到 Logback。 对于简单需求:可以直接使用 java.util.logging,避免引入额外依赖。

log4j/log4j2 集成SpringBoot

log4j不再介绍,详细查阅官方文档。log4j2 具有优越的性能,以SpringBoot整合为例,参考 SpringBoot整合log4j2进行日志配置及防坑指南

img

1.导入依赖

xml
<!-- 排除 Spring-boot-starter 默认的日志配置 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <!-- 注意:去掉springboot默认配置,若项目只依赖的spring-boot-starter-web,用下面这句即可。
    <artifactId>spring-boot-starter-web</artifactId>
     --> 
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- 引入log4j2依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

2.log4j2配置文件

yaml
logging:
  config: classpath:log4j2.xml # 线上环境可以指定配置文件

如果定义的配置文件名为:log4j2-spring.xml,此时则不需要再添加上面的配置

生产环境可以创建配置文件在启动参数中指定线上配置。

shell
# 此处时区参数不加就需要在log4j2.xml中添加,否则日志时间不准确。
JVM_ARGS="-Dfile.encoding=utf-8 -Duser.timezone=Asia/Shanghai"
APP_ARGS="--spring.config.location=./conf/application.yaml,./conf/app-xxx.yaml"

nohup java -jar ${JVM_ARGS} xxx-*.jar ${APP_ARGS}

推荐在项目运行目录中创建conf目录,将配置文件放置在下面,目录结构如下:

shell
.
├── conf
│   ├── application.yaml   #配置config.config: conf/log4j2.xml
│   └── log4j2.xml
├── xxx-1.0-release.jar
├── logs
│   ├── app.log
│   └── error.log
└── run.sh

3.配置log4j2.xml日志

参考示例如下,更加需要删减。

xml
<?xml version="1.0" encoding="UTF-8"?>
<!--      Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,
     当设置成trace时,可以看到log4j2内部各种详细输出
-->
<!-- monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数 -->
<configuration monitorInterval="5">
    <!-- 日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->

    <!-- 变量配置 -->
    <Properties>
        <!--
            格式化输出:
            %d表示日期,注意时区参数{Asia/Shanghai},不提供日志时间可能存在异常。
            %thread表示线程名,
            %-5level:级别从左显示5个字符宽度
            %msg:日志消息,%n是换行符
            %logger{50} 表示 Logger 名字最长50个字符
        -->
        <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS}{Asia/Shanghai} %highlight{%-5level}[%thread] %style{%logger{50}}{cyan} : %msg%n" />

        <!-- 定义日志存储的路径,不要配置相对路径 -->
        <property name="FILE_PATH" value="此处更换为你的日志文件存储路径" />
        <property name="FILE_NAME" value="此处更换为你的项目名称" />
    </Properties>

    <appenders>
        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}" disableAnsi="false" noConsoleNoAnsi="false"/>
            <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
        </console>

        <!--
          这个会打印出所有的info及以下级别的信息,每次大小超过size,
          则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档
        -->
        <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖 -->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>

        <!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval属性用来指定多久滚动一次,默认是1 hour-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="20MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
            <DefaultRolloverStrategy max="15"/>
        </RollingFile>
    </appenders>

    <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
    <!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.mybatis" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </logger>
        <!--监控系统信息-->
        <!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
        <Logger name="org.springframework" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>

        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
        </root>
    </loggers>
</configuration>

Logback 集成与配置

在 Spring Boot 应用中配置 Logback 是非常常见的做法。Spring Boot 默认已经包含了 Logback 作为日志框架,因此通常不需要显式添加依赖。

1.添加依赖

xml
<!-- 如果需要显式添加 Logback 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>

2.配置 Logback

在 src/main/resources 目录下创建或修改 logback-spring.xml 文件。这个文件会覆盖默认的 Logback 配置,并且会被 Spring Boot 自动识别。若名称不是默认只添加配置

yaml
logging:
  config: classpath:logback.xml # 线上环境可以指定配置文件

3.配置日志规则

参考示例

xml
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>logs/app.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>

    <logger name="com.example" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </logger>
</configuration>
最近更新