Java中日志框架的使用
# Java 中日志框架的使用
# 日志定义:
在计算机领域,日志文件(logfile)是一个记录了发生在运行中的操作系统或其他软件中的事件的文件,或者记录了在网络聊天软件的用户之间发送的消息。
日志记录(Logging):是指保存日志的行为。最简单的做法是将日志写入单个存放日志的文件。
日志级别优先级:
ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
# 日志框架的作用:
①:跟踪用户对系统访问,记录了系统行为的时间、地点、状态等相关信息,能够帮助我们了解并监控系统状态
②:进行统计
③:进行 Debug,在系统产生问题时,能够帮助我们快速的定位、诊断并解决问题。
在发生错误或者接近某种危险状态时能够及时提醒我们处理
# 常用的日志框架类别简介:
Log4j Apache Log4j 是一个基于 Java 的日志记录工具。它是由Ceki Gülcü
首创的,现在则是 Apache 软件基金会的一个项目。 Log4j 是几种 Java 日志框架之一。
Log4j 2 Apache Log4j 2 是 apache 开发的一款 Log4j 的升级产品,Log4j 被 apache 收购,升级,改为 log4j2,框架改动很大,只是借用之名。
JCL (Jakarta Commons Logging) Apache 基金会所属的项目,是一套 Java 日志接口,之前叫 Jakarta Commons Logging,后更名为 Commons Logging。
Slf4j(Simple Logging Facade for Java) 类似于 Commons Logging,是一套简易 Java 日志门面,本身并无日志的实现。
Logback 一套日志组件的实现(slf4j 阵营)。
JUL (Java Util Logging),自 Java1.4 以来的官方日志实现,已被淘汰。
jboss-logging 等。
Spring 框架内部使用的日志框架是 JCL (Jakarta Commons Logging)
Mybatis 框架中使用的是 Log4j
Hibernate 框架中使用的是 jboss-logging
Springboot 底层使用的是 SLF4j + Logback
(Log4j,Logback,SLF4j 都是同一个作者。)
# 问题引入:
市场上存在非常多的日志框架。每一种日志框架都有自己单独的 API,要使用对应的框架就要使用其对应的 API,这就大大的增加应用程序代码对于日志框架的耦合性。
# 解决思路:
为了解决上述问题,就在日志框架和应用程序之间架设一个沟通的桥梁,对于应用程序来说,无论底层的日志框架如何变,都不需要有任何感知。只要门面服务做的足够好,随意换另外一个日志框架,应用程序不需要修改任意一行代码,就可以直接上线。
在软件开发领域有这样一句话:计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。而门面模式就是对于这句话的典型实践。
Logback
文档免费。Logback
的所有文档是全面免费提供的,不象 Log4J 那样只提供部分免费文档而需要用户去购买付费文档。Logback 拥有更好的性能。
因为springboot
底层使用的是 SLF4j + Logback
,而且平时开发中使用频率最高的也是此组合,所以选择使用此组合进行日志框架的整合。
# 可能出现的问题:
如果我们直接暴力的排除其他日志框架,可能导致第三方库在调用日志接口时抛出 ClassNotFound 异常,这里就需要用到中间转换包。
中间转换包说白了就是一种偷天换日的解决方案。比如 log4j-over-slf4j
,即 log4j -> slf4j 的转换包,这个库定义了与 log4j 一致的接口(包名、类名、方法签名均一致),但是接口的实现却是对 slf4j 日志接口的包装,即间接调用了 slf4j 日志接口,实现了对日志的转发。
# 解决方案:
①:先排除其他日志包
②:在项目中引入 slf4j
的 转换包
③:在项目中引入 slf4j+logback
依赖 + logback
的配置文件
<!--在项目中引入 slf4j的 转换包-->
<!-- https://mvnrepository.com/artifact/org.slf4j/log4j-over-slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId><!-- 替换log4j -->
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId><!-- 替换commons-logging -->
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId><!-- 替换java.util.logging -->
<version>1.7.25</version>
</dependency>
<!--在项目中引入 slf4j+logback 依赖-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
logback.xml
配置文件
< ?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
<!-- 日志:从低到高;只会打印指定级别以后的; additivity表示是否将日志信息反馈给root
DEBUG==》INFO===》WARN===》ERROR
Additivity:false ,避免重复打印日志
-->
<!-- 在自己的项目在中设置打印日志的级别,开发时使用-->
<logger name="com.xxx.xxx" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
</configuration>