日志简介
对于程序员来说,出现bug的第一反应,应该是查看日志记录。日志对于bug修复、问题追踪、统计分析等都有很大的帮助。目前主流的日志框架有log4j、log4j 2、Commons Logging、Slf4j、Logback、JUL等。
关于这些日志的类别、历史、关系以及实现机制比较,可以参考Java常用日志框架介绍了解(发展历史是很有意思的 )。
常见日志
通常情况下,日志是由一个抽象层+实现层的组合来搭建的。 整体思想是采用了设计模式中的外观模式,也叫门面模式(设计模式之外观模式),可以简单的理解为接口与实现,调用者只需要关注接口而无需关注具体的实现。
如图所示,日志门面+桥接器+日志实现框架的方式实现了解耦,当想要修改日志种类时,代码无需做任何改动,只需更换桥接器和日志实现框架即可。
比较常用的组合:
日志门面 | 实现方案 |
---|---|
Commons Logging | Log4j |
Slf4j | Logback |
建议选择Slf4j+Logback,相比其他组合,有以下优势:
1) 限制较少,使用范围更广。
2) 更好的性能,更低的开销,支持占位符,方便日志代码的阅读,而 LOG4J 则不支持。
3) Slf4j和Logback都是由Ceki Gülcü开发,衔接性更佳。
4) 文档免费。
其他组合方式,可以参考SLF4J官网
Logback介绍
Logback由logback-core、logback-classic 和 logback-access 3个组件组成。
logback-core:提供了 Logback的核心功能,是另外两个组件的基础模块。
logback-classic :则实现了 SLF4J 的API,所以当想配合 SLF4J 使用时,需要将 logback-classic 引入依赖中。
logback-access :是为了集成Servlet环境而准备的,可提供HTTP访问日志接口。
使用Logback
日志级别
trace < debug < info < warn < error
默认的级别为:INFO
日志使用
maven中引入依赖
<!-- 日志文件管理包 logback -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
添加配置文件logback.xml
LogBack配置文件中的 Configuration 是根节点,Appender、Root是Configuration的子节点。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 配置信息,每60s扫描一次,这里的debug若设置为true,则会实时打印出logback的信息,所以这里我们设置为false-->
<configuration scan="false" scanPeriod="60 second" debug="false">
<!-- 定义参数常量 -->
<!-- TRACE<DEBUG<INFO<WARN<ERROR 从小到大 -->
<!-- log的level默认值是debug -->
<property name="log.level" value="DEBUG"></property>
<!-- 文件保留时间。30天 -->
<property name="log.maxHistory" value="30"></property>
<!-- 日志文件的存储跟路径,catalina.base是tomcat下实例的路径 -->
<property name="log.filePath" value="/test/logs"></property>
<!-- 日志内容的形式(格式) +执行的线程+日志级别+日志相关的信息-->
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<property name="log.pattern"
value="%d{yyyy-MM-dd HH:mm:ss} [%thread]-%-5level %logger{50} - %msg%n"></property>
<!-- 输出到控制台的配置-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 类似于layout,并有将转化后的文件写入文件中的功能 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- DEBUG -->
<!-- 按照每天,滚动生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${log.filePath}/test.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${log.pattern}</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="DEBUG">
<appender-ref ref="FILE"/>
</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 文件滚动输出
root节点中的level属性,其值可以是:TRACE、DEBUG、INFO、 WARN、ERROR、ALL 和 OFF中的任何一个。如果 root 元素没有引用任何 appender,是不会打印日志的。
接下来,在业务代码中,调用SLF4j的方法,使用Logger打印即可,截图引入的jar包,也正验证了SLF4J外观模式的使用。