日志组件
参考资料
一、简介
日志门面
日志门面定义了一组日志的接口规范,它并不提供底层具体的实现逻辑。Apache Commons Logging 和 Slf4j就属于这一类。
日志实现
日志实现则是日志具体的实现,包括日志级别控制、日志打印格式、日志输出形式(输出到数据库、输出到文件、输出到控制台等)。Log4j、Log4j2、Logback 以及 Java Util Logging 则属于这一类。
将日志门面和日志实现分离其实是一种典型的门面模式,这种方式可以让具体业务在不同的日志实现框架之间自由切换,而不需要改动任何代码,开发者只需要掌握日志门面的 API 即可。
日志门面是不能单独使用的,它必须和一种具体的日志实现框架相结合使用。
那么日志框架是否可以单独使用呢?
技术上来说当然没问题,但是我们一般不会这样做,因为这样做可维护性很差,而且后期扩展不易。
例如 A 开发了一个工具包使用 Log4j 打印日志,B 引用了这个工具包,但是 B 喜欢使用 Logback 打印日志,此时就会出现一个业务使用两个甚至多个日志框架,开发者也需要维护多个日志的配置文件。因此我们都是用日志门面打印日志。
二、日志类型
- 登录日志:登入登出日志【ip、时间】
- 操作日志:【操作人、操作时间、操作详情】
- 接口日志:【入参、出参、时间】
三、slf4j
//查看slf4j源码,LoggerFactory.getLogger(Object.class)
getLogger的时候会去classpath下找STATIC_LOGGER_BINDER_PATH,STATIC_LOGGER_BINDER_PATH值为"org/slf4j/impl/StaticLoggerBinder.class",
即所有slf4j的实现,在提供的jar包路径下,一定是有"org/slf4j/impl/StaticLoggerBinder.class"存在的
SLF4J,是原来log4j的作者写的一个新的日志组件,意思是简单日志门面接口,可以跟其他日志组件配合使用,常用的配合是slf4j+logback,无论从功能上还是从性能上都较之log4j有了很大的提升
SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。
按照官方的说法,SLF4J是一个用于日志系统的简单 Facade ,允许最终用户在部署其应用时使用其所希望的日志System
Facade(外观)模式为子系统中的各类(或结构与方法)提供一个简明一致的界面,隐藏子系统的复杂性,使子系统更加容易使用。
四、log4j & log4j2
Log4j是apache的一个开源项目,是一个用来操作日志的包。通过使用Log4J,可以指定日志信息输出的目的地,如控制台、文件、CUI组件、NT的事件记录器;还可以控制每一条日志输出格式。并且都是采用配置文件的形式。
log4j有三个主要的组件:Logger、Appender、Layout
log4j使用
1. 添加log4j依赖(添加Log4j包)
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
2. 添加log4j配置文件
Log4j中组件是通过属性文件进行配置的,该文件默认名称为log4j.properties,默认路径在src根目录下,在web项目中,通过在web.xml文件中添加log4jConfigLocation属性来修改配置文件名称及路径。
3.关业务类中创建Logger对象
3.1创建Logger对象有两种方式,第一种是通过当前类的Class对象创建。
3.2第二种方式则通过自定义名称创建。(不建议采用该方式)
4.在业务代码中添加日志输出代码
根据系统中日志信息的重要程度,选择logger对象不同的级别进行记录,log4j会根据配置文件(log4j.properties)中配置的日志级别来输入对应的日志。
log4j2使用
Log4j和Log4j2的区别
og4j是Apache的一个开源项目,log4j2和log4j是一个作者,只不过log4j2是重新架构的一款日志组件,他抛弃了之前log4j的不足,以及吸取了优秀的logback的设计重新推出的一款新组件。log4j2的社区活跃很频繁而且更新的也很快
五、logback
Logback是由log4j创始人设计的另一个开源日志组件,官网:http://logback.qos.ch。 它当前分为下面下个模块:
- logback-core:其它两个模块的基础模块
- logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging
- logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能
Logback、slf4j和Log4j关系
- slf4j如jdbc一样,定义了一套接口,是一个日志门面,可实现多个日志系统间快速切换(通过修改配置文件)
- log4j是apache实现的一个开源日志组件.(Wrapped implementations)
- logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架。是slf4j的原生实现。
Logback使用
1.添加pom依赖
slf4j-api
logback-core
logback-classic
2.配置config.properties:
#logback中的日志级别
logback.common.level=error
logback.business.level=info
logback.root.level=error
3.添加logbak.xml配置
4.记录日志
//1).slf4j 配合具体日志实现log4j、logback
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(ConfigCacheService.class);
logger.error("找不到控件{}", new Object[]{itemid});
//其他日志组件使用 apache.commons.logging
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
private static final Log log = LogFactory.getLog(XmlParser.class);
log.error("IOException:" + e.getMessage());
//其他日志组件使用 log4j
import org.apache.log4j.Logger;
private static final Logger logger = Logger.getLogger(Ssxsysbj.class);
logger.error("诉讼线索移送流程创建失败:", e);
六、Log4jdbc
Log4jdbc 的官方主页是https://github.com/arthurblake/log4jdbc,它具有以下特点:
- 完全支持 JDBC3 和 JDBC4
- 配置简单,在大多数情况下,只需要将 JDBC 驱动类改成 net.sf.log4jdbc.DriverSpy ,同时将 jdbc:log4jdbc 添加到现有的 JDBC URL 之前,最后配置日志记录的种类即可
- 将 Prepared Statements 中的绑定参数自动插入到对应的位置。在大多数情况下极大改善了可读性及调试工作
- SQL 的耗时信息能被获取从而帮助判断哪些语句执行得过慢,同时这些信息可以被工具识别得到一个关于慢 SQL 的报表
- SQL 连接信息也可以获取从而帮助诊断关于连接池或线程的问题
- 兼容任何 JDBC 驱动,需要 JDK1.4 及以上与 Slf4j1.x 开源软件,使用 Apache 2.0 License
使用 Log4jdbc 的步骤
感兴趣的朋友可以去 Log4jdbc 的项目主页看它的使用方法,如果单纯使用 Log4jdbc ,不会对 ResultSet 以表格方式呈现,在这里我们使用扩展自 Log4jdbc 的日志框架 Log4jdbc-log4j2 ,它增加了对 ResultSet 以表格方式呈现的处理,项目主页是:https://code.google.com/p/log4jdbc-log4j2/。它的使用步骤如下:
1、决定使用哪个版本的 JAR 包:
如果使用 JDK1.5 , 应该使用 JDBC3 版本的 JAR 包即 log4jdbc-log4j2-jdbc3.jar 。
如果使用 JDK1.6 , 应该使用 JDBC4 版本的 JAR 包即 log4jdbc-log4j2-jdbc4.jar (即使实际使用的 JDBC 驱动是 JDBC3 的甚至更老)。
如果使用 JDK1.7 , 应该使用 JDBC4.1 版本的 JAR 包即 log4jdbc-log4j2-jdbc4.1.jar (即使实际使用的 JDBC 驱动是 JDBC3 的甚至更老)。
2、将 JAR 包添加进项目:
将 JAR 包添加进项目有两种方式,第一种是直接将 Log4jdbc-log4j2 和 Slf4j 的 JAR 包添加进 CLASSPATH 中,第二种是使用 MAVEN 方式引入 JAR 包,这里我们主要说明第二种方式。在 pom.xml 文件中,根据使用的 JDBC 驱动的版本来替换 log4jdbc-log4j2-jdbcXX (比如 log4jdbc-log4j2-jdbc4.1 , 或者 log4jdbc-log4j2-jdbc4 , 或者 log4jdbc-log4j2-jdbc3 )。该框架需要配合 Slf4j 一起使用,MAVEN 配置如下:
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbcXX</artifactId>
<version>1.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>
3、将项目的配置文件中的 JDBC 驱动类改成 net.sf.log4jdbc.sql.jdbcapi.DriverSpy 。
4、将 jdbc:log4 添加到现有的 JDBC URL 之前:
例如原来的 JDBC URL 是
jdbc:mysql://localhost:3306/MyDatabase
,则应该改成:
jdbc:log4jdbc:mysql://localhost:3306/MyDatabase
5、配置日志记录的种类:
Log4jdbc 用以下几个可以配置的日志种类:
jdbc.sqlonly : 仅记录 SQL
jdbc.sqltiming :记录 SQL 以及耗时信息
jdbc.audit :记录除了 ResultSet 之外的所有 JDBC 调用信息,会产生大量的记录,有利于调试跟踪具体的 JDBC 问题
jdbc.resultset :会产生更多的记录信息,因为记录了 ResultSet 的信息
jdbc.connection :记录连接打开、关闭等信息,有利于调试数据库连接相关问题
以上日志种类都可以设置为 DEBUG , INFO 或 ERROR 级别。当设置为 FATAL 或 OFF 时,意味关闭记录。
以下是一个采用 Log4j 作为具体日志系统的典型配置,将这些配置到 log4j.properties 里面:
log4j.logger.jdbc.sqlonly=OFF
log4j.logger.jdbc.sqltiming=INFO
log4j.logger.jdbc.audit=OFF
log4j.logger.jdbc.resultset=OFF
log4j.logger.jdbc.connection=OFF
6、添加 log4jdbc.log4j2.properties 文件:
这是最后一步,在项目的 CLASSPATH 路径下创建一个 log4jdbc.log4j2.properties 文件,告诉 Log4jdbc-log4j2 使用的是 Slf4j 来记录和打印日志,在该配置文件里增加:
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
最后,运行一下项目,看看效果。
问题记录
1.Apache Log4j2 远程代码执行高危漏洞 解决方案
Apache Log4j任意代码执行漏洞修复 spring-boot-starter-log4j2
Apache Log4j2 远程代码执行高危漏洞 解决方案
Apache Log4j2 远程代码执行漏洞(CVE-2021-44228 )风险紧急通告,腾讯安全全面支持检测拦截
2.打印sql 不同层级的包不打sql日志时,配置成最上级路径com.wds.demo即可
<springProfile name="dev,fat,prod">
<logger name="com.wds.demo.mapper" level="DEBUG"/>
</springProfile>
3.指定包日志级别为debug
<!-- 指定com.wds日志输出级别 DEBUG -->
<logger name="com.wds">
<level value="DEBUG"></level>
<appender-ref ref="STDOUT" />
</logger>
<!-- 全局设置日志输出级别 INFO -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>