java日志框架

本文介绍了Java日志框架的重要性,详细阐述了SLF4J、Log4j和Logback的关系及用途。讨论了日志级别的概念,并在SpringBoot项目中展示了如何配置和使用Logback日志,包括日志配置文件的解析和日志输出策略。
摘要由CSDN通过智能技术生成

参考博客

NO.1 Spring Boot干货系列:(七)默认日志logback配置解析 【作者:嘟嘟MD】

NO.2 Java日志框架SLF4J和log4j以及logback的联系和区别

NO.3  SLF4J和Logback和Log4j和Logging的区别与联系

 

1. 为什么需要日志

  • 对于程序的运行状态进行监控和行为分析
  • 当程序运行出错时,快速定位问题的位置

2. 日志能做什么

  • 将日志消息打印到控制台、输出到文件等
  • 日志内容可以做格式化,如纯文本、XML、 HTML格式等
  • 对不同类、不同包、不同等级日志可以灵活输出到不同的文件中
  • 可以对日志进行分级,例如测试环境使用debug级别日志,生成环境使用error级别日志

3. 体系简单介绍

3.1 日志接口框架

常见日志接口框架有两个:

  • JCL(Jakarta Commons Logging),又叫做 Apache Commons Logging
  • SLF4J(Simple Logging Facade for JAVA)

日志接口框架只提供了供用户调用的接口,并没有给出具体实现

3.2 日志实现框架

  • JUL(java.util.logging):Java 内置的日志模块,能满足基本的日志需要
  • Log4j、Log4j2:经典的日志解决方式
  • Logback:Log4j的替代产品,出自同一个作者。须要配合日志框架SLF4j使用
  • slf4j-nop:no-operation
  • slf4j-simple:simple

3.3 日志接口框架和日志实现框架

其中,log4j和JUL(java.util.logging)因为没有直接实现slf4j接口框架,所以需要相应的适配器(slf4j-log12、slf4j-jdk14)来将slf4j接口框架和其进行绑定。而logback、slf4j-simple、slf4j-nop直接实现了slf4j接口框架,所以不需要适配器。

3.4 推荐使用 “日志接口框架+日志实现框架

在使用日志时,可以不配合日志接口框架而直接使用日志实现框架,但是并不建议这样使用。

假设项目中已经使用了log4j,而我们此时加载了一个类库,而这个类库依赖另一个日志实现框架。这个时候我们就需要维护两个日志实现框架,这是一个非常麻烦的事情。但是如果配合使用slf4j就不同了,由于应用调用的是日志接口方法,与底层日志实现是无关的,因此可以任意更换具体的日志实现框架。

4. 日志级别

日志级别从低到高分别是

ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF

级别简单介绍

  • ALL:最低等级。用于打开所有日志记录
  • TRACE:很低的日志级别,一般不会使用
  • DEBUG:通常用在本地调试或测试环境上,打印一些调试的信息
  • INFO:通常用在生产环境上,打印一些重要的监测信息
  • WARN:表明会出现潜在错误的情形,有些信息不是错误信息,但需要给出提示
  • ERROR:指出虽然发生错误事件,但仍然不影响系统的继续运行
  • FATAL:每个严重的错误事件将会导致应用程序的退出
  • OFF:最高等级的,用于关闭所有日志记录

大多数日志框架推荐常用的级别是,DEBUG、INFO、WARN、ERROR。

如果将log level设置在某一个级别上,那么比此级别优先级高的log都会打印出来,比此级别优先级低的log都不会打印出来。

5. springboot项目中使用logback日志

如何将日志加入到项目中?下面以在 springboot 项目中引入 logback 日志为例。

5.1 默认情况下

Spring框架使用的是Jakarta Commons Logging API (JCL)。

Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台(即,日志默认级别为INFO)。

5.2 日志信息介绍

  • 时间日期:精确到毫秒
  • 日志级别:ERROR, WARN, INFO, DEBUG、TRACE
  • 进程ID
  • 分隔符:--- 标识实际日志的开始
  • 线程名:方括号括起来(可能会截断控制台输出)
  • Logger名:通常使用源代码的类名
  • 实际日志内容

5.3 引入日志依赖

在 springboot 项目中,只要添加了 spring-boot-starter-logging 依赖,则应用将自动使用 logback 作为应用日志框架。

通过查看依赖可知,spring-boot-starter 已经包含了 spring-boot-starter-logging。而 spring-boot-start-web、mybatis-spring-boot-starter、spring-booter-start-jdbc 等都包含了 spring-boot-starter-logging,所以并不需要直接依赖 spring-boot-starter-logging。

5.4 在 application.properties 配置文件配置日志

假设项目所在目录为 D:\Projects\Test。

  • logging.file

该属性用来指定日志文件路径和文件名(路径可以是绝对路径,也可以是相对路径)。

logging.file=logs\\my.log
# 如果配置的是相对路径,则会在项目根目录生成指定日志文件
# D:\Projects\Test\logs\my.log

##############

logging.file=E:\\logs\\my.log
# 如果配置的是绝对路径,则生成指定日志文件
# E:\logs\my.log


# 如果logs目录不存在,则会自动创建该目录。
# 如果该目录下已存在同名文件,则会在原文件后继续追加当前日志内容。
  • logging.path

该属性用来指定日志文件路径,在指定路径下生成默认日志文件 spring.log(只能指定目录,不能指定文件名)。

logging.path=E:\\logs
# E:\logs\spring.log

# 如果logs目录不存在,则会自动创建该目录。
# 如果该目录下已存在spring.log,则会在原文件后继续追加当前日志内容。
  • 如果同时配置 logging.file 和 logging.path,则只有 logging.file 配置会生效。 

5.5 logback.xml 与 logback-spring.xml

  • 根据不同的日志系统,使用下面这些默认的命名规则,并且放在 src/main/resources 下面,日志文件就能被自动的加载。
> logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy

> log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml

> log4j2:log4j2-spring.xml, log4j2.xml

> JUL(java util logging):logging.properties
  • 如果不想使用上面的默认命名规则(比如,针对不同profile使用不同的日志配置名称进行区分),则可以在 spring 配置文件中使用 logging.config 属性指定自定义日志名称。
logging.config=classpath:logging-dev.xml
  • 使用 logback 日志时,推荐使用 logback-spring.xml 文件名代替 logback.xml 进行配置。因为 logback.xml 加载早于application.properties,则如果想要在 logback.xml 中使用 application.properties 配置文件中的变量就无法实现了,而改成 logback-spring.xml 就不会有这个问题了。

5.6 logback-spring.xml 配置文件示例

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>logback</contextName>

    <property name="logPath" value="E:/logs" />
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
   
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>debug</level>
        </filter>
        <encoder>
            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logPath}/info.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
            <totalSizeCap>5GB</totalSizeCap>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <logger name="org.apache.ibatis" level="info"/>
    <logger name="org.mybatis.spring" level="info"/>
    <logger name="com.baomidou.mybatisplus" level="info"/>

    <root level="info">
        <appender-ref ref="console" />
        <appender-ref ref="file" />
    </root>
</configuration>

 5.7 配置文件解析

5.7.1 <configuration>

配置文件的根节点

<configuration  scan="true" scanPeriod="60 seconds" debug="false">
  • scan:设置为true时,如果配置文件发生改变,将会被重新加载,默认值为true。
  • scanPeriod:监测配置文件是否有修改的监测时间间隔,如果没有给出时间单位,默认单位是毫秒。只有当scan为true时,此属性生效。默认的时间间隔为1分钟。
  • debug:设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。

5.7.2 <contextName>

上下文名称

<contextName>logback</contextName>

每个 logger 都关联到 logger 上下文,默认上下文名称为 “default”。可以设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改,可以通过 %contextName 来打印日志上下文名称。

5.7.3 <property>

定义变量

<property name="logPath" value="E:/logs" />
  • name:变量的名称
  • value:变量的值
  • 定义好的变量会保存到 logger 上下文中,可以使 ${varName} 来引用变量

5.7.4 <appender>

输出策略及其他配置

<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />

<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>debug</level>
    </filter>
    <encoder>
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>

<!-- 文件输出 -->
<appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${logPath}/info.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <fileNamePattern>${logPath}/info_%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
        <maxFileSize>100MB</maxFileSize>
        <maxHistory>60</maxHistory>
        <totalSizeCap>5GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

解析


<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
  • name:节点名称,通过该值可以引用该节点的配置(后面再说)
  • class:指定日志的输出策略,控制台输出(ch.qos.logback.core.ConsoleAppender),文件输出(ch.qos.logback.core.rolling.RollingFileAppender)

 

<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    <level>debug</level>
</filter>
  • filter.class:系统定义的拦截器(ch.qos.logback.classic.filter.ThresholdFilter)
  • level:设置过滤级别。如果设置为 debug,则比 debug 级别低的(不包括debug级别)日志都不会打印到控制台上(或输出到日志文件中)。

 

<encoder>
    <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
    <charset>UTF-8</charset>
</encoder>

可以直接指定日志格式,日志格式解析如下:

  • %d{HH: mm:ss.SSS} —— 日志输出时间
  • %contextName —— 日志上下文名称
  • %thread —— 输出日志的进程名字,这在Web应用以及异步任务处理中很有用
  • %-5level —— 日志级别,并且使用5个字符靠左对齐
  • %logger{36} —— 日志输出者的名字
  • %msg —— 日志消息
  • %n —— 平台的换行符

示例

也可以设置彩色日志格式,但彩色日志格式要引入渲染类的依赖:

<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>

<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />

<encoder>
    <pattern>${CONSOLE_LOG_PATTERN}</pattern>
    <charset>UTF-8</charset>
</encoder>

示例

彩色日志格式建议只用于控制台日志输出,因为如果在文件日志输出中采用彩色日志,会出现乱码。


 

<file>${logPath}/info.log</file>
<!-- 或 -->
<file>E:/logs/info.log</file>

指定日志文件位置,在文件输出策略中进行该配置。


 

<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    <fileNamePattern>${logPath}/info_%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
    <maxFileSize>100MB</maxFileSize>
    <maxHistory>60</maxHistory>
    <totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>

日志记录器的滚动策略。随着应用的运行时间越来越长,日志也会增长的越来越多,将他们输出到同一个文件并不合理。

  • fileNamePattern:定义了日志的切分方式。如上述配置,把每一天的日志归档到一个文件中,当一个文件大小到了100M,就生成一个新的文件,后缀加1。
  • maxFileSize:每个日志文件的上限大小。如上述配置,到了100M就生成一个新的日志文件
  • maxHistory:保留最近60天的日志
  • totalSizeCap:总日志文件大小上限,到了上限就删除旧的日志文件

示例

5.7.5 <root>

<root level="INFO">
    <appender-ref ref="console"/>
    <appender-ref ref="file"/>
</root>

root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性。

  • level:设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。默认是DEBUG。
  • appender-ref:引入 appender 节点配置,ref 指定 <appender> 的 name 属性值

5.7.6 <logger>

<logger name="org.apache.ibatis" level="info"/>
<logger name="org.mybatis.spring" level="info"/>
<logger name="com.baomidou.mybatisplus" level="info"/>

用来设置某一个包或者具体的某一个类的日志打印级别。

  • name:指定受此 logger 约束的某一个包或者具体的某一个类
  • level:设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特殊值 INHERITED或者同义词 NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。
  • addtivity:是否向上级 logger 传递打印信息,默认是true。

5.7.7 <springProfile>

据不同环境(profile)来定义不同的日志输出。

<!-- 测试环境+开发环境. 多个使用逗号隔开. -->
<springProfile name="test,dev">
    <logger name="com.test.controller" level="info" />
</springProfile>

<!-- 生产环境. -->
<springProfile name="prd">
    <logger name="com.test.controller" level="error" />
</springProfile>

因为前面说过,要使用 spring 配置文件中的变量值(例如:当前环境变量profile),需要定义日志文件名为 logback-spring.xml 而不是 logback.xml。所以,要使用这个配置,需要定义日志文件名为 logback-spring.xml。

5.8 使用日志

方式一(LoggerFactory):

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Test{
    private static final Logger log = LoggerFactory.getLogger(Test.class); 

    public void test(){
        log.trace("===================trace=============");
        log.debug("===================debug=============");
        log.info("===================info=============");
        log.warn("===================warn=============");
        log.error("===================error=============");
    }
}

方式二(使用lombox注解):

引入lomobx 的 maven依赖

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.10</version>
</dependency>

使用注解

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Test{
    
    public void test(){
        log.trace("===================trace=============");
        log.debug("===================debug=============");
        log.info("===================info=============");
        log.warn("===================warn=============");
        log.error("===================error=============");
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值