1. 简介
1.1 认识日志框架
在项目开发中,使用日志非常重要,不管是记录运行情况还是定位线上问题,都离不开对日志的分析。在 Java 领域里存在着多种日志框架,如 JCL、SLF4J、Jboss-logging、jUL、log4j、log4j2、logback 等等。
| 日志分类 | 描述 | 举例 |
|---|---|---|
| 日志门面(日志抽象层) | 为 Java 日志访问提供一套标准和规范的 API 框架,其主要意义在于提供接口。 | JCL(Jakarta Commons Logging)、SLF4j(Simple Logging Facade for Java)、jboss-logging |
| 日志实现 | 日志门面的具体的实现 | Log4j、JUL(java.util.logging)、Log4j2、Logback |
通常情况下,日志由一个日志门面和日志实现组合搭建而成,SpringBoot 选用的是 SLF4j + logback。
SLF4J 是目前市面上最流行的日志门面,它是把不同的日志系统的实现进行了具体的抽象化,只提供了统一的日志使用接口,使用时只需要按照其提供的接口方法进行调用即可,由于它只是一个接口,并不是一个具体的可以直接单独使用的日志框架,所以最终日志的格式、记录级别、输出方式等都要通过接口绑定的具体的日志系统来实现,这些具体的日志系统就有 log4j,logback,java.util.logging 等,它们才实现了具体的日志系统的功能。
Logback 是 Log4j 的改进版本,而且原生支持 SLF4J(因为是同一作者开发的),因此 Logback+SLF4J 的组合是日志框架的最佳选择,而且 Logback 的配置可以是 XML 或 Groovy 代码。
1.2 日志级别
常见的日志级别如下(优先级依次升高)。
| 序号 | 日志级别 | 说明 |
|---|---|---|
| 1 | trace | 追踪,指明程序运行轨迹。 |
| 2 | debug | 调试,实际应用中一般将其作为最低级别,而 trace 则很少使用。 |
| 3 | info | 输出重要的信息,使用较多。 |
| 4 | warn | 警告,使用较多。 |
| 5 | error | 错误信息,使用较多。 |
1.3 日志输出格式
| 序号 | 输出格式 | 说明 |
|---|---|---|
| 1 | %d{yyyy-MM-dd HH:mm:ss, SSS} | 日志生产时间,输出到毫秒的时间 |
| 2 | %-5level | 输出日志级别,-5 表示左对齐并且固定输出 5 个字符,如果不足在右边补 0 |
| 3 | %logger 或 %c | logger 的名称 |
| 4 | %thread 或 %t | 输出当前线程名称 |
| 5 | %p | 日志输出格式 |
| 6 | %message 或 %msg 或 %m | 日志内容,即 logger.info(“message”) |
| 7 | %n | 换行符 |
| 8 | %class 或 %C | 输出 Java 类名 |
| 9 | %file 或 %F | 输出文件名 |
| 10 | %L | 输出错误行号 |
| 11 | %method 或 %M | 输出方法名 |
| 12 | %l | 输出语句所在的行数, 包括类名、方法名、文件名、行数 |
| 13 | hostName | 本地机器名 |
| 14 | hostAddress | 本地 ip 地址 |
1.4 yaml中配置日志级别
可以在 yaml 配置文件中设置日志级别,但一般我们会在 logback.xml 中进行配置。
logging: # 设置日志级别level:com:xuwei:platformserver:trace
2. Slf4j+Logback使用
2.1 引入所需依赖
Spring Boot 的核心启动器 spring-boot-starter 引入了 spring-boot-starter-logging,spring-boot-starter-logging 的 Maven 依赖不但引入了 logback-classic (包含了日志框架 SLF4J 的实现),还引入了 log4j-to-slf4j(log4j 的替换包),jul-to-slf4j (JUL 的替换包)。
<!-- 日志框架 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency>
2.2 排除第三方框架依赖日志框架
当我们引入了依赖了其他日志框架的第三方框架(例如 Hibernate)时,只需要把这个框架所依赖的日志框架排除,即可实现日志框架的统一:
<dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-console</artifactId><version>${activemq.version}</version><exclusions><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency>
2.3 slf4j 简单使用。
@SpringBootTest@Slf4jclass PlatformServerApplicationTests {private static final Logger logger = LoggerFactory.getLogger(PlatformServerApplicationTests.class);@Testvoid contextLoads() {//日志级别 由低到高logger.trace("trace 级别日志");logger.debug("debug 级别日志");logger.info("info 级别日志");logger.warn("warn 级别日志");logger.error("error 级别日志");}// 和上面功能一样,需引入lombok依赖@Testvoid slf4jTest() {log.trace("trace 级别日志");log.debug("debug 级别日志");log.info("info 级别日志");log.warn("warn 级别日志");log.error("error 级别日志");}}
2.4 设计 logback.xml 文件。
<?xml version="1.0" encoding="UTF-8"?><configuration scan="true" scanPeriod="60 seconds" debug="false"><!-- 日志存放路径 --><property name="log.path" value="logs/platform-server" /><!-- 日志输出格式 --><property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" /><!-- 控制台输出 --><appender name="console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${log.pattern}</pattern></encoder></appender><!-- 系统日志输出 --><appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/info.log</file><!-- 循环政策:基于时间创建日志文件 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 日志文件名格式 --><fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern><!-- 日志最大的历史 60天 --><maxHistory>60</maxHistory></rollingPolicy><encoder><pattern>${log.pattern}</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 过滤的级别 --><level>INFO</level><!-- 匹配时的操作:接收(记录) --><onMatch>ACCEPT</onMatch><!-- 不匹配时的操作:拒绝(不记录) --><onMismatch>DENY</onMismatch></filter></appender><appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/error.log</file><!-- 循环政策:基于时间创建日志文件 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 日志文件名格式 --><fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern><!-- 日志最大的历史 60天 --><maxHistory>60</maxHistory></rollingPolicy><encoder><pattern>${log.pattern}</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 过滤的级别 --><level>ERROR</level><!-- 匹配时的操作:接收(记录) --><onMatch>ACCEPT</onMatch><!-- 不匹配时的操作:拒绝(不记录) --><onMismatch>DENY</onMismatch></filter></appender><!-- 系统模块日志级别控制 --><logger name="com.xuwei.platformserver" level="info" /><!-- Spring日志级别控制 --><logger name="org.springframework" level="warn" /><root level="info"><appender-ref ref="console" /></root><!--系统操作日志--><root level="info"><appender-ref ref="file_info" /><appender-ref ref="file_error" /></root></configuration>
