Java日志(五):lockback实践

本文介绍了如何使用logback进行日志打印,包括配置logback.xml,理解日志级别,以及如何按天和文件大小滚动日志文件。还详细讲解了日志级别的有效性以及如何通过过滤器控制不同级别的日志输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、先打印几行日志试试

创建web project,引入jar包:
logback-classic-1.2.3.jar,logback-core-1.2.3.jar,slf4j-api-1.7.25.jar
在classpath路径下创建logback.xml配置文件,启动后logback默认自动读取:
logback.xml文件在classpath下
logback.xml配置文件的简单配置内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- logback默认开启每60秒扫描加载logback.xml配置文件的变化,下面做了修改 -->
<configuration debug="false" scan="true" scanPeriod="30 seconds">
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level : %msg%n%caller{1}</pattern>
        </encoder>
    </appender>

    <!-- 把STDOUT添加到root Logger -->
    <root>
        <level value="info" />
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

上面配置内容解析:
(1)<configuration>标签是整个配置文件的根标签
(2)可以配置多个<appender>日志输出位置,每个appender内部可以配置一个<encoder>,encoder的class属性不写默认就是PatternLayoutEncoder,encoder内部可以配置一个<pattern>,pattern用于规定日志的格式。
(3)pattern格式:具体可以参考logback的PatternLayout 参数解析
简单说下,一般是appender包含encoder包含layout包含pattern,由于PatternLayout太过常用,所以直接提供个PatternLayoutEncoder,这个encoder内部已经封装了layout,所以它可以直接装配pattern。

下面是使用slf4j的API通过logback打印日志:

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

public class LogbackTest {
    private static Logger logger = LoggerFactory.getLogger(LogbackTest.class);

    public void infoMethod() {
        logger.info("this is a info message");
    }
    public void errorMethod() {
        try {
            int i=0;
            i=1/i;
        } catch (Exception e) {
            logger.error("attention, error!",e);
        }
    }
}

输出结果如下:

2019-03-31 15:50:41 INFO  : this is a info message
Caller+0	 at com.lwr.LogbackTest.infoMethod(LogbackTest.java:10)
2019-03-31 15:50:41 INFO  : this is a info message
Caller+0	 at com.lwr.LogbackTest.infoMethod(LogbackTest.java:10)
2019-03-31 15:50:41 ERROR : attention, error!
Caller+0	 at com.lwr.LogbackTest.errorMethod(LogbackTest.java:17)
java.lang.ArithmeticException: / by zero
	at com.lwr.LogbackTest.errorMethod(LogbackTest.java:15)
	at com.lwr.TestServlet.doGet(TestServlet.java:22)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
。。。

二、logback的日志级别

1、logback会根据包的路径依次创建logger对象,整个路径下来形成一条logger父子链。
比如创建logger1(com.lwr.Test)的同时会创建logger2(com.lwr)和logger3(com),同时logger3是logger2的父logger,logger2是logger1的父logger,以此递推,而logger(root)是最顶层的logger也就是logger3的父logger。
2、logger的有效级别。比如有三个logger(和级别):爷爷com.logger(warn)>父com.lwr.logger(debug)>子com.lwr.Test.logger(无),那么“子logger”的有效级别是依次往上找到的第一logger级别,也就是父logger的debug级别,低于该级别的日志将无法通过“子logger”打印出来。而爷爷logger的warn级别传递到父logger就被置换了,只影响自己的级别。
3、控制日志打印级别
(1)根据package包路径控制哪个包路径下的所有logger打印什么级别以上的日志:
在logback.xml文件的<configuration>标签下添加<logger>标签:

<!-- com.lwr包路径下的所有logger打印的信息都是warn级别以上 -->
<!-- 除非com.lwr包路径下的路径又设置了自己的级别,或者logger设置了自己的级别 -->
    <logger name="com.lwr" level="warn"/>

(2)在(1)中,限定死了warn以下日志都不会打印。实际上更加常用的是根据输出位置来决定日志打印的级别,比如控制台可以打印info级别,而error.log只需要error级别的日志,而不管error日志来自于哪个类。
所以,通常把级别的控制权给到输出目的地appender,在logback中可以通过给appender添加一个过滤器Filter,专门用于级别的判断过滤。级别过滤器又主要分两种:
第一种,门槛级别过滤器ThresholdFilter,如下:

<appender>
        <!-- 只要日志级别高于等于门槛级别,此过滤器就放行 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>info</level>
        </filter>
        ...
</appender>

源码判断过程如下:

    public FilterReply decide(ILoggingEvent event) {
    //
        if (event.getLevel().isGreaterOrEqual(level)) {
            return FilterReply.NEUTRAL;//NEUTRAL表示走下一个过滤器,如果没有则最终通行了
        } else {
            return FilterReply.DENY;//如果下面还有过滤器也不再判断,直接不通行
        }
    }

第二种,相应等级级别过滤器LevelFilter,xml中配置如下:

<appender>
        <!-- 当日志级别等于设定的level,返回onMatch,否则返回onMismatch -->
        <!-- onMatch也可以设定为DENY拒绝;match结果可以对应以下三个动作之一:
         accept:整个过滤链不再向下走,直接返回通过操作
         deny:整个过滤链不再向下走,直接返回不通过操作
         neutral:不返回操作,继续沿过滤链走下一个过滤器-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        ...
</appender>

源码判断过程如下:

    public FilterReply decide(ILoggingEvent event) {
    //
        if (event.getLevel().equals(level)) {
            return onMatch;
        } else {
            return onMismatch;
        }
    }

LevelFilter可以指定比如我只要warn级别的日志。

三、按天以及按文件大小的策略滚动日志文件

logback支持按时间段(月、天、小时等)分割日志文件,同时支持按每个文件大小来分割日志文件。
1、按天生成日志文件
logback.xml配置文件加上一个输出到file的appender,通过include标签包含进来:
logback.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="5 seconds">
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level : %msg%n%caller{1}</pattern>
        </encoder>
    </appender>

    <!-- 引入输出到文件的appender-->
    <include resource="timeBasedFileAppender.xml"/>
    <!-- 日志输出级别 -->
    <root>
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

timeBasedFileAppender.xml:

<included>
    <!-- 按照每天生成日志文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 文件存放在tomcat/logs目录中 -->
        <file>${CATALINA_BASE}\logs\console.log</file>
        <!-- TimeBasedRollingPolicy是按时间生成日志文件策略的类 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- yyyy-MM-dd格式表示按天滚动日志文件 -->
            <FileNamePattern>${CATALINA_BASE}\logs\console.%d{yyyy-MM-dd}.log</FileNamePattern>
            <!-- 保存30份日志文件 -->
            <maxHistory>30</maxHistory>
            <!-- 总日志文件大小不超过3GB -->
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level : %msg%n%caller{1}</pattern>
        </encoder>
    </appender>
</included>

根据上面配置之后,调用打印日志方法后,会在tomcat/logs目录中生成每天的console.log日志文件并保存日志信息。

2、按文件大小分割日志文件

把logback.xml中的<include resource="timeBasedFileAppender.xml"/>改为<include resource="sizeBasedFileAppender.xml"/>

sizeBasedFileAppender.xml内容如下:

<included>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${CATALINA_BASE}\logs\console.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>${CATALINA_BASE}\logs\console%i.log</fileNamePattern>
            <!-- %i参数的取值从1到3,表示只保存3份历史日志文件 -->
            <minIndex>1</minIndex>
            <maxIndex>3</maxIndex>
        </rollingPolicy>

        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <!-- 因为测试,每个文件10KB大小 -->
            <maxFileSize>10KB</maxFileSize>
        </triggeringPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level : %msg%n%caller{1}</pattern>
        </encoder>
    </appender>
</included>

最终只有三份历史日志文件和一份当前的日志文件:日志文件列表

3、按时间和大小一起来分割日志文件
在logback.xml文件中有如下配置:

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- SizeAndTimeBasedRollingPolicy是同时结合时间和文件大小来滚动的策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--注意!!标注aux的%d参数只做使用,与按天滚动策略无任何关系,这里按天分目录保存-->
            <FileNamePattern>${CATALINA_BASE}\logs\%d{yyyy-MM-dd, aux}\console.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <maxFileSize>10KB</maxFileSize>
            <!--貌似是保存近4天的日志文件-->
            <maxHistory>4</maxHistory>
            <!--所有文件总共2GB封顶-->
            <totalSizeCap>2GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level : %msg%n%caller{1}</pattern>
        </encoder>
    </appender>

启动之后,自动按天,同时按文件大小分割日志文件,注意到\logs%d{yyyy-MM-dd, aux}代表每天生成一个目录存放当天的所有日志文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值