[整理]SpringBoot⽇志总结
⽬录
1. Java ⽇志概览
说到 Java ⽇志,很多初学者可能都⽐较懵,因为这⾥涉及到太多东西了:Apache Commons Logging、Slf4j、Log4j、Log4j2、Logback、Java Util Logging 等等,这些框架各⾃有什么作⽤?他们之间有什么区别?
1.1 总体概览
下⾯这张图很好的展⽰了 Java 中的⽇志体系:
可以看到,Java 中的⽇志框架主要分为两⼤类:⽇志门⾯和⽇志实现。
⽇志门⾯
⽇志门⾯定义了⼀组⽇志的接⼝规范,它并不提供底层具体的实现逻辑。Apache Commons Logging 和 Slf4j 就属于这⼀类。
⽇志实现
⽇志实现则是⽇志具体的实现,包括⽇志级别控制、⽇志打印格式、⽇志输出形式(输出到数据库、输出到⽂件、输出到控制台等)。Log4j、Log4j2、Logback 以及 Java Util Logging 则属于这⼀类。
将⽇志门⾯和⽇志实现分离其实是⼀种典型的门⾯模式,这种⽅式可以让具体业务在不同的⽇志实现框架之间⾃由切换,⽽不需要改动任何代码,开发者只需要掌握⽇志门⾯的API 即可。
⽇志门⾯是不能单独使⽤的,它必须和⼀种具体的⽇志实现框架相结合使⽤。
那么⽇志框架是否可以单独使⽤呢?
技术上来说当然没问题,但是我们⼀般不会这样做,因为这样做可维护性很差,⽽且后期扩展不易。
例如 A 开发了⼀个⼯具包使⽤ Log4j 打印⽇志,B 引⽤了这个⼯具包,但是 B 喜欢使⽤ Logback 打印⽇志,此时就会出现⼀个业务使⽤两个甚⾄多个⽇志框架,开发者也需要维护多个⽇志的配置⽂件。因此我们都是⽤⽇志门⾯打印⽇志。
1.2 ⽇志级别
使⽤⽇志级别的好处在于,调整级别,就可以屏蔽掉很多调试相关的⽇志输出。不同的⽇志实现定义的⽇志级别不太⼀样,不过也都⼤同⼩异。
Java Util Logging
Java Util Logging 定义了 7 个⽇志级别,从严重到普通依次是:
1. SEVERE [sɪ'vɪə]严重的
2. WARNING
3. INFO
4. CONFIG
5. FINE
6. FINER
7. FINEST
因为默认级别是 INFO,因此 INFO 级别以下的⽇志,不会被打印出来。
Log4j
Log4j 定义了 8 个⽇志级别(除去 OFF 和 ALL,可以说分为 6 个级别),从严重到普通依次是:log4j2 appender
1. OFF:最⾼等级的,⽤于关闭所有⽇志记录。
2. FATAL:重⼤错误,这种级别可以直接停⽌程序了。
3. ERROR:打印错误和异常信息,如果不想输出太多的⽇志,可以使⽤这个级别。
4. WARN:警告提⽰。
5. INFO:⽤于⽣产环境中输出程序运⾏的⼀些重要信息,不能滥⽤。
6. DEBUG:⽤于开发过程中打印⼀些运⾏信息。
7. TRACE
8. ALL 最低等级的,⽤于打开所有⽇志记录。
Logback
Logback ⽇志级别⽐较简单,从严重到普通依次是:
1. ERROR
2. WARN
3. INFO
4. DEBUG
5. TRACE
1.3 综合对⽐
Java Util Logging 系统在 JVM 启动时读取配置⽂件并完成初始化,⼀旦应⽤程序开始运⾏,就⽆法修改配置。
另外,这种⽇志实现配置也不太⽅便,只能在 JVM 启动时传递参数,像下⾯这样:
-Djava.fig.file=<config-file-name>。
由于这些局限性,导致 Java Util Logging 并未⼴泛使⽤。
Log4j 虽然配置繁琐,但是⼀旦配置完成,使⽤起来就⾮常⽅便,只需要将相关的配置⽂件放到 classpath 下即可。在很多情况下,Log4j 的配置⽂件我们可以在不同的项⽬中反复使⽤。
Log4j 可以和 Apache Commons Logging 搭配使⽤,Apache Commons Logging 会⾃动搜索并使⽤ Log4j,如果没有到 Log4j,再使⽤ Java Util Logging。
⽐ Log4j + Apache Commons Logging 组合更得⼈⼼的是 Slf4j + Logback 组合。
Logback 是 Slf4j 的原⽣实现框架,它也出⾃ Log4j 作者(Ceki Gülcü)之⼿,但是相⽐ Log4j,它拥有更多的优点、特性以及更强的性能。
1.4 最佳实践
如果不想添加任何依赖,使⽤ Java Util Logging 或框架容器已经提供的⽇志接⼝。
如果⽐较在意性能,推荐:Slf4j + Logback。
如果项⽬中已经使⽤了 Log4j 且没有发现性能问题,推荐组合为:Slf4j + Log4j2。
2. Spring Boot ⽇志实现
Spring Boot 使⽤ Apache Commons Logging 作为内部的⽇志框架门⾯,它只是⼀个⽇志接⼝,在实际应⽤中需要为该接⼝来指定相应的⽇志实现。
Spring Boot 默认的⽇志实现是 Logback。这个很好查看:随便启动⼀个 Spring Boot 项⽬,从控制台⼀⾏⽇志,例如下⾯这样:
如果不⼀样,则在application.properties或l配置:spring.profiles.active=prod
考虑到最后的 prod 是⼀个可以变化的字符,我们在项⽬中全局搜索:The following profiles are active,结果如下:
在⽇志输出的那⼀⾏ debug。然后再次启动项⽬,如下图:
此时我们就可以看到真正的⽇志实现是 Logback。
其他的诸如 Java Util Logging、Log4j 等框架,Spring Boot 也有很好的⽀持。
在 Spring Boot 项⽬中,只要添加了如下 web 依赖,⽇志依赖就⾃动添加进来了:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.1 Spring Boot ⽇志配置
Spring Boot 的⽇志系统会⾃动根据 classpath 下的内容选择合适的⽇志配置,在这个过程中⾸选 Logback。
如果开发者需要修改⽇志级别,只需要在 application.properties ⽂件中通过logging.level 前缀+包名的形式进⾏配置即可,例如下⾯这样:springframework.web=debug
hibernate=error
如果你想将⽇志输出到⽂件,可以通过如下配置指定⽇志⽂件名:
logging.file.name=javaboy.log
logging.file.name 可以只指定⽇志⽂件名,也可以指定⽇志⽂件全路径,例如下⾯这样:
logging.file.name=/Users/sang/Documents/javaboy/javaboy.log
如果你只是想重新定义输出⽇志⽂件的路径,也可以使⽤ logging.file.path 属性,如下:
logging.file.path=/Users/sang/Documents/javaboy
如果想对输出到⽂件中的⽇志进⾏精细化管理,还有如下⼀些属性可以配置:
llingpolicy.file-name-pattern:⽇志归档的⽂件名,⽇志⽂件达到⼀定⼤⼩之后,⾃动进⾏压缩归档。
llingpolicy.clean-history-on-start:是否在应⽤启动时进⾏归档管理。
llingpolicy.max-file-size:⽇志⽂件⼤⼩上限,达到该上限后,会⾃动压缩。
al-size-cap:⽇志⽂件被删除之前,可以容纳的最⼤⼤⼩。
llingpolicy.max-history:⽇志⽂件保存的天数。
⽇志⽂件归档这块,⼩伙伴们感兴趣可以⾃⼰试下,可以⾸先将 max-file-size 属性调⼩,这样⽅便看到效果:
llingpolicy.max-file-size=1MB
然后添加如下接⼝:
@RestController
public class HelloController {
private static final Logger logger = getLogger(HelloController.class);
@GetMapping("/hello")
public void hello() {
for (int i = 0; i < 100000; i++) {
logger.info("hello javaboy");
}
}
}
访问该接⼝,可以看到最终⽣成的⽇志⽂件被⾃动压缩了:
application.properties 中还可以配置⽇志分组。
⽇志分组能够把相关的 logger 放到⼀个组统⼀管理。
例如我们可以定义⼀个 tomcat 组:
然后统⼀管理 tomcat 组中的所有 logger:
at=TRACE
Spring Boot 中还预定义了两个⽇志分组 web 和 sql,如下:
不过在 application.properties 中只能实现对⽇志⼀些⾮常简单的配置,如果想实现更加细粒度的⽇志配置,那就需要使⽤⽇志实现的原⽣配置;例如 Logback 的 l,Log4j 的 l 等。
如果这些⽇志配置⽂件存在于 classpath 下,那么默认情况下,Spring Boot 就会⾃动加载这些配置⽂件。
2.2 Logback 配置
2.2.1 基本配置
默认的 Logback 配置⽂件名有两种:
Spring Boot 中为 Logback 提供了四个默认的配置⽂件,位置在 org/springframework/boot/logging/logback/,分别是:
如果需要⾃定义 l ⽂件,可以在⾃定义时使⽤这些默认的配置⽂件,也可以不使⽤。⼀个典型的 l ⽂件如下(l):<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/l"/>
<include resource="org/springframework/boot/logging/l" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
<logger name="org.springframework.web" level="DEBUG"/>
</configuration>
可以通过 include 引⼊ Spring Boot 已经提供的配置⽂件,也可以⾃定义。
2.2.2 输出到⽂件
如果想禁⽌控制台的⽇志输出,转⽽将⽇志内容输出到⼀个⽂件,我们可以⾃定义⼀个 l ⽂件,并引⼊前⾯所说的 l ⽂件。像下⾯这样(l):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/l" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${pdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/l" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
2.3 Log4j 配置
如果 classpath 下存在 Log4j2 的依赖,Spring Boot 会⾃动进⾏配置。
默认情况下 classpath 下当然不存在 Log4j2 的依赖,如果想使⽤ Log4j2,可以排除已有的 Logback,然后再引⼊ Log4j2,如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
Log4j2 的配置就⽐较容易了,在 reources ⽬录下新建 l ⽂件,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="warn">
<properties>
<Property name="app_name">logging</Property>
<Property name="log_path">logs/${app_name}</Property>
</properties>
<appenders>
<console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%d][%t][%p][%l] %m%n" />
</console>
<RollingFile name="RollingFileInfo" fileName="${log_path}/info.log"
filePattern="${log_path}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%">
<Filters>
<ThresholdFilter level="INFO" />
<ThresholdFilter level="WARN" onMatch="DENY"
onMismatch="NEUTRAL" />
</Filters>
<PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<SizeBasedTriggeringPolicy size="2 MB" />
</Policies>
<DefaultRolloverStrategy compressionLevel="0" max="10"/>
</RollingFile>
<RollingFile name="RollingFileWarn" fileName="${log_path}/warn.log"
filePattern="${log_path}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%">
<Filters>
<ThresholdFilter level="WARN" />
<ThresholdFilter level="ERROR" onMatch="DENY"
onMismatch="NEUTRAL" />
</Filters>
<PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<SizeBasedTriggeringPolicy size="2 MB" />
</Policies>
<DefaultRolloverStrategy compressionLevel="0" max="10"/>
</RollingFile>
<RollingFile name="RollingFileError" fileName="${log_path}/error.log"
filePattern="${log_path}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%">
<ThresholdFilter level="ERROR" />
<PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<SizeBasedTriggeringPolicy size="2 MB" />
</Policies>
<DefaultRolloverStrategy compressionLevel="0" max="10"/>
</RollingFile>
</appenders>
<loggers>
<root level="info">
<appender-ref ref="Console" />
<appender-ref ref="RollingFileInfo" />
<appender-ref ref="RollingFileWarn" />
<appender-ref ref="RollingFileError" />
</root>
</loggers>
</configuration>
说明:
⾸先在 properties 节点中指定了应⽤名称以及⽇志⽂件位置。
然后通过⼏个不同的 RollingFile 对不同级别的⽇志分别处理,不同级别的⽇志将输出到不同的⽂件,并
按照各⾃的命名⽅式进⾏压缩。这段配置⽐较程式化,⼩伙伴们可以保存下来做成 IntelliJ IDEA 模版以便⽇常使⽤。
3.⼩结
这就是 Spring Boot ⽇志了,整体来说并不难。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论