最全Java日志框架详解

最全Java日志框架详解 

在项目开发过程中,我们可以通过 debug 查找问题。而在线上环境我们查找问题只能通过打印日志的方式查找问题。因此对于一个项目而言,日志记录是一个非常重要的问题。因

此,如何选择一个合适的日志记录框架也非常重要。

在Java开发中,常用的日志记录框架有JDKLog、Log4J、LogBack、SLF4J、SLF4J。这些日志记录框架各有各的特点,各有各的应用场景。了解这些框架的特点及应用场景,有

利于我们做技术选型的时候做出正确的判断。

JDKLog:日志小刀

JDKLog是JDK官方提供的一个记录日志的方式,直接在JDK中就可以使用。

 
  1. import java.util.logging.Logger;

  2. /****

  3. ** JDKLog Demo

  4. **/

    扫描二维码关注公众号,回复: 3290109 查看本文章
  5. public class JDKLog

  6. {

  7. public static void main( String[] args )

  8. {

  9. Logger logger = Logger.getLogger("JDKLog");

  10. logger.info("Hello World.");

  11. }

  12. }

JDKLog 的有点是使用非常简单,直接在 JDK 中就可以使用。但 JDKLog 功能比较太过于简单,不支持占位符显示,拓展性比较差,所以现在用的人也很少。

Log4J:日志大炮

Log4J 是 Apache 的一个日志开源框架,有多个分级(DEBUG/INFO/WARN/ERROR)记录级别,可以很好地将不同日志级别的日志分开记录,极大地方便了日志的查看。

Log4J 有 1.X 版本和 2.X 版本,现在官方推荐使用 2.X 版本,2.X 版本在架构上进行了一些升级,配置文件也发生了一些变化。但好在官方的配置说明文档非常清楚,通过查阅

文档能解决大部分的问题。

使用 Log4J 框架首先需要引入依赖的包:

 
  1. <!-- Log4J -->

  2. <dependency>

  3. <groupId>org.apache.logging.log4j</groupId>

  4. <artifactId>log4j-api</artifactId>

  5. <version>2.6.2</version>

  6. </dependency>

  7. <dependency>

  8. <groupId>org.apache.logging.log4j</groupId>

  9. <artifactId>log4j-core</artifactId>

  10. <version>2.6.2</version>

  11. </dependency>

增加配置文件 log4j2.xml 放在 resource 目录下:

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <Configuration status="WARN">

  3. <Appenders>

  4. <Console name="Console" target="SYSTEM_OUT">

  5. <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>

  6. </Console>

  7. </Appenders>

  8. <Loggers>

  9. <Root level="info">

  10. <AppenderRef ref="Console"/>

  11. </Root>

  12. </Loggers>

  13. </Configuration>

其中节点的 level 属性表示输出的最低级别。

最后编写一个测试类:

 
  1. import org.apache.logging.log4j.LogManager;

  2. import org.apache.logging.log4j.Logger;

  3. /****

  4. ** Log4J Demo

  5. **/

  6. public class Log4jLog {

  7. public static void main(String args[]) {

  8. Logger logger = LogManager.getLogger(Log4jLog.class);

  9. logger.debug("Debug Level");

  10. logger.info("Info Level");

  11. logger.warn("Warn Level");

  12. logger.error("Error Level");

  13. }

  14. }

运行测试类输出结果:

10:16:08.279 [main] INFO com.chanshuyi.Log4jLog - Info Level
10:16:08.280 [main] WARN com.chanshuyi.Log4jLog - Warn Level
10:16:08.280 [main] ERROR com.chanshuyi.Log4jLog - Error Level
如果没有配置 log4j2.xml 配置文件,那么LOG4J将自动启用类似于下面的的配置文件:

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <Configuration status="WARN">

  3. <Appenders>

  4. <Console name="Console" target="SYSTEM_OUT">

  5. <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>

  6. </Console>

  7. </Appenders>

  8. <Loggers>

  9. <Root level="error">

  10. <AppenderRef ref="Console"/>

  11. </Root>

  12. </Loggers>

  13. </Configuration>

使用默认配置文件的输出结果:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
11:40:07.377 [main] ERROR com.chanshuyi.Log4jLog - Error Level

从上面的使用步骤可以看出 Log4J 的使用稍微复杂一些,但是条理还是很清晰的。而且因为 Log4J 有多个分级(DEBUG/INFO/WARN/ERROR)记录级别,所以可以很好地记

录不同业务问题。因为这些优点,所以在几年前几乎所有人都使用 Log4J 作为日志记录框架,群众基础可谓非常深厚。

但 Log4J 本身也存在一些缺点,比如不支持使用占位符,不利于代码阅读等缺点。但是相比起 JDKLog,Log4J 可以说是非常好的日志记录框架了。

LogBack:日志火箭

LogBack 其实可以说是 Log4J 的进化版,因为它们两个都是同一个人(Ceki Gülcü)设计的开源日志组件。LogBack 除了具备 Log4j 的所有优点之外,还解决了 Log4J 不能

使用占位符的问题。

使用 LogBack 需要首先引入依赖:

 
  1. <!-- LogBack -->

  2. <dependency>

  3. <groupId>ch.qos.logback</groupId>

  4. <artifactId>logback-classic</artifactId>

  5. <version>1.1.7</version>

  6. </dependency>

配置 logback.xml 配置文件:

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <configuration>

  3. <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

  4. <layout class="ch.qos.logback.classic.PatternLayout">

  5. <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>

  6. </layout>

  7. </appender>

  8. <logger name="com.chanshuyi" level="TRACE"/>

  9. <root level="debug">

  10. <appender-ref ref="STDOUT" />

  11. </root>

  12. </configuration>

LogBack 的日志级别区分可以细分到类或者包,这样就可以使日志记录变得更加灵活。之后在类文件中引入Logger类,并进行日志记录:

 
  1. import org.slf4j.Logger;

  2. import org.slf4j.LoggerFactory;

  3. /****

  4. ** LogBack Demo

  5. **/

  6. public class LogBack {

  7. static final Logger logger = LoggerFactory.getLogger(LogBack.class);

  8. public static void main(String[] args) {

  9. logger.trace("Trace Level.");

  10. logger.debug("Debug Level.");

  11. logger.info("Info Level.");

  12. logger.warn("Warn Level.");

  13. logger.error("Error Level.");

  14. }

  15. }

输出结果:

14:34:45.747 [main] TRACE com.chanshuyi.LogBack - Trace Level.
14:34:45.749 [main] DEBUG com.chanshuyi.LogBack - Debug Level.
14:34:45.749 [main] INFO com.chanshuyi.LogBack - Info Level.
14:34:45.749 [main] WARN com.chanshuyi.LogBack - Warn Level.
14:34:45.749 [main] ERROR com.chanshuyi.LogBack - Error Level.

LogBack 解决了 Log4J 不能使用占位符的问题,这使得阅读日志代码非常方便。除此之外,LogBack 比 Log4J 有更快的运行速度,更好的内部实现。并且 LogBack 内部集成

了 SLF4J 可以更原生地实现一些日志记录的实现。

SLF4J:适配器

上面说了 JDKLog、Log4J、LogBack 这几个常用的日志记录框架,它们都有各自的优缺点,适合在不同的场景下使用。可能简单的项目直接用 JDKLog 就可以了,而复杂的

项目需要用上 Log4J。

很多时候我们做项目都是从简单到复杂,也就是我们很可能一开始使用的是 JDKLog,之后业务复杂了需要使用 Log4J,这时候我们如何将原来写好的日志用新的日志框架输出

呢?
一个最死板的方法就是一行行代码修改,把之前用 JDKLog 的日志代码全部修改成 Log4J 的日志接口。但是这种方式不仅效率低下,而且做的工作都是重复性的工作,这怎么

能忍呢。

正式因为在实际的项目应用中,有时候可能会从一个日志框架切换到另外一个日志框架的需求,这时候往往需要在代码上进行很大的改动。为了避免切换日志组件时要改动代

码,这时候一个叫做 SLF4J(Simple Logging Facade for Java,即Java简单日志记录接口集)的东西出现了。

SLF4J(Simple Logging Facade for Java,即Java简单日志记录接口集)是一个日志的接口规范,它对用户提供了统一的日志接口,屏蔽了不同日志组件的差异。这样我们在

编写代码的时候只需要看 SLF4J 这个接口文档即可,不需要去理会不同日之框架的区别。而当我们需要更换日志组件的时候,我们只需要更换一个具体的日志组件Jar包就可以

了。

而整合 SLF4J 和日志框架使用也是一件很简单的事情。

SLF4J+JDKLog

SLF4J + JDKLog 需要在 Maven 中导入以下依赖包:

 
  1. <dependency>

  2. <groupId>org.slf4j</groupId>

  3. <artifactId>slf4j-api</artifactId>

  4. <version>1.7.21</version>

  5. </dependency>

  6. <dependency>

  7. <groupId>org.slf4j</groupId>

  8. <artifactId>slf4j-jdk14</artifactId>

  9. <version>1.7.21</version>

  10. </dependency>

编写测试类:

 
  1. import org.slf4j.Logger;

  2. import org.slf4j.LoggerFactory;

  3. /****

  4. ** SLF4J + JDKLog

  5. **/

  6. public class Slf4jJDKLog {

  7. final static Logger logger = LoggerFactory.getLogger(Slf4jJDKLog.class);

  8. public static void main(String[] args) {

  9. logger.trace("Trace Level.");

  10. logger.info("Info Level.");

  11. logger.warn("Warn Level.");

  12. logger.error("Error Level.");

  13. }

  14. }

输出结果:
七月 15, 2016 3:30:02 下午 com.chanshuyi.slf4j.Slf4jJDKLog main
信息: Info Level.
七月 15, 2016 3:30:02 下午 com.chanshuyi.slf4j.Slf4jJDKLog main
警告: Warn Level.
七月 15, 2016 3:30:02 下午 com.chanshuyi.slf4j.Slf4jJDKLog main
严重: Error Level.

SLF4J+LOG4J

需要依赖的 Jar 包:slf4j-api.jar、slf4j-412.jar、log4j.jar,导入Maven依赖:

 
  1. <!-- 2.SLF4J + Log4J -->

  2. <dependency>

  3. <groupId>org.slf4j</groupId>

  4. <artifactId>slf4j-api</artifactId>

  5. <version>1.7.21</version>

  6. </dependency>

  7. <dependency>

  8. <groupId>org.slf4j</groupId>

  9. <artifactId>slf4j-log4j12</artifactId>

  10. <version>1.7.21</version>

  11. </dependency>

  12. <dependency>

  13. <groupId>log4j</groupId>

  14. <artifactId>log4j</artifactId>

  15. <version>1.2.17</version>

  16. </dependency>

配置 log4j.xml 文件:

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

  3. <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' >

  4. <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">

  5. <layout class="org.apache.log4j.PatternLayout">

  6. <param name="ConversionPattern"

  7. value="[%d{dd HH:mm:ss,SSS} %-5p] [%t] %c{2} - %m%n" />

  8. </layout>

  9. <!--过滤器设置输出的级别-->

  10. <filter class="org.apache.log4j.varia.LevelRangeFilter">

  11. <param name="levelMin" value="debug" />

  12. <param name="levelMax" value="error" />

  13. <param name="AcceptOnMatch" value="true" />

  14. </filter>

  15. </appender>

  16. <!-- 根logger的设置-->

  17. <root>

  18. <priority value ="debug"/>

  19. <appender-ref ref="myConsole"/>

  20. </root>

  21. </log4j:configuration>

我们还是用上面的代码,无需做改变,运行结果为:
[15 16:04:06,371 DEBUG] [main] slf4j.SLF4JLog - Debug Level.
[15 16:04:06,371 INFO ] [main] slf4j.SLF4JLog - Info Level.
[15 16:04:06,371 WARN ] [main] slf4j.SLF4JLog - Warn Level.
[15 16:04:06,371 ERROR] [main] slf4j.SLF4JLog - Error Level.
SLF4J+LogBack

导入依赖:

 
  1. <dependency>

  2. <groupId>org.slf4j</groupId>

  3. <artifactId>slf4j-api</artifactId>

  4. <version>1.7.21</version>

  5. </dependency>

  6. <dependency>

  7. <groupId>ch.qos.logback</groupId>

  8. <artifactId>logback-classic</artifactId>

  9. <version>1.1.7</version>

  10. </dependency>

  11. <dependency>

  12. <groupId>ch.qos.logback</groupId>

  13. <artifactId>logback-core</artifactId>

  14. <version>1.1.7</version>

  15. </dependency>

配置 logback.xml 文件:

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <configuration>

  3. <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

  4. <layout class="ch.qos.logback.classic.PatternLayout">

  5. <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>

  6. </layout>

  7. </appender>

  8. <logger name="com.chanshuyi" level="TRACE"/>

  9. <root level="warn">

  10. <appender-ref ref="STDOUT" />

  11. </root>

  12. </configuration>

我们还是用上面的代码,无需做改变,运行结果为:
16:08:01.040 [main] TRACE com.chanshuyi.slf4j.SLF4JLog - Trace Level.
16:08:01.042 [main] DEBUG com.chanshuyi.slf4j.SLF4JLog - Debug Level.
16:08:01.043 [main] INFO com.chanshuyi.slf4j.SLF4JLog - Info Level.
16:08:01.043 [main] WARN com.chanshuyi.slf4j.SLF4JLog - Warn Level.
16:08:01.043 [main] ERROR com.chanshuyi.slf4j.SLF4JLog - Error Level.

LogBack日志框架

经过上面的介绍,相信大家对 Java 常用的日志框架都有了一定认识。

那么在实际使用中到底选择哪种日志框架合适呢?

按笔者理解,现在最流的日志框架解决方案莫过于SLF4J + LogBack。原因有下面几点:

LogBack 自身实现了 SLF4J 的日志接口,不需要 SLF4J 去做进一步的适配。

LogBack 自身是在 Log4J 的基础上优化而成的,其运行速度和效率都比 LOG4J 高。

SLF4J + LogBack 支持占位符,方便日志代码的阅读,而 LOG4J 则不支持。

从上面几点来看,SLF4J + LogBack是一个较好的选择。

LogBack 被分为3个组件:logback-core、logback-classic 和 logback-access。

logback-core 提供了 LogBack 的核心功能,是另外两个组件的基础。

logback-classic 则实现了 SLF4J 的API,所以当想配合 SLF4J 使用时,需要将 logback-classic 引入依赖中。

logback-access 是为了集成Servlet环境而准备的,可提供HTTP-access的日志接口。

LogBack的日志记录数据流是从 Class(Package)到 Logger,再从Logger到Appender,最后从Appender到具体的输出终端。

LogBack配置文件可以分为几个节点,其中 Configuration 是根节点,Appender、Logger、Root是Configuration的子节点。

appender节点

是的子节点,是负责写日志的组件。appender有两个必要属性name、class 。name指定appender的名称,class指定appender的全限定名class,主要包括:
ch.qos.logback.core.ConsoleAppender 控制台输出
ch.qos.logback.core.FileAppender 文件输出
ch.qos.logback.core.RollingFileAppender 文件滚动输出

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <configuration debug="true" scan="true" scanPeriod="2">

  3. <!-- conf consoel out -->

  4. <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">

  5. </appender>

  6. <!-- conf file out -->

  7. <appender name="file_out" class="ch.qos.logback.core.FileAppender">

  8. </appender>

  9. <!-- conf file out -->

  10. <appender name="file_out" class="ch.qos.logback.core.RollingFileAppender">

  11. </appender>

  12. <root></root>

  13. <logger></logger>

  14. </configuration>

ConsoleAppender
把日志添加到控制台,有如下节点:

<encoder> : 对日志进行格式化。

<target> : 字符串System.out 或者 System.err, 默认 System.out;

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <configuration>

  3. <!-- conf consoel out -->

  4. <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">

  5. <encoder>

  6. <pattern>%date [%thread] %-5level %logger - %message%newline</pattern>

  7. </encoder>

  8. </appender>

  9. <root level="INFO">

  10. <appender-ref ref="console_out" />

  11. </root>

  12. </configuration>

FileAppender
把日志添加到文件,有如下节点:
<file>:被写入的文件名,可以是相对目录 , 也可以是绝对目录 , 如果目录不存在则会自动创建。

<append>:如果是true , 日志被追加到文件结尾 , 如果是false,清空现存文件 , 默认是true。

<encoder>:对日志进行格式化 [具体的转换符说明请参见官网.]

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <configuration>

  3. <appender name="file_out" class="ch.qos.logback.core.FileAppender">

  4. <file>logs/debug.log</file>

  5. <encoder>

  6. <pattern>%date [%thread] %-5level %logger - %message%newline</pattern>

  7. </encoder>

  8. </appender>

  9. </configuration>

rollingFileAppender
滚动纪录文件,先将日志记录到指定文件,当符合某种条件时,将日志记录到其他文件,有如下节点:
<file>:被写入的文件名,可以是相对目录,也可以解决目录,如果目录不存在则自动创建。
<append>:如果是true,日志被追加到文件结尾,如果是false,清空现存文件,默认是true。
<encoder>:对日志进行格式化。
<rollingPolicy>:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。
rollingPolicy
TimeBaseRollingPolicy :最常用的滚动策略,根据时间来制定滚动策略,即负责滚动也负责触发滚动。有如下节点;
<fileNamePattern>:必要节点,包含文件及“%d” 转换符,“%d”可以包含一个java.text.SimpleDateFormat 制定的时间格式,如:%d{yyyy-MM},如果直接使用%d ,默认格式是 yyyy-MM-dd。
<maxHistory>:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件,假设设置每个月滚动,且 是 6,则只保存最近6个月的文件,删除之前的旧文件,注意:删除旧文件是哪些为了归档而创建的目录也会被删除。
<filenamePattern>:必须包含“%i” 例如:设置最小值,和最大值分别为1和2,命名模式为 log%i.log,会产生归档文件log1.log和log2.log,还可以指定文件压缩选项,例如:log%i.log.gz 或者 log%i.log.zip
triggeringPolicy:告知RollingFileAppender,激活RollingFileAppender滚动。

 
  1. <!-- 03:conf errorAppender out -->

  2. <appender name="errorAppender" class="ch.qos.logback.core.RollingFileAppender">

  3. <file>logs/error.log</file>

  4. <!-- 设置滚动策略 -->

  5. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

  6. <!--设置日志命名模式-->

  7. <fileNamePattern>errorFile.%d{yyyy-MM-dd}.log</fileNamePattern>

  8. <!--最多保留30天log-->

  9. <maxHistory>30</maxHistory>

  10. </rollingPolicy>

  11. <!-- 超过150MB时,触发滚动策略 -->

  12. <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

  13. <maxFileSize>150</maxFileSize>

  14. </triggeringPolicy>

  15. <encoder>

  16. <pattern>%d [%p] %-5level %logger - %msg%newline</pattern>

  17. </encoder>

  18. </appender>

logger节点
logger是的子节点,来设置某一个包或者具体的某一个类的日志打印级别,以及指定。logger仅有一个name属性,两个可选属性 level/addtivity。
name:用来指定受此loger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关。可选值有TRACE、DEBUG、INFO、WARN、ERROR、ALL和OFF。还有一个特俗值INHERITED 或者 同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前logger将会继承上级的级别。
addtivity:是否向上级logger传递打印信息,默认为true;
可以包含零个或多个元素,表示这个appender将会添加到logger。

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <configuration>

  3. <!-- conf consoel out -->

  4. <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">

  5. <filter class="ch.qos.logback.classic.filter.LevelFilter">

  6. <!-- 过滤掉非INFO级别 -->

  7. <level>INFO</level>

  8. <onMatch>ACCEPT</onMatch>

  9. <onMismatch>DENY</onMismatch>

  10. </filter>

  11. </appender>

  12. <!-- conf infoAppender out -->

  13. <appender name="infoAppender" class="ch.qos.logback.core.RollingFileAppender">

  14. <file>logs/info.log</file>

  15. <!-- 设置滚动策略 -->

  16. <rollingPoliy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

  17. <!--设置日志命名模式-->

  18. <fileNamePattern>infoFile.%d{yyyy-MM-dd}.log</fileNamePattern>

  19. <!--最多保留30天log-->

  20. <maxHistory>30</maxHistory>

  21. </rollingPoliy>

  22. <!-- 超过150MB时,触发滚动策略 -->

  23. <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

  24. <maxFileSize>150</maxFileSize>

  25. </triggeringPolicy>

  26. <encoder>

  27. <pattern>%d [%p] %-5level %logger - %msg%newline</pattern>

  28. </encoder>

  29. </appender>

  30. <!-- 添加两个appender节点 -->

  31. <logger name="logback.olf.log" level="info">

  32. <appender-ref ref = "console_out"/>

  33. <appender-ref ref = "infoAppender"/>

  34. </logger>

  35. </configuration>

root节点
元素配置根logger。该元素有一个level属性,没有name属性,因为已经被命名 为root。Level属性的值大小写无关,其值为下面其中一个字符串:TRACE、DEBUG、INFO、 WARN、ERROR、ALL 和 OFF。如果 root 元素没 有引用任何 appender,就会失去所有 appender。

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <configuration>

  3. <!-- conf consoel out -->

  4. <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">

  5. <filter class="ch.qos.logback.classic.filter.LevelFilter">

  6. <!-- 过滤掉非INFO级别 -->

  7. <level>INFO</level>

  8. <onMatch>ACCEPT</onMatch>

  9. <onMismatch>DENY</onMismatch>

  10. </filter>

  11. </appender>

  12. <!-- 01:conf infoAppender out -->

  13. <appender name="infoAppender" class="ch.qos.logback.core.RollingFileAppender">

  14. <file>logs/info.log</file>

  15. <!-- 设置滚动策略 -->

  16. <rollingPoliy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

  17. <!--设置日志命名模式-->

  18. <fileNamePattern>infoFile.%d{yyyy-MM-dd}.log</fileNamePattern>

  19. <!--最多保留30天log-->

  20. <maxHistory>30</maxHistory>

  21. </rollingPoliy>

  22. <!-- 超过150MB时,触发滚动策略 -->

  23. <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

  24. <maxFileSize>150</maxFileSize>

  25. </triggeringPolicy>

  26. <encoder>

  27. <pattern>%d [%p] %-5level %logger - %msg%newline</pattern>

  28. </encoder>

  29. </appender>

  30. <!-- 02:conf debugAppender out -->

  31. <appender name="debugAppender" class="ch.qos.logback.core.RollingFileAppender">

  32. <file>logs/debug.log</file>

  33. <!-- 设置滚动策略 -->

  34. <rollingPoliy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

  35. <!--设置日志命名模式-->

  36. <fileNamePattern>debugFile.%d{yyyy-MM-dd}.log</fileNamePattern>

  37. <!--最多保留30天log-->

  38. <maxHistory>30</maxHistory>

  39. </rollingPoliy>

  40. <!-- 超过150MB时,触发滚动策略 -->

  41. <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

  42. <maxFileSize>150</maxFileSize>

  43. </triggeringPolicy>

  44. <encoder>

  45. <pattern>%d [%p] %-5level %logger - %msg%newline</pattern>

  46. </encoder>

  47. </appender>

  48. <!-- 03:conf errorAppender out -->

  49. <appender name="errorAppender" class="ch.qos.logback.core.RollingFileAppender">

  50. <file>logs/error.log</file>

  51. <!-- 设置滚动策略 -->

  52. <rollingPoliy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

  53. <!--设置日志命名模式-->

  54. <fileNamePattern>errorFile.%d{yyyy-MM-dd}.log</fileNamePattern>

  55. <!--最多保留30天log-->

  56. <maxHistory>30</maxHistory>

  57. </rollingPoliy>

  58. <!-- 超过150MB时,触发滚动策略 -->

  59. <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

  60. <maxFileSize>150</maxFileSize>

  61. </triggeringPolicy>

  62. <encoder>

  63. <pattern>%d [%p] %-5level %logger - %msg%newline</pattern>

  64. </encoder>

  65. </appender>

  66. <root level="ALL">

  67. <appender-ref ref="infoAppender"/>

  68. <appender-ref ref="debugAppender"/>

  69. <appender-ref ref="errorAppender"/>

  70. </root>

  71. </configuration>

filter过滤节点
级别过滤器(LevelFilter)
LevelFilter 根据记录级别对记录事件进行过滤。如果事件的级别等于配置的级别,过滤 器会根据 onMatch 和 onMismatch 属性接受或拒绝事件。下面是个配置文件例子:

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <configuration>

  3. <!-- conf consoel out -->

  4. <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">

  5. <filter class="ch.qos.logback.classic.filter.LevelFilter">

  6. <!-- 过滤掉非INFO级别 -->

  7. <level>INFO</level>

  8. <onMatch>ACCEPT</onMatch>

  9. <onMismatch>DENY</onMismatch>

  10. </filter>

  11. <encoder>

  12. <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>

  13. </encoder>

  14. </appender>

  15. <root level="DEBUG">

  16. <appender-ref ref="console_out" />

  17. </root>

  18. </configuration>

临界值过滤器(ThresholdFilter)
ThresholdFilter过滤掉低于指定临界值的事件。

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <configuration>

  3. <!-- conf consoel out -->

  4. <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">

  5. <filter class="ch.qos.logback.classic.filter.ThresholdFilter">

  6. <!-- 过滤掉TRACE和DEBUG级别的日志 -->

  7. <level>INFO</level>

  8. </filter>

  9. <encoder>

  10. <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>

  11. </encoder>

  12. </appender>

  13. <root level="DEBUG">

  14. <appender-ref ref="console_out" />

  15. </root>

  16. </configuration>

求值过滤器(EvaluatorFilter)
评估是否符合指定的条件

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <configuration>

  3. <!-- conf consoel out -->

  4. <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">

  5. <filter class="ch.qos.logback.classic.filter.EvaluatorFilter">

  6. <evaluator>

  7. <!--过滤掉所有日志中不包含hello字符的日志-->

  8. <expression>

  9. message.contains("hello")

  10. </expression>

  11. <onMatch>NEUTRAL</onMatch>

  12. <onMismatch>DENY</onMismatch>

  13. </evaluator>

  14. </filter>

  15. <encoder>

  16. <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>

  17. </encoder>

  18. </appender>

  19. <root level="DEBUG">

  20. <appender-ref ref="console_out" />

  21. </root>

  22. </configuration>

匹配器(Matchers)

 
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <configuration>

  3. <!-- conf consoel out -->

  4. <appender name ="console_out" class="ch.qos.logback.core.ConsoleAppender">

  5. <filter class="ch.qos.logback.classic.filter.EvaluatorFilter">

  6. <evaluator>

  7. <matcher>

  8. <Name>odd</Name>

  9. <!-- 过滤掉序号为奇数的语句-->

  10. <regex>statement [13579]</regex>

  11. </matcher>

  12. <expression>odd.matches(formattedMessage)</expression>

  13. <onMatch>NEUTRAL</onMatch>

  14. <onMismatch>DENY</onMismatch>

  15. </evaluator>

  16. </filter>

  17. <encoder>

  18. <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>

  19. </encoder>

  20. </appender>

  21. <root level="DEBUG">

  22. <appender-ref ref="console_out" />

  23. </root>

  24. </configuration>

下面是一个我常用的logback.xml配置文件,供大家参考:

 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <configuration debug="true" scan="true" scanPeriod="30 seconds">

  3. <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

  4. <!-- encoders are by default assigned the type

  5. ch.qos.logback.classic.encoder.PatternLayoutEncoder -->

  6. <encoder>

  7. <pattern>%d{yyyy-MM-dd HH:mm:ss} [%level] - %m%n</pattern>

  8. <!-- 常用的Pattern变量,大家可打开该pattern进行输出观察 -->

  9. <!--

  10. <pattern>

  11. %d{yyyy-MM-dd HH:mm:ss} [%level] - %msg%n

  12. Logger: %logger

  13. Class: %class

  14. File: %file

  15. Caller: %caller

  16. Line: %line

  17. Message: %m

  18. Method: %M

  19. Relative: %relative

  20. Thread: %thread

  21. Exception: %ex

  22. xException: %xEx

  23. nopException: %nopex

  24. rException: %rEx

  25. Marker: %marker

  26. %n

  27. </pattern>

  28. -->

  29. </encoder>

  30. </appender>

  31. <!-- 按日期区分的滚动日志 -->

  32. <appender name="ERROR-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">

  33. <file>logs/error.log</file>

  34. <encoder>

  35. <pattern>%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>

  36. </encoder>

  37. <filter class="ch.qos.logback.classic.filter.LevelFilter">

  38. <level>ERROR</level>

  39. <onMatch>ACCEPT</onMatch>

  40. <onMismatch>DENY</onMismatch>

  41. </filter>

  42. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

  43. <!-- daily rollover -->

  44. <fileNamePattern>error.%d{yyyy-MM-dd}.log.zip</fileNamePattern>

  45. <!-- keep 30 days' worth of history -->

  46. <maxHistory>30</maxHistory>

  47. </rollingPolicy>

  48. </appender>

  49. <!-- 按文件大小区分的滚动日志 -->

  50. <appender name="INFO-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">

  51. <file>logs/info.log</file>

  52. <encoder>

  53. <pattern>%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>

  54. </encoder>

  55. <filter class="ch.qos.logback.classic.filter.LevelFilter">

  56. <level>INFO</level>

  57. <onMatch>ACCEPT</onMatch>

  58. <onMismatch>DENY</onMismatch>

  59. </filter>

  60. <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">

  61. <fileNamePattern>info.%i.log</fileNamePattern>

  62. <minIndex>1</minIndex>

  63. <maxIndex>3</maxIndex>

  64. </rollingPolicy>

  65. <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

  66. <maxFileSize>5MB</maxFileSize>

  67. </triggeringPolicy>

  68. </appender>

  69. <!-- 按日期和大小区分的滚动日志 -->

  70. <appender name="DEBUG-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">

  71. <file>logs/debug.log</file>

  72. <encoder>

  73. <pattern>%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>

  74. </encoder>

  75. <filter class="ch.qos.logback.classic.filter.LevelFilter">

  76. <level>DEBUG</level>

  77. <onMatch>ACCEPT</onMatch>

  78. <onMismatch>DENY</onMismatch>

  79. </filter>

  80. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

  81. <!-- rollover daily -->

  82. <fileNamePattern>debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>

  83. <timeBasedFileNamingAndTriggeringPolicy

  84. class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">

  85. <!-- or whenever the file size reaches 100MB -->

  86. <maxFileSize>100MB</maxFileSize>

  87. </timeBasedFileNamingAndTriggeringPolicy>

  88. </rollingPolicy>

  89. </appender>

  90. <!-- 级别阀值过滤 -->

  91. <appender name="SUM-OUT" class="ch.qos.logback.core.rolling.RollingFileAppender">

  92. <file>logs/sum.log</file>

  93. <encoder>

  94. <pattern>%d{yyyy-MM-dd HH:mm:ss} [%class:%line] - %m%n</pattern>

  95. </encoder>

  96. <!-- deny all events with a level below INFO, that is TRACE and DEBUG -->

  97. <filter class="ch.qos.logback.classic.filter.ThresholdFilter">

  98. <level>INFO</level>

  99. </filter>

  100. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

  101. <!-- rollover daily -->

  102. <fileNamePattern>debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>

  103. <timeBasedFileNamingAndTriggeringPolicy

  104. class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">

  105. <!-- or whenever the file size reaches 100MB -->

  106. <maxFileSize>100MB</maxFileSize>

  107. </timeBasedFileNamingAndTriggeringPolicy>

  108. </rollingPolicy>

  109. </appender>

  110. <root level="debug">

  111. <appender-ref ref="STDOUT" />

  112. <appender-ref ref="ERROR-OUT" />

  113. <appender-ref ref="INFO-OUT" />

  114. <appender-ref ref="DEBUG-OUT" />

  115. <appender-ref ref="SUM-OUT" />

  116. </root>

  117. </configuration>

如何进行日志系统转换?
在实际的日志转换过程中,SLF4J其实是充当了一个中介的角色。例如当我们一个项目原来是使用LOG4J进行日志记录,但是我们要换成LogBack进行日志记录。
此时我们需要先将LOG4J转换成SLF4J日志系统,再从SLF4J日志系统转成LogBack日志系统。
从日志框架转向SLF4J
jul-to-slf4j:jdk-logging到slf4j的桥梁
log4j-over-slf4j:log4j1到slf4j的桥梁
jcl-over-slf4j:commons-logging到slf4j的桥梁
从SLF4J转向具体的日志框架
slf4j-jdk14:slf4j到jdk-logging的桥梁
slf4j-log4j12:slf4j到log4j1的桥梁
log4j-slf4j-impl:slf4j到log4j2的桥梁
logback-classic:slf4j到logback的桥梁
slf4j-jcl:slf4j到commons-logging的桥梁
例如我们一开始使用的是 Log4J 日志框架,现在我们希望转成 LogBack 框架,那么我们首先需要加入 log4j-over-slf4j.jar 将 Log4J 转成 SLF4J,之后再加入 logback-classic.jar 将 SLF4J 转成 LogBack。
日志技术框架一览
JUL:JDK中的日志记录工具,也常称为JDKLog、jdk-logging。
LOG4J1:一个具体的日志实现框架。
LOG4J2:一个具体的日志实现框架,是LOG4J1的下一个版本。
LOGBACK:一个具体的日志实现框架,但其性能更好。
JCL:一个日志门面,提供统一的日志记录接口,也常称为commons-logging。
SLF4J:一个日志门面,与JCL一样提供统一的日志记录接口,可以方便地切换看具体的实现框架。
JUL、LOG4J1、LOG4J2、LOGBACK是日志实现框架,而JCL、SLF4J是日志实现门面

猜你喜欢

转载自blog.csdn.net/kingmax54212008/article/details/82805548