Java⽇志(五):lockback实践
⼀、先打印⼏⾏⽇志试试
创建web project,引⼊jar包:
在classpath路径下创建l配置⽂件,启动后logback默认⾃动读取:
<?xml version="1.0" encoding="UTF-8"?>
<!-- logback默认开启每60秒扫描加载l配置⽂件的变化,下⾯做了修改 -->
<configuration debug="false" scan="true" scanPeriod="30 seconds">
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.ConsoleAppender">
<encoder class="ch.qos.der.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格式:具体可以参考
简单说下,⼀般是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 = Logger(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) {
<("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.Method(LogbackTest.java:17)
java.lang.ArithmeticException: / by zero
at com.Method(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打印什么级别以上的⽇志:
在l⽂件的<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 (Level().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 (Level().equals(level)) {
return onMatch;
} else {
return onMismatch;
}
}
LevelFilter可以指定⽐如我只要warn级别的⽇志。
三、按天以及按⽂件⼤⼩的策略滚动⽇志⽂件
logback⽀持按时间段(⽉、天、⼩时等)分割⽇志⽂件,同时⽀持按每个⽂件⼤⼩来分割⽇志⽂件。
1、按天⽣成⽇志⽂件
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="5 seconds">
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.ConsoleAppender">
<encoder class="ch.qos.der.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="l"/>
<!-- ⽇志输出级别 -->
<root>
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
<included>
<!-- 按照每天⽣成⽇志⽂件 -->
<appender name="FILE" class="ch.olling.RollingFileAppender">
<!-- ⽂件存放在tomcat/logs⽬录中 -->
<file>${CATALINA_BASE}\logs\console.log</file>
<!-- TimeBasedRollingPolicy是按时间⽣成⽇志⽂件策略的类 -->
<rollingPolicy class="ch.olling.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.der.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level : %msg%n%caller{1}</pattern>
</encoder>
</appender>
</included>
根据上⾯配置之后,调⽤打印⽇志⽅法后,会在tomcat/logs⽬录中⽣成每天的console.log⽇志⽂件并保存⽇志信息。
2、按⽂件⼤⼩分割⽇志⽂件
把l中的<include resource="l"/>改为<include resource="l"/> l内容如下:
<included>
<appender name="FILE" class="ch.olling.RollingFileAppender">
<file>${CATALINA_BASE}\logs\console.log</file>
<rollingPolicy class="ch.olling.FixedWindowRollingPolicy">
<fileNamePattern>${CATALINA_BASE}\logs\console%i.log</fileNamePattern>
<!-- %i参数的取值从1到3,表⽰只保存3份历史⽇志⽂件 -->
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.olling.SizeBasedTriggeringPolicy">
<!-- 因为测试,每个⽂件10KB⼤⼩ -->
java xml是什么
<maxFileSize>10KB</maxFileSize>
</triggeringPolicy>
<encoder class="ch.qos.der.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level : %msg%n%caller{1}</pattern>
</encoder>
</appender>
</included>
最终只有三份历史⽇志⽂件和⼀份当前的⽇志⽂件:
3、按时间和⼤⼩⼀起来分割⽇志⽂件
在l⽂件中有如下配置:
<appender name="FILE" class="ch.olling.RollingFileAppender">
<!-- SizeAndTimeBasedRollingPolicy是同时结合时间和⽂件⼤⼩来滚动的策略 -->
<rollingPolicy class="ch.olling.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}代表每天⽣成⼀个⽬录存放当天的所有⽇志⽂件。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。