slf4j与log4j、logback选择与使用(倾向slf4j+logback)
slf4j与log4j、logback简介
1.是什么?
1)log4j(log for java)
Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程;这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
log4j是一个具体的日志框架,可以单独使用。
2)logback
logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现(即直接实现了slf4j的接口,而log4j并没有直接实现,所以就需要一个适配器slf4j-log4j12.jar),logback一共有以下几个模块:
logback-core:其它两个模块的基础模块
logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging
logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能
logback也是一个具体的日志框架,可以单独使用。
3)slf4j(simple logging facade for java)
slf4j意为Java简单日志门面,它是不同的日志系统进行的具体的抽象化,提供了统一的日志使用接口,使用时只需要按照其提供的接口方法进行调用即可。
注意:slf4j只是一个接口,不是具体的日志框架,使用的时候需要绑定具体的日志框架,才能实现具体的日志功能
slf4j调用逻辑:
2.怎么用
综合上面的介绍,我们有以下四种选择:
单独使用log4j
单独使用logback
使用slf4j + log4j
使用slf4j + logback
考虑到日志代码与日志框架的解耦,需要使用slf4j;考虑到日志功能对设备性能的影响,选用logback;故可以使用slf4j+logback,后面介绍也主要是这个组合。
logback相比于log4j的优势如下:
1)更快的执行速度: 基于我们先前在log4j上的工作,logback 重写了内部的实现,在某些特定的场景上面,甚至可以比之前的速度快上10倍。在保证logback的组件更加快速的同时,同时所需的内存更加少。
2)logback-classic 非常自然的实现了SLF4J:ogback-classic中的longging类自然的实现了SLF4J。当你使用 logback-classic作为底层实现时,涉及到LF4J日记系统的问题你完全不需要考虑。更进一步来说,由于 logback-classic强烈建议使用SLF4J作为客户端日记系统实现,如果需要切换到log4j或者其他,你只需要替换一个jar包即可,不需要去改变那些通过SLF4J API 实现的代码。这可以大大减少更换日记系统的工作量。
3)自动重新载入配置文件:Logback-classic可以在配置文件被修改后,自动重新载入。这个扫描过程很快,无资源争用,并且可以动态扩展支持在上百个线程之间每秒上百万个调用。它和应用服务器结合良好,并且在JEE环境通用,因为它不会调用创建一个单独的线程来做扫描。
优雅地从I/O错误中恢复:FileAppender和它的子类,包括RollingFileAppender,可以优雅的从I/O错误中恢复。所以,如果一个文件服务器临时宕机,你再也不需要重启你的应用,而日志功能就能正常工作。当文件服务器恢复工作,logback相关的appender就会透明地和快速的从上一个错误中恢复。
4)自动清除旧的日志归档文件:通过设置TimeBasedRollingPolicy 或者 SizeAndTimeBasedFNATP的 maxHistory 属性,你就可以控制日志归档文件的最大数量。如果你的回滚策略是每月回滚的,并且你希望保存一年的日志,那么只需简单的设置maxHistory属性为12。对于12个月之前的归档日志文件将被自动清除。
5)自动压缩归档日志文件:RollingFileAppender可以在回滚操作中,自动压缩归档日志文件。压缩通常是异步执行的,所以即使是很大的日志文件,你的应用都不会因此而被阻塞。
6)配置文件可以处理不同的情况,开发人员经常需要判断不同的Logback配置文件在不同的环境下(开发,测试,生产)。而这些配置文件仅仅只有一些很小的不同,可以通过,和来实现,这样一个配置文件就可以适应多个环境。
7)Filters(过滤器)有些时候,需要诊断一个问题,需要打出日志。在log4j,只有降低日志级别,不过这样会打出大量的日志,会影响应用性能。在Logback,你可以继续 保持那个日志级别而除掉某种特殊情况,如alice这个用户登录,她的日志将打在DEBUG级别而其他用户可以继续打在WARN级别。要实现这个功能只需加4行XML配置。可以参考MDCFIlter 。
8)logback原生支持同时按日期和文件大小分割日志,而log4j需要自己写代码实现
9)自动压缩已经打出来的log:RollingFileAppender在产生新文件的时候,会自动压缩已经打出来的日志文件。压缩是个异步过程,所以甚至对于大的日志文件,在压缩过程中应用不会受任何影响
3.Spring Boot工程使用slf4j + logback
1)配置依赖:
引入logback <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>${logback.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> 使用exclusions排除Spring-Boot-Starter引入的其他日志 <exclusions> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </exclusion> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-to-slf4j</artifactId> </exclusion> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </exclusions> spring本身日志就使用的commons-logging,仅仅去掉就会使其不能正常工作,还需要添加commons logging到slf4j的桥接器jcl-over-slf4j,如下在项目中添加该依赖: <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${jcl.over.slf4j.version}</version> </dependency>
2)配置logback
在 src\main\resources 路径下创建logback.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--> <property name="LOG_HOME" value="C:/Users/wangb/Desktop/logs/funds" /> <!--控制台日志, 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!--文件日志, 按照每天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 文件滚动策略:按照文件大小和日期滚动 --> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!--日志文件输出的文件名,%d{yyyy-MM-dd}表示日期,%i表示当前日期第i(0起)个文件--> <FileNamePattern>${LOG_HOME}/funds.log.%d{yyyy-MM-dd}.%i.log</FileNamePattern> <!--单个日志文件最大的大小--> <MaxFileSize>5MB</MaxFileSize> <!-- 总文件大小,当总的日志文件大小超过这个大小是,删除最早的文件 --> <totalSizeCap>200MB</totalSizeCap> <!--日志文件保留时间,单位与前面的FileNamePattern,如上面文件名时间部分格式为%d{yyyy-MM-dd},表示是天--> <MaxHistory>3</MaxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!--myibatis log configure--> <logger name="com.apache.ibatis" level="TRACE"/> <logger name="java.sql.Connection" level="DEBUG"/> <logger name="java.sql.Statement" level="DEBUG"/> <logger name="java.sql.PreparedStatement" level="DEBUG"/> <!-- 日志输出级别 --> <root level="DEBUG"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE"/> </root> </configuration>
4.补充slf4j
1)Slf4j日志级别:
Slf4j有四个级别的log level可供选择,级别从上到下由低到高,优先级高的将被打印出来。
Debug 简单来说,对程序调试有利的信息都可以debug输出
info 对用户有用的信息
warn 可能会导致错误的信息
error 顾名思义,发生错误的地方
5.补充logback
暂无