为什么不用log4j了呢?
因为log4j和Logback都是同一个作者(ceki)写的,他本人说:log4j太烂了,不想再改了。所以写了一个log4j的升级版本,那就是Logback。我想开发者本人说的,应该够权威了吧!
怎么用好Logback(日志实现)呢?
和SLF4J(日志门面,和上面两个框架都是同一个作者写的)搭配使用,效果更佳!(springboot中用的也是这两个)
slf4j的简单使用
slf4j(Simple Logging Facade for Java,4是for的意思)作为日志门面,还是很不错的,举个例子:
一般我们都要传入类名对应的class对象给logger,如:
private final Logger log = LoggerFactory.getLogger(LogTest.class);
但是使用@Slf4j注解,程序就可以直接使用log了,还是挺方便的。
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
class RiverApplicationTests {
@Test
void logSomething() {
log.error("Slf4j");//可以直接使用log对象
}
}
说明:使用@Slf4j,需要添加相应的依赖和在idea中安装lombok插件。
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
</dependency>
还有如打印多个变量,也挺方便的:
//{}是占位符
log.info("userName: {}, password: {}", userName, password);
Logback的使用
可以有两种配置方式:一种是application.yml(功能简单),另一种是logback-spring.xml(功能强大)
application.yml配置(输出格式、输出路径和日志级别等)
logging:
pattern:
console: "%d -- %msg%n" #%d为日期,%msg为日志信息,%n是换行
file:
path: log #配置路径,如果没有设置name,默认会生成spring.log文件
#name: log/test.log
level:
root: info #根日志级别为info
com.boot.river.RiverApplicationTests: error #特定类的日志级别为error
输出日志信息的控制符如下:
%c: 输出日志信息所属的类目,通常就是所在类的全名
%L: 输出代码中的行号
%F: 输出日志消息产生时所在的文件名称
%m: 输出代码中指定的消息,产生的日志具体信息
%l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main (TestLog4.java:10)
%d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy年MM月dd日 HH:mm:ss},2019年12月26日 22:45:57
%p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
%r: 输出自应用启动到输出该log信息耗费的毫秒数
%t: 输出产生该日志事件的线程名
%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像Java servlets这样的多客户多线程的应用中。
%%: 输出一个”%”字符
%n: 输出一个回车换行符,Windows平台为”\r\n”,Unix平台为”\n”输出日志信息换行
logback-spring.xml配置(error和info信息分开打印、每天一个日志文件等)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>
%d -- %msg%n
</pattern>
</layout>
</appender>
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch><!--命中error日志,则不打印-->
<onMismatch>ACCEPT</onMismatch><!--没命中error日志,都打印出来-->
</filter>
<encoder>
<pattern>
%msg%n
</pattern>
</encoder>
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路径,日期作为文件名的一部分-->
<fileNamePattern>log/info.%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level><!--只打印error级别的日志,因为是ThresholdFilter,所以如果是WARN,则会打印WARN和ERROR日志-->
</filter>
<encoder>
<pattern>
%msg%n
</pattern>
</encoder>
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路径,日期作为文件名的一部分-->
<fileNamePattern>log/error.%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="consoleLog" />
<appender-ref ref="fileInfoLog" />
<appender-ref ref="fileErrorLog" />
</root>
</configuration>
觉得有用的老铁赞一下呗~