java日志体系

Java 中的日志体系

Java 中的日志框架主要分为两大类:日志门面和日志实现
在这里插入图片描述

  • 日志门面
    日志门面定义了一组日志的接口规范,它并不提供底层具体的实现逻辑。Apache Commons Logging 和 Slf4j 就属于这一类

  • 日志实现
    日志实现则是日志具体的实现,包括日志级别控制、日志打印格式、日志输出形式(输出到数据库、输出到文件、输出到控制台等)。Log4j、Log4j2、Logback 以及 Java Util Logging 则属于这一类

将日志门面和日志实现分离其实是一种典型的门面模式,这种方式可以让具体业务在不同的日志实现框架之间自由切换,而不需要改动任何代码,开发者只需要掌握日志门面的 API 即可

日志级别

Java Util Logging
Java Util Logging 定义了 7 个日志级别,从严重到普通依次是:

  • SEVERE
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST
    因为默认级别是 INFO,因此 INFO 级别以下的日志,不会被打印出来

Log4j
Log4j 定义了 8 个日志级别(除去 OFF 和 ALL,可以说分为 6 个级别),从严重到普通依次是:

  • OFF:最高等级的,用于关闭所有日志记录。
  • FATAL:重大错误,这种级别可以直接停止程序了。
  • ERROR:打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。
  • WARN:警告提示。
  • INFO:用于生产环境中输出程序运行的一些重要信息,不能滥用。
  • DEBUG:用于开发过程中打印一些运行信息。
  • TRACE
  • ALL 最低等级的,用于打开所有日志记录

Logback

Logback 日志级别比较简单,从严重到普通依次是:

  • ERROR
  • WARN
  • INFO
  • DEBUG
  • TRACE

最佳实践

  • 如果不想添加任何依赖,使用 Java Util Logging 或框架容器已经提供的日志接口
  • 如果比较在意性能,推荐:Slf4j + Logback
  • 如果项目中已经使用了 Log4j 且没有发现性能问题,推荐组合为:Slf4j + Log4j2

Spring Boot 日志实现

Spring Boot 使用 Apache Commons Logging 作为内部的日志框架门面,它只是一个日志接口,在实际应用中需要为该接口来指定相应的日志实现。

Spring Boot 默认的日志实现是 Logback。这个很好查看:随便启动一个 Spring Boot 项目,从控制台找一行日志,例如下面这样:
在这里插入图片描述
在日志输出的那一行打上断点然后再次启动项目,如下图:
在这里插入图片描述
此时我们就可以看到真正的日志实现是 Logback
在这里插入图片描述
在 Spring Boot 项目中,只要添加了如下 web 依赖,日志依赖就自动添加进来了:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

在这里插入图片描述

Spring Boot 日志配置

Spring Boot 的日志系统会自动根据 classpath 下的内容选择合适的日志配置,在这个过程中首选 Logback

修改日志级别,只需要在 application.properties 文件中通过 logging.level 前缀+包名 的形式进行配置即可:

logging.level.org.springframework.web=debug

将日志输出到文件,可以通过如下配置指定日志文件名:

logging.file.name=dong.log

logging.file.name 可以只指定日志文件名,也可以指定日志文件全路径:

logging.file.name=/Users/dong/file/dong/LQZ.log

重新定义输出日志文件的路径,也可以使用 logging.file.path 属性

logging.file.path=/Users/sang/dong/file/dong

对输出到文件中的日志进行精细化管理,还有如下一些属性可以配置:

logging.logback.rollingpolicy.file-name-pattern:日志归档的文件名,日志文件达到一定大小之后,自动进行压缩归档。
logging.logback.rollingpolicy.clean-history-on-start:是否在应用启动时进行归档管理。
logging.logback.rollingpolicy.max-file-size:日志文件大小上限,达到该上限后,会自动压缩。
logging.logback.rollingpolicy.total-size-cap:日志文件被删除之前,可以容纳的最大大小。
logging.logback.rollingpolicy.max-history:日志文件保存的天数

日志文件归档

logging.logback.rollingpolicy.max-file-size=1MB

编写测试类:

import static org.slf4j.LoggerFactory.getLogger;
@RestController
public class HelloController {
    private static final Logger logger = getLogger(HelloController.class);
    @GetMapping("/hello")
    public void hello() {
        for (int i = 0; i < 100000; i++) {
            logger.info("hello dong");
        }
    }
}

访问该接口,可以看到最终生成的日志文件被自动压缩
在这里插入图片描述

application.properties 配置日志分组

日志分组能够把相关的 logger 放到一个组统一管理

例如定义一个 tomcat 组:

logging.group.tomcat=org.apache.catalina,org.apache.coyote, org.apache.tomcat

统一管理 tomcat 组中的所有 logger:

logging.level.tomcat=TRACE

Spring Boot 中还预定义了两个日志分组 web 和 sql,如下:
在这里插入图片描述

Logback 配置

默认的 Logback 配置文件名有两种:

  • logback.xml:这种配置文件会直接被日志框架加载
  • logback-spring.xml:这种配置文件不会被日志框架直接加载,而是由 Spring Boot 去解析日志配置,可以使用 Spring Boot 的高级 Profile 功能

Spring Boot 中为 Logback 提供了四个默认的配置文件,位置在org/springframework/boot/logging/logback/,分别是:

  • defaults.xml:提供了公共的日志配置,日志输出规则等
  • console-appender.xml:使用 CONSOLE_LOG_PATTERN 添加一个- ConsoleAppender
  • file-appender.xml:添加一个 RollingFileAppender
  • base.xml:为了兼容旧版 Spring Boot 而提供的

一个典型的 logback.xml 文件如下(resources/logback.xml):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
    <logger name="org.springframework.web" level="DEBUG"/>
</configuration>

如果想禁止控制台的日志输出,转而将日志内容输出到一个文件,我们可以自定义一个 logback-spring.xml 文件,并引入前面所说的 file-appender.xml 文件
resources/logback-spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
    <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
    <root level="INFO">
        <appender-ref ref="FILE" />
    </root>
</configuration>

Log4j 配置

如果 classpath 下存在 Log4j2 的依赖,Spring Boot 会自动进行配置

默认情况下 classpath 下当然不存在 Log4j2 的依赖,如果想使用 Log4j2,可以排除已有的 Logback,然后再引入 Log4j2,如下:

<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>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Log4j2 的配置就比较容易了,在 reources 目录下新建 log4j2.xml 文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="warn">
    <properties>
        <Property name="app_name">logging</Property>
        <Property name="log_path">logs/${app_name}</Property>
    </properties>
    <appenders>
        <console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%d][%t][%p][%l] %m%n" />
        </console>
        <RollingFile name="RollingFileInfo" fileName="${log_path}/info.log"
                     filePattern="${log_path}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <ThresholdFilter level="INFO" />
                <ThresholdFilter level="WARN" onMatch="DENY"
                                 onMismatch="NEUTRAL" />
            </Filters>
            <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" />
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
                <SizeBasedTriggeringPolicy size="2 MB" />
            </Policies>
            <DefaultRolloverStrategy compressionLevel="0" max="10"/>
        </RollingFile>
        <RollingFile name="RollingFileWarn" fileName="${log_path}/warn.log"
                     filePattern="${log_path}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz">
            <Filters>
                <ThresholdFilter level="WARN" />
                <ThresholdFilter level="ERROR" onMatch="DENY"
                                 onMismatch="NEUTRAL" />
            </Filters>
            <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" />
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
                <SizeBasedTriggeringPolicy size="2 MB" />
            </Policies>
            <DefaultRolloverStrategy compressionLevel="0" max="10"/>
        </RollingFile>

        <RollingFile name="RollingFileError" fileName="${log_path}/error.log"
                     filePattern="${log_path}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz">
            <ThresholdFilter level="ERROR" />
            <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" />
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
                <SizeBasedTriggeringPolicy size="2 MB" />
            </Policies>
            <DefaultRolloverStrategy compressionLevel="0" max="10"/>
        </RollingFile>
    </appenders>
    <loggers>
        <root level="info">
            <appender-ref ref="Console" />
            <appender-ref ref="RollingFileInfo" />
            <appender-ref ref="RollingFileWarn" />
            <appender-ref ref="RollingFileError" />
        </root>
    </loggers>
</configuration>

首先在 properties 节点中指定了应用名称以及日志文件位置
然后通过几个不同的 RollingFile 对不同级别的日志分别处理,不同级别的日志将输出到不同的文件,并按照各自的命名方式进行压缩

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值