1. slf4j、log4j、logback是什么?
1.1 slf4j(simple logging facade for java)
SLF4J
意为 Java 简单日志门面,它是把不同的日志系统的实现进行了具体的抽象化,只提供了统一的日志使用接口,使用时只需要按照其提供的接口方法进行调用即可。
由于SLF4J
只是一个接口,不是具体的日志框架,使用的时候需要绑定具体的日志框架,才能实现具体的日志功能,这些具体的日志系统就有log4j
、logback
、java.util.logging
等,它们才实现了具体的日志系统的功能。
1.2 log4j(log for java)
Log4j
是 Apache 的一个开源项目,通过使用Log4j
,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
1.3 logback
logback
同样是由 log4j 的作者设计完成的,拥有更好的特性,用来取代 log4j 的一个日志框架,是slf4j
的原生实现。(即直接实现了slf4j
的接口,而log4j
并没有直接实现,所以就需要一个适配器slf4j-log4j12.jar
),logback一共有以下几个模块:
logback-core
:其它两个模块的基础模块logback-classic
:它是 log4j 的一个改良版本,同时它完整实现了slf4j API,使你可以很方便地更换成其它日志系统,如 log4j 或 JDK14 Logginglogback-access
:访问模块与 Servlet 容器集成提供通过 Http 来访问日志的功能
同样,单独使用它时,需要引入以上 jar,然后进行配置文件的配置,最后就是在相关类中进行使用。
联系
SLF4J
原理很简单,他只提供一个核心包:slf4j-api.jar
,结合其他框架 jar 包情况为:
- SLF4J 和 logback 结合:slf4j-api.jar、logback-classic.jar、logback-core.jar
- SLF4J 和 log4j 结合:slf4j-api.jar、slf4j-log4j.jar、log4j.jar
- SLF4J 和 JDK中java.util.logging 结合:slf4j-api.jar、slf4j-jdk14.jar
使用
为什么要使用SLF4J?
- slf4j是一个日志接口,自己没有具体实现日志系统,只提供了一组标准的调用api,这样将调用和具体的日志实现分离,使用slf4j后有利于根据自己实际的需求更换具体的日志系统,比如,之前使用的具体的日志系统为log4j,想更换为logback时,只需要删除log4j相关的jar,然后加入logback相关的jar和日志配置文件即可,而不需要改动具体的日志输出方法。
- 如果你开发的是一个面向公众使用的组件或公共服务模块,那么一定要使用slf4的这种形式,这有利于别人在调用你的模块时保持和他系统中使用统一的日志输出。
- slf4j日志输出时可以使用{}占位符,如,
logger.info("testlog: {}", "test")
,而如果只使用log4j做日志输出时,只能以logger.info("testlog:"+"test")
这种形式,前者要比后者在性能上更好,后者采用+连接字符串时就是new 一个String 字符串,在性能上就不如前者。
log4j、logback 均是具体的日志框架,可以单独使用,也可以结合 slf4j 使用。单独使用,分别调用框架自己的方法来输出日志信息;绑定 slf4j 一起使用,调用 slf4j 的 api 来输入日志信息。
考虑到日志代码与日志框架的解耦,需要使用 slf4j;考虑到日志功能对设备性能的影响,选用 logback;故可以使用组合slf4j + logback
。
2. logback使用步骤
2.1 加入依赖
Logback 使用 Java 的简单日志记录外观(SLF4J)作为其接口。我们需要将 Logback 和 SLF4J 所需 Jar
pom.xml:
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
<scope>test</scope>
</dependency>
<!-- logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
2.2 logback.xml配置文件
将logback.xml
加入到项目的 resource 目录下。
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<contextName>logback</contextName>
<!-- 1.1、读取spring环境变量 -->
<springProperty scope="context" name="SERVER_NAME" source="spring.application.name" defaultValue="SpringBootDemo"/>
<!-- 1.2、定义参数 -->
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
<!-- 项目路径,可用绝对路径,也可用相对路径,如下是用的相对路径,系统会自动在项目所在的盘符创建文件夹 -->
<property name="log.path" value="D:/zndl/logs" />
<property name="log.maxHistory" value="365" />
<!-- 2.1、彩色日志格式 -->
<!-- 配置格式变量:CONSOLE_LOG_PATTERN 彩色日志格式 -->
<!-- magenta:洋红 -->
<!-- boldMagenta:粗红-->
<!-- cyan:青色 -->
<!-- white:白色 -->
<!-- magenta:洋红 -->
<property name="CONSOLE_LOG_PATTERN"
value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/>
<!-- 2.2、常规日志格式 -->
<!-- 格式化输出:%d:表示日期 %thread:表示线程名 %-5level:级别从左显示5个字符宽度 %msg:日志消息 %n:是换行符-->
<property name="log.pattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - [%method,%line] - %msg%n" />
<!-- 3.1、输出控制台设置 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- 此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息 -->
<!-- 例如:如果此处配置了INFO级别,则后面其他位置即使配置了DEBUG级别的日志,也不会被输出 -->
<!--
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
-->
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<!-- <charset>UTF-8</charset> -->
</encoder>
</appender>
<!-- 3.2、输出到文件设置 -->
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 日志文件的路径及文件名 -->
<file>${log.path}/${SERVER_NAME}/log_info.log</file>
<!-- 日志文件输出格式 -->
<encoder>
<pattern>${log.pattern}</pattern>
<!-- 此处设置字符集 -->
<!-- <charset>UTF-8</charset> -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/${SERVER_NAME}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- 文件最大保存历史数量 -->
<MaxHistory>${log.maxHistory}</MaxHistory>
</rollingPolicy>
<!-- 此日志文件只记录 info 级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:允许写入日志 -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:禁止写入 -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 日志文件的路径及文件名 -->
<file>${log.path}/${SERVER_NAME}/log_warn.log</file>
<!-- 日志文件输出格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<!-- <charset>UTF-8</charset> -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${SERVER_NAME}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录 warn 级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 日志文件的路径及文件名 -->
<file>${log.path}/${SERVER_NAME}/log_error.log</file>
<!-- 日志文件输出格式 -->
<encoder>
<pattern>${log.pattern}</pattern>
<!-- <charset>UTF-8</charset> -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${SERVER_NAME}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录 ERROR 级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
<logger>:用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。
<logger>:仅有一个name属性,一个可选的level和一个可选的addtivity属性。
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
如果未设置此属性,那么当前logger将会继承上级的级别。
-->
<!--
使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别。
-->
<!--
<root>节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认是DEBUG
可以包含零个或多个appender元素。
-->
<!--
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
-->
<!-- 4、指定需要输出的项目 -->
<!-- 开发环境 spring.profiles.active=dev -->
<springProfile name="dev">
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
<!-- 可以输出项目中的debug日志,包括mybatis的sql日志;也可以指定mybatis的mapper包日志级别 -->
<!-- <logger name="com.ymqx" level="DEBUG" /> -->
<logger name="com.ymqx.mapper" level="DEBUG" />
</springProfile>
<!-- 生产环境 spring.profiles.active=dev -->
<springProfile name="pro">
<root level="INFO">
<!-- 生产环境最好不配置console写文件 -->
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
<!-- 生产环境, 指定某包日志为warn级 -->
<logger name="com.ymqx.except" level="warn"/>
</springProfile>
</configuration>
logback配置属性详解:
根节点<configuration>
<configuration scan="true" scanPeriod="10 seconds" debug="false">
<!-- 其他配置省略-->
</configuration>
- scan : 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
- scanPeriod : 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
- debug : 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
子节点<property>
<property name="log.path" value="D:/zndl/logs" />
property
用来定义变量值的标签,定义变量后,可以使${}
来使用变量。
- name:变量的名称
- value:变量定义的值
子节点<springProperty>
多环境配置下,通过 application.yml 传递参数过来,<property>
取不到环境参数,用<springProperty>
读取 spring 环境变量。
<springProperty scope="context" name="SERVER_NAME" source="spring.application.name" defaultValue="SpringBootDemo"/>
- name:变量的名称
- source:application.yml 配置的属性值
子节点<appender>
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 日志文件的路径及文件名 -->
<file>${log.path}/${SERVER_NAME}/log_info.log</file>
<!-- 日志文件输出格式 -->
<encoder>
<pattern>${log.pattern}</pattern>
<!-- 此处设置字符集 -->
<!-- <charset>UTF-8</charset> -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/${SERVER_NAME}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- 文件最大保存历史数量 -->
<MaxHistory>${log.maxHistory}</MaxHistory>
</rollingPolicy>
<!-- 此日志文件只记录 info 级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:允许写入日志 -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:禁止写入 -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
appender
用来格式化日志输出。
- name:名称
- class:class用来指定哪种输出策略,常用就是
控制台输出策略ConsoleAppender
和文件输出策略RollingFileAppender
。
ConsoleAppender策略
将日志信息打印到控制台上,更加准确的说:使用 System.out 或者 System.err 方式输出,主要子标签有:filter、encoder
FileAppender策略
用于将日志信息输出到文件中,主要子标签有:append,encoder,file。
RollingFileAppender策略
RollingFileAppender
继承FIleAppender
。功能:能够动态的创建一个文件。也就是说:到满足一定的条件,就会创建一个新的文件,然后将日志写入到新的文件中。有两个重要的标签与 RollingFileAppender 进行交互:RollingPolicy
、TriggeringPolicy
,主要子标签:file,append,encoder,rollingPolicy,triggerPolicy
以下分别介绍 appender 子标签:
file
被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。
append
如果是 true,日志被追加到文件结尾,如果是 false,清空现存文件,默认是true
。
encoder
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<!-- <charset>UTF-8</charset>-->
</encoder>
- %d{HH:mm:ss.SSS}:输出日志的打印日志,模式语法与 java.text.SimpleDateFormat 兼容。
- %t / %thread:输出产生日志的线程名。
- %-5level:日志级别,并且使用5个字符靠左对齐。
- %logger{length}:输出日志的logger名,可有一个整形参数,功能是缩短logger名,设置为0表示只输入logger最右边。
- %msg:表示打印输出的消息。
- %n:表示换行
filter
当满足过滤器指定的条件时,才记录日志(不满足条件时,拒绝记录日志)。logback 支持自定义过滤器,当然 logback 也自带了一些常用的过滤器,在绝大多数时候,自带的过滤器其实就够用了,一般是不需要自定义过滤器的。
过滤器 | 来源 | 说明 | 相对常用 |
---|---|---|---|
LevelFilter | Filter | 对 指定 level 的日志进行记录,对不等于指定 level 的日志不记录 | 是 |
ThresholdFilter | Filter | 对 大于或等于指定 level 的日志进行记录,对小于指定 level 的日志不记录 | 是 |
EvaluatorFilter | Filter | 对满足指定表达式的日志进行记录,对不满足指定表达式的日志不作记录 | 是 |
MarkerFilter | TurboFilter | 针对带有指定标记的日志,进行记录(或不作记录) | 否 |
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
ThresholdFilter
来过滤掉 ERROR 级别以下的日志不输出到文件中。
<!-- 此日志文件只记录 info 级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:允许写入日志 -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:禁止写入 -->
<onMismatch>DENY</onMismatch>
</filter>
- ACCEPT:表示不用看后面的过滤器了,这里就给直接同意了,需要记录。
- DENY:表示不用看后面的过滤器了,这里就给拒绝了,不作记录。
- NEUTRAL:表示需不需要记录,还需要看后面的过滤器。若所有过滤器返回的全部都是NEUTRAL,那么需要记录日志。
rollingPolicy
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/${SERVER_NAME}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>30</maxHistory>
</rollingPolicy>
子节点<logger>
<logger name="com.ymqx.mapper" level="DEBUG" />
logger
节点,可选节点,用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>
,它将会覆盖 root 的输出级别。属性包含name属性,一个可选的level、一个可选的addtivity属性。
- name:用来指定受此 logger 约束的某一个包或者具体的某一个类。
- level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前 logger 将会继承上级的级别。
- addtivity:是否向上级传递打印信息。
默认是true
。
注意:addtivity默认值是true,打印信息默认向上级传递,有可能会打印两次。(logger本身打印一次,root接到后又打印一次。)
子节点<root>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
root
节点是必选节点,用来指定最基础的日志输出级别,只有一个 level 属性。level 默认是DEBUG
。可以包含零个或多个 appender 元素。
多环境配置 <springProfile>
<!-- 开发环境 spring.profiles.active=dev -->
<springProfile name="dev">
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
<!-- 可以指定输出项目中的debug日志,包括mybatis的sql日志;也可以直接指定mybatis的mapper包日志级别 -->
<!-- <logger name="com.ymqx" level="DEBUG" /> -->
<logger name="com.ymqx.mapper" level="DEBUG" />
</springProfile>
<!-- 生产环境 spring.profiles.active=pro -->
<springProfile name="pro">
<root level="INFO">
<!-- 生产环境最好不配置console写文件 -->
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
<!-- 生产环境, 指定某包日志为warn级 -->
<logger name="com.ymqx.except" level="warn"/>
</springProfile>
通过 application.yml 的参数spring.profiles.active
指定
2.3 项目中使用日志进行记录
public class Example {
private static final Logger log = LoggerFactory.getLogger(Example.class);
public static void main(String[] args) {
log.debug("debug");
log.info("info");
log.warn("warn");
log.error("error");
log.info("Example log from {}", Example.class.getSimpleName());
}
}
2.4 搭配lombok来省略创建Logger对象
可以搭配 lombok 来使用,在类上面加上@Slf4j
注解来省略创建 Logger 对象。@Slf4j
注解在类上,为类提供一个属性名为log
的 slf4j 日志对象。
@Slf4j
public class Example {
public static void main(String[] args) {
log.debug("debug");
log.info("info");
log.warn("warn");
log.error("error");
log.info("Example log from {}", Example.class.getSimpleName());
}
}
3. SpringBoot使用logback
SpringBoot 默认日志系统就是 LogBack。如果不需要更改为其他日志系统如:Log4j2 等,则无需多余的配置,LogBack默认将日志打印到控制台上。
3.1 依赖
如果要使用LogBack,原则上是需要添加spring-boot-starter-logging
依赖,因为Spring Boot项目一般都会引用spring-boot-starter
或者spring-boot-starter-web
,而这两个起步依赖中都已经包含了对于spring-boot-starter-logging
的依赖,所以,无需额外添加依赖。
3.2 项目使用
通过 LoggerFactory 获取 Logger 即可。private static final Logger logger = LoggerFactory.getLogger(JdbcController.class);
package org.example.Controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RestController
public class JdbcController {
private static final Logger logger = LoggerFactory.getLogger(JdbcController.class);
@GetMapping(path = "/testLog")
public String testLog() {
logger.debug("debug");
logger.info("info");
logger.warn("warn");
logger.error("error");
return "hello spring boot";
}
}
Spring Boot 默认的日志级别为INFO
,INFO 及以上的级别日志可以打印。
还可以搭配 lombok 来省略创建 Logger 对象:
package org.example.Controller;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
public class JdbcController {
@GetMapping(path = "/testLog")
public String testLog() {
log.debug("debug");
log.info("info");
log.warn("warn");
log.error("error");
return "hello spring boot";
}
}
@Slf4j
注解在类上,为类提供一个属性名为log
的 slf4j 日志对象。
3.3 日志信息存储到文件
线上环境,需要将日志信息存储到文件,可以通过 application.yml
文件配置相关参数。
# 日志配置
logging:
file: D:/zndl/logs/temp.log
level:
root: info
# mybatis日志
org.mybatis: debug
com.ymqx.mapper: debug
pattern:
console: "%clr(%d{MM-dd HH:mm:ss.SSS}){faint} %clr(${server.name} ${LOG_LEVEL_PATTERN}) %clr(${PID:- }){magenta} %clr([%5.5t]){faint} %clr(%-20.20logger{39} %5.5line){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}}"
file: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"
logging.path
该属性用来配置日志文件的路径
logging.file
该属性用来配置日志文件名,如果该属性不配置,默认文件名为spring.log
logging.level
该属性用于配置日志级别。日志级别总共有 ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
,且级别是逐渐提高,如果日志级别设置为 INFO,意味记录 INFO 及其以上的级别日志。
logging:
level:
root: info
org.mybatis: debug
org.apache.zookeeper.ZooKeeper: OFF
root
,即项目的所有日志。我们也可以使用package
级别,即指定包下使用相应的日志级别。
logging.pattern.console
该属性用于定制日志控制台输出格式。
logging.pattern.file
该属性用于定制日志文件输出格式。
- %d{HH:mm:ss.SSS}:输出日志的打印日志,模式语法与 java.text.SimpleDateFormat 兼容。
- %t / %thread:输出产生日志的线程名。
- %-5level:日志级别,并且使用5个字符靠左对齐。
- %logger{length}:输出日志的logger名,可有一个整形参数,功能是缩短logger名,设置为0表示只输入logger最右边。
- %msg:表示打印输出的消息。
- %n:表示换行
@Slf4j
@RestController
public class JdbcController {
@GetMapping(path = "/userMb/{userId}")
public String getUserMbs(@PathVariable("userId") String userId){
System.out.println(userId);
List<UserMb> userMbs = userService.selectUserMbList(userId);
log.debug("debug");
log.info("info");
log.warn("warn");
log.error("error");
log.info("userMbs = {}", userMbs);
return "hello spring boot";
}
}
访问 http://192.168.1.166:8080/userMb/1
终端打印:
日志文件 D:\zndl\logs\temp.log:
3.4 logback.xml配置日志
通过 application.yml 配置日志功能不丰富,我们可以通过logback-spring.xml
配置多样的日志配置,在 resources 目录下直接创建名为 logback-spring.xml 的文件即可。
具体参见本章节
访问 http://192.168.1.166:8080/userMb/1
终端打印:
日志文件 D:\zndl\logs\SpringBootDemo\log_info.log:
日志文件 D:\zndl\logs\SpringBootDemo\log_warn.log:
日志文件 D:\zndl\logs\SpringBootDemo\log_error.log:
springboot 的 logback.xml 和 logback-spring.xml 的区别?
logback 和 logback-spring.xml 都可以用来配置 logback,但是两者的加载顺序是不一样的。
logback.xml ---> application.properties ---> logback-spring.xml
logback.xml 加载早于 application.yml,所以如果你在 logback.xml 使用了application.yml 的变量时,那么就会获取不到。比如,在 logback.xml 中使用<springProperty>
,就获取不到变量 spring.application.name :
<springProperty scope="context" name="SERVER_NAME" source="spring.application.name" defaultValue="SpringBootDemo"/>
解决方案:只要将文件名改成 logback-spring.xml 就可以解决。
4. SpringBoot使用Log4j
因为不怎么常用,暂不整理,用到可参考
spingboot默认日志系统LogBack、Log4j和slf4j使用详解
java中的slf4j、log4j和logback的区别与联系以及使用方法
5. 小结
- slf4j 是 java 的一个日志门面,实现了日志框架一些通用的api,log4j 和 logback 是具体的日志框架。
- 他们可以单独的使用,也可以绑定 slf4j 一起使用。推荐组合
slf4j + logback
。