对于任何一个编程语言或者框架来说,在编写代码时,日志都是必不可少的内容。日志不仅可以帮助开发者了解系统中出现的问题,也能够帮助开发者了解框架、程序是如何运行的。
比如,在Spring框架中,基本上大家都会用log日志来跟踪filter的执行顺序、spring的启动顺序等等。
但是日志并不代表是一种简单的文本输出,在很多场景下,程序对日志的输出目标、格式、位置、色彩、速度都有要求。因此,市面上有很多出名的框架,例如log4j
、log4j2
、logback
、jdk log
等等。虽然他们当中最出名的几个,都是同一个人写的。。。
当种类变多功能变强的时候,选择就成为了一个问题。如何选择一个好用的、好记的日志框架,以及如何快速的适配各种系统需要开发人员去考虑。
此篇将会记录Java的日志体系,一些场景下的选择和常用配置。
什么是日志体系
那么什么是日志体系呢?我们都知道面向接口编程,由大佬们定义接口规范,小的们去实现。这样程序跑起来的时候,可以不在意究竟是哪一个实现承担的任务。举个例子。
就像你拨打别人的手机,你只需要拨出号码,不需要在意对方是电信、移动、联通或者是小米之类的通讯商。这就是他们都符合可拨打的规范带来的好处。
日志系统也是这样,不需要在意你用了什么日志框架,无论是log4j
、logback
或者是jdk原生的java.util.logger
,都能够被log日志的规范所兼容。
那么,你想要打印日志的时候,你只需要调用log.info("hello")
就可以打印"hello"。**而且,当你需要从一个框架迁移到另外一个日志框架的时候,只需要把依赖的日志框架jar包换进来,就立即生效。
而这个规范、规范的实现加上日志框架,就成为了日志体系。
在日常,最常见的和最著名的两种日志体系分别是基于JCL的日志体系和基于Slf4j的日志体系。
基于jcl日志体系
jcl日志体系的接口规范由commons-logging
提供,这是apache commons系列的工具包之一。Apache commons系列的工具包都非常有用,比如流操作、文件复制、加密解密之类的常用操作,都可以直接找到完善的解决方案。。。具体的操作晚上有很多的介绍,如果你想要知道他一共有多少种,可以直接去Maven仓库中搜索一下org.apache.commons看看。
commons-logging
已经停止更新,最后的状态如下所示:
具体的使用。。。因为我已经不用了,所以可以参考其他的使用教程:
需要注意的是jcl是存在一定缺陷的,这也是为什么现在大多数都使用slf4j作为接口规范。
基于slf4j日志体系
slf4j的历程也是非常的传奇,有兴趣的可以去搜索看看。
写了log4j、log4j2、slf4j、logback的传奇日志作者。。。Ceki
slf4j
的全称为Simple Logging Facade For Java
,从下图可见,slf4j
的能耐比jcl
大得多,基本上覆盖了所有出名的(自己写的...)日志框架。
slf4j
的使用和jcl的使用没有太大的差异,如下所示:
//声明日志对象,Logger的全限定名为
org.slf4j.Logger 而不是 java.util.Logger
static Logger log = LoggerFactory.getLogger(Log02Application.class);
//简单的测试方法
public static void main(String[] args) {
log.info("hello log");
}
具体的案例我们通过整合来介绍:
整合springboot
在springboot中,默认使用了logback
作为日志框架。默认的输出如下所示:
2017-11-29 12:58:17.757 INFO 47280 --- [ restartedMain] cn.hhchat.log02.Log02Application : hello log
但是当然你可以自己配置,配置文件放在resources文件目录下即可,springboot会自动按顺序搜寻下列文件。
- Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
- Log4j:log4j-spring.properties, log4j-spring.xml, -
log4j.properties, log4j.xml - Log4j2:log4j2-spring.xml, log4j2.xml
- JDK (Java Util Logging):logging.properties
使用log4j2
由于springboot默认使用了logback,因此当你试图使用log4j2的时候,你需要先剔除logback
。
<!--从spring-boot-starter中剔除logging,该依赖如果没有的话,可以直接把整个依赖粘上,如果依赖已经存在,只需要添加<exclustions>中间的内容即可。-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--引入log4j2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
整合spring
log4j2配置
日志的配置一直是一个大麻烦,因为每次都要导出翻博客来找,虽然之前看过官方的文档,但是现在也记不太清了,所以整理一下思路,记录一个普遍可用的方式供以后复制使用。
下面是配置的基本步骤:
log4j2配置首先,你需要先配置一个Logger
,logger定义了该logger配置使用的包和日志级别、输出到什么位置等等内容,之后配置Appender,appender表示的是你需要将日志输出到什么文件以及输出的格式。
logback配置
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss} [%thread] [%-5level] %logger{36} - %msg%n</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/base.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/base.log.%d.%i</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 64 MB -->
<maxFileSize>64 MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>
%d %p (%file:%line\)- %m%n
</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
</appender>
<root level="info">
<appender-ref ref="CONSOLE" />
</root>
<!--<logger name="com.example" level="DEBUG">-->
<!--<appender-ref ref="baselog" />-->
<!--</logger>-->
</configuration>
如果后续用到更多的日志需求,再回来补充,最近看到黄勇的架构探险上对于日志体系的分析,有很多很有意思的东西
网友评论