目前(2017)流行的日志框架莫过于 slf4j + log4j,我们知道 log4j 相对于 commons-logging 等其他一些日志框架来说很好用,而且性能也很好,然而 log4j 也有其局限性或者说是设计缺陷,比如不能够对于不同的日志输出源所输出的日志进行分类(简单来说就是可以针对不同的类进行不同的日志输出管理),不能够严格地根据日志级别进行日志输出管理(比如debug级别的日志输出到debug.log,info级别的日志输出到info.log)等等,现在在 logback 中都实现了,logback 相对于 log4j 来说相当于是 log4j 的2.0 版本,还有一点 loackback 和 log4j 的作者是同一个人(Ceki Gülcü)。
logback 官网: https://logback.qos.ch/manual/configuration.html
下面作者将介绍一些关于 slf4j + logback 基础的配置(能够拿过去就能用的)
1.引入logback 的依赖 jar
在 maven 的 pom.xml 文件中添加
<!-- 属性设置 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
<slf4j.version>1.7.25</slf4j.version>
<slf4jLogback.version>1.2.3</slf4jLogback.version>
</properties>
<!-- log -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${slf4jLogback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${slf4jLogback.version}</version>
</dependency>
2.在classpath 下创建 logback.xml
注意 : logback 程序汇自动扫描项目根目录(classpath) 下的配置文件 logback-test.xml 和 logback.xml,如果是扫描到其中一个则直接使用其配置,如果这两个文件都没有扫描到,则使用 logback 的默认配置,因此,只需将 logback 的配置文件 logback.xml 放到项目根目录(classpath)下即可
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 解释一下: scan: 是否自动扫描,默认 false;scanPeriod:扫描频率,默认 1 60 secounds; debug: 是否在控制台打印日志的时候,输出 logback 内部的状态/日志信息,默认 false -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 属性定义 -->
<!-- 设置日志输出位置 -->
<property name="LOG_HOME" value="E:\\logs\\campustore" />
<!-- 设置日志文件最大保存时间(单位:day) -->
<property name="maxHistory" value="90" />
<!-- 控制台输出 ch.qos.logback.core.ConsoleAppender-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 对日志进行格式化 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger -%msg%n</pattern>
</encoder>
</appender>
<!-- ConsoleAppender 控制台输出日志 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 对日志进行格式化 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %-5level %logger{50}\(%F %L\) -%msg%n </pattern>
</encoder>
</appender>
<!-- DEBUG日志 -->
<!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 RollingFileAppender-->
<appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,记录「所有」级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 拦截日志的级别 -->
<level>DEBUG</level>
<!-- 对于符合级别要求的日志处理方式(ACCEPT:接受处理,DENY:拒绝处理)-->
<onMatch>ACCEPT</onMatch>
<!-- 对于不符合级别要求的日志处理方式(ACCEPT:接受处理,DENY:拒绝处理)-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<!-- 关于滚动策略:有依据时间的(TimeBasedRollingPolicy),有依据大小(SizeBasedTriggeringPolicy)的,作者采用的是同时根据时间和大小的方式 -->
<!-- 滚动策略: 时间 和 大小 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志保存路径于名称 -->
<fileNamePattern>${LOG_HOME}/debug/debugLog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<!-- 每个日志文件的大小,超过则生成新的日志文件-->
<maxFileSize>10MB</maxFileSize>
<maxHistory>${maxHistory}</maxHistory>
<!-- 所有日志文件总大小 -->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %-5level %logger{50}\(%F %L\) -%msg%n </pattern>
</encoder>
</appender>
<!-- INFO级别日志 -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录「INFO」级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/info/infoLog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>${maxHistory}</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %-5level %logger{50}\(%F %L\) -%msg%n </pattern>
</encoder>
</appender>
<!-- WARN级别日志 -->
<appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录「WARN」级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/warn/warnLog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>${maxHistory}</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %-5level %logger{50}\(%F %L\) -%msg%n </pattern>
</encoder>
</appender>
<!-- ERROR级别日志 -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器,只记录「ERROR」级别的日志 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/error/errorLog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>${maxHistory}</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %-5level %logger{50}\(%F %L\) -%msg%n </pattern>
</encoder>
</appender>
<!-- 关于logger 标签,可以用来设定不同的类输出不同级别的日志
name: 用来指定日志输出源 包名/类名
level: 用来指定日志输出级别,被指定的包/类 中的日志只有是该级别或高于定义的日志级别才能够被记录
additivity: 用来表明是否记录/输出 该日志源的日志,true:输出,false: 不输出
logger下的标签 <appender-ref用来包含输出类型>,和<root>标签下的一样
-->
<!-- eg: com.ljq.test 类的日志输出 info 及以上级别的日志 -->
<logger name="com.ljq.test" level="info" />
<!-- eg: com.ljq.test1 类的日志不输出 -->
<logger name="com.ljq.test1" additivity="false" />
<!-- 根日志,所有日志appender都必须包含在root/logger中,否则不会起作用 -->
<root level="debug">
<appender-ref ref="STDOUT" />
<appender-ref ref="DEBUG" />
<appender-ref ref="INFO" />
<appender-ref ref="WARN" />
<appender-ref ref="ERROR" />
</root>
</configuration>
关于 logback 的配置,注释已经很详细了,作者就不再多说了,详细配置可以参考 logback 官网
3. 测试程序
LoggerTest.java
package com.ljq.test;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @description: Test Logger
* @author: lujunqiang
* @email: flying9001@gmail.com
* @date: 2017/11/12
*/
public class LoggerTest {
private static final Logger log = LoggerFactory.getLogger(LoggerTest.class);
@Test
public void logTest() {
log.debug("Logger test for DEBUG level");
log.info("Logger test for INFO level");
log.warn("Logger test for WARN level");
log.error("Logger test for ERROR level");
}
}
控制台输出结果:
2017-11-12 22:19:06:931 [main] DEBUG com.ljq.test.LoggerTest(LoggerTest.java 20) -Logger test for DEBUG level
2017-11-12 22:19:06:946 [main] INFO com.ljq.test.LoggerTest(LoggerTest.java 21) -Logger test for INFO level
2017-11-12 22:19:06:946 [main] WARN com.ljq.test.LoggerTest(LoggerTest.java 22) -Logger test for WARN level
2017-11-12 22:19:06:946 [main] ERROR com.ljq.test.LoggerTest(LoggerTest.java 23) -Logger test for ERROR level
日志输出目录&日志文件
打开生成的日志文件:
4. 项目目录截图
最后,推荐一下作者的个人公众号「404Code」,分享一个互联网人的技术与思考,欢迎关注!