聊聊日常开发中,你会选择哪款Log框架?

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

本篇文章主要讲解我在工作中是使用什么日志框架,因为大家都知道:适合的才是最好的。springboot 相信大家都用过吧,是的,关于日志的选择,springboot 都帮我们做好了,它的日志门面选用的就是 SLF4J,而日志实现选用的是Logback

至于它为什么会这样选择?我觉得还是有一定的道理的。至于门面为什么选择SLF4J,不作过多赘述,还是来聊聊实现为什么选择Logback吧。

Logback 作为流行的 log4j 项目的继承者。这两个框架都是同一个人写的,性能比 log4j 要好。至于 log4j2 ,它是log4j 1.x 的升级版,参考了 logback 的一些优秀的设计,并且修复了一些问题,因此带来了一些重大的提升。为什么没有选择它呢?我认为还是因为其他的一些框架没有更好的和log4j2 进行适配起来。导致现在流行的日志框架都还是选择Logback

日志的用途

日志的用途大致可以归纳成以下三种:

  • 问题追踪:通过日志不仅仅包括我们程序的一些bug,也可以在安装配置时,通过日志可以发现问题。
  • 状态监控:通过实时分析日志,可以监控系统的运行状态,做到早发现问题、早处理问题。
  • 安全审计:审计主要体现在安全上,通过对日志进行分析,可以发现是否存在非授权的操作。

日志的级别

数字越大,级别越高,框架只会输出大于等于当前日志级别的信息。

  • ERROR 40
  • WARN 30
  • INFO 20
  • DEBUG 10
  • TRACE 0

Slf4j的使用

springboot默认帮我们配置好了日志。spring-boot-starter这个依赖里面已经为我们集成好了,自己去看看。

第一种方式

1
2
3
4
5
java复制代码private static final Logger logger = LoggerFactory.getLogger(Test.class);

logger.info();

...

默认的级别上info,按上面的排名只会输出 info、warn、error级别以上的日志。

在获取logger对象时,一般都是将本类的class传递进去,在默认的格式在日志输出时会把每条日志信息所在的class名输出出来。

第二种方式

使用 Lombok

Lombok不仅仅提供了强大的@Data注解,同时支持日志相关。

@Slf4j添加在类上,我们就不用再手动的获取Logger对象了,而是直接使用log。

1
2
3
java复制代码log.debug("dubug..."); 
log.info("info...");
log.error("error...");

输出格式

1
2
java复制代码log.info("name = " + name + " ,age = " + age);
log.info("name:{},age: {}", name, age);

配置文件

我们可以在配置文件中修改日志的默认配置。

image-20210926113424811

logback-spring.xml

下面是我经常用到的一些配置,你们可以根据自己的需要进行一些修改,文件默认放在resources目录下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
xml复制代码<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--设置存储路径变量-->
<property name="LOG_HOME" value="./logs"/>

<!--控制台输出appender-->
<appender name="console" 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>
<!--设置编码-->
<charset>UTF-8</charset>
</encoder>
</appender>

<!--打印所有日志-->
<appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--日志名,指定最新的文件名,其他文件名使用FileNamePattern -->
<File>${LOG_HOME}/log.log</File>
<!--文件滚动模式 按照时间,每天产生一个-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名,使用gz压缩-->
<FileNamePattern>${LOG_HOME}/log.%d{yyyy-MM-dd}.log.gz</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
<!--按大小分割同一天的-->
<!-- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">-->
<!-- <maxFileSize>100MB</maxFileSize>-->
<!-- </timeBasedFileNamingAndTriggeringPolicy>-->
</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>
<!--设置编码-->
<charset>UTF-8</charset>
</encoder>
<!--在root指定的级别之上再次进行过滤,输出大于等于level,可通过onMatch和onMisMatch来确定只输出某个级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
</filter>
</appender>

<!--打印Error日志-->
<appender name="errorLogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--日志名,指定最新的文件名,其他文件名使用FileNamePattern -->
<File>${LOG_HOME}/error.log</File>
<!--文件滚动模式 按照时间,每天产生一个-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名,使用gz压缩-->
<FileNamePattern>${LOG_HOME}/error.%d{yyyy-MM-dd}.log.gz</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</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>
<!--设置编码-->
<charset>UTF-8</charset>
</encoder>

<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!--设置日志级别,过滤掉info日志,只输入error日志-->
<level>ERROR</level>
</filter>
</appender>


<!--指定基础的日志输出级别-->
<root level="INFO">
<!--appender将会添加到这个loger-->
<appender-ref ref="console"/>
<appender-ref ref="logFile"/>
<appender-ref ref="errorLogFile"/>
</root>
</configuration>

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
java复制代码import lombok.extern.slf4j.Slf4j;

@Slf4j
public class TestService
{

public static void main(String[] args)
{
log.info("info信息");
log.warn("warn信息");
log.error("error信息");
}
}

小结

以上就是我平时在工作中用到日志框架的简单的使用。同时也提醒大家,在输出日志的时候要谨慎,由于输出log过程需要进行磁盘操作,所以log信息一定要言简意赅,不要输出一些无用的log

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%