slf4j⽇志门⾯与springboot⽇志介绍使⽤(logback,log4j2)
写在前边: ⽇志是我们开发不能少的⼯具,它可以记录很多运⾏和调试的信息,让我们后期更好的维护项⽬。
:⼩⽩编码
⽬录
JAVA⽇志框架
1. 控制⽇志输出的内容和格式
2. 控制⽇志输出的位置
3. ⽇志优化:异步⽇志,⽇志⽂件的归档和压缩
4. ⽇志系统的维护
5. ⾯向接⼝开发 – ⽇志的门⾯
SpringBoot⽇志
SpringBoot:底层是Spring框架,Spring框架默认是⽤JCL;SpringBoot选⽤ SLF4j和logback;
SLF4J⽇志门⾯
简单⽇志门⾯(Simple Logging Facade For Java) SLF4J主要是为了给Java⽇志访问提供⼀套标准、规范的API框架,其主要意义在于提供接⼝,具体的实现可以交由其他⽇志框架,例如log4j和logback等。当然slf4j⾃⼰也提供了功能较为简单的实现,但是⼀般很少⽤到。对于⼀般的Java项⽬⽽⾔,⽇志框架会选择slf4j-api作为门⾯,配上具体的实现框架(log4j、logback等),中间使⽤桥接器完成桥接。
SLF4J是⽬前市⾯上最流⾏的⽇志门⾯。现在的项⽬中,基本上都是使⽤SLF4J作为我们的⽇志系统。两⼤功能:
1. ⽇志框架的绑定
2. ⽇志框架的桥接
要切换⽇志框架,只需替换类路径上的slf4j绑定。例如,要从java.util.logging切换到log4j,只需将slf4j-jdk14-1.7.27.jar替换为slf4j-log4j12-1.7.27.jar即可。
SLF4J不依赖于任何特殊的类装载。实际上,每个SLF4J绑定在编译时都是硬连线的, 以使⽤⼀个且只有⼀个特定的⽇志记录框架。例如,slf4j-log4j12-1.7.27.jar绑定在编译时绑定以使⽤og4j。在您的代码中,除了slf4j-api-1.7.27.jar之外,您只需将您选择的⼀个且只有⼀个绑定放到相应的类路径位置。不要在类路径上放置多个绑定。以下是⼀般概念的图解说明。
每⼀个⽇志的实现框架都有⾃⼰的配置⽂件。使⽤slf4j以后,配置⽂件还是做成⽇志实现框架⾃⼰本⾝的配置⽂件;
⽇志遗留问题
通常,您依赖的某些组件依赖于SLF4J以外的⽇志记录API。您也可以假设这些组件在不久的将来不会切换到SLF4J。为了解决这种情
况,SLF4J附带了⼏个桥接模块,这些模块将对log4j,JCL和java.util.logging API的调⽤重定向,就好像它们是对SLF4J API⼀样。
桥接解决的是项⽬中⽇志的遗留问题,当系统中存在之前的⽇志API,可以通过桥接转换到slf4j的实现
1. 先去除之前⽼的⽇志框架的依
2. 添加SLF4J提供的桥接组件
3. 为项⽬添加SLF4J的具体实现
如何让系统中所有的⽇志都统⼀到slf4j;
1、将系统中其他⽇志框架先排除出去;
2、⽤中间包来替换原有的⽇志框架;
3、我们导⼊slf4j其他的实现
Springboot底层⽇志依赖:使⽤logback
Logback⽇志
Logback是由log4j创始⼈设计的另⼀个开源⽇志组件,性能⽐log4j要好。
Logback主要分为三个模块:
logback-core:其它两个模块的基础模块
logback-classic:它是log4j的⼀个改良版本,同时它完整实现了slf4j API
logback-access:访问模块与Servlet容器集成提供通过Http来访问⽇志的功能
后续的⽇志代码都是通过SLF4J⽇志门⾯搭建⽇志系统,所以在代码是没有区别,主要是通过修改配置⽂件和l依赖Logback使⽤
由于Springboot底层是logback⽇志,所以我们直接使⽤
//记录器
Logger logger = Logger(getClass());
@Test
public void contextLoads(){
//System.out.println();
//⽇志的级别;
//由低到⾼  trace<debug<info<warn<error
//可以调整输出的⽇志级别;⽇志就只会在这个级别以以后的⾼级别⽣效
logger.debug("这是debug⽇志...");
//SpringBoot默认给我们使⽤的是info级别的,没有指定级别的就⽤SpringBoot默认规定的级别;root级别
logger.info("这是info⽇志...");
logger.warn("这是warn⽇志...");
<("这是error⽇志...");
}
Logback配置
logger:⽇志的记录器,把它关联到应⽤的对应的context上后,主要⽤于存放⽇志对象,也可以定义⽇志类型、级别。
Appender:⽤于指定⽇志输出的⽬的地,⽬的地可以是控制台、⽂件、数据库等等。
.Layout:负责把事件转换成字符串,格式化的⽇志信息的输出。在logback中Layout对象被封装在encoder中。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--⽇志⽂件保存路径:默认当前项⽬所在的盘符/huixian/logs/⽬录下-->
<property name="file_path" value="/huixian/logs/"/>
<!-- 定义⽇志⽂件名称:项⽬名 -->
<property name="appName" value="huixian"/>
<!-- ⽂件⽇志输出格式 -->
<!-- ⽂件⽇志输出格式 -->
<property name="file_pattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} = [%thread] = [%-5level] = %logger{50} - [%method,%line] - %msg%n"/>
<!-- 控制台⽇志输出格式 -->
<property name="console_pattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} = [%thread] = [%-5level] = %logger{25} - [%method,%line] - %msg%n"/>
<!--控制台⽇志输出-->
<appender name="console" class="ch.ConsoleAppender">
<encoder>
<!--调⽤:name的值-->
<pattern>${console_pattern}</pattern>
</encoder>
</appender>
<!--⽂件⽇志输出-->
<appender name="file_log" class="ch.FileAppender">
<!--⽇志保存路径+名称-->
<file>${file_path}/${appName}.log</file>
<!--⽇志追加到末尾-->
<append>true</append>
<!--⽇志消息格式设置-->
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!--⽇志拆分和归档-->
<!-- 滚动记录⽂件,先将⽇志记录到指定⽂件,当符合某个条件时,将⽇志记录到其他⽂件 -->
<appender name="appLogAppender" class="ch.olling.RollingFileAppender">
<!-- 指定⽇志⽂件的名称 -->
<file>${file_path}/${appName}.log</file>
<!--⽇志追加到末尾-->
<append>true</append>
<!--TimeBasedRollingPolicy:最常⽤的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->
<rollingPolicy class="ch.olling.TimeBasedRollingPolicy">
<!--⽇志⽂件名格式 -->
<fileNamePattern>${file_path}/${appName}%d{yyyy-MM-dd}.log</fileNamePattern>
<!--⽇志最⼤的历史 60天 -->
<maxHistory>60</maxHistory>
<!--
当⽇志⽂件超过maxFileSize指定的⼤⼩是,根据上⾯提到的%i进⾏⽇志⽂件滚动
注意此处配置SizeBasedTriggeringPolicy是⽆法实现按⽂件⼤⼩进⾏滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy              -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.olling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</rollingPolicy>
<!--⽇志输出格式: -->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${file_pattern}</pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--过滤的级别:只接受ERROR错误 -->
<level>ERROR</level>
<!--匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!--不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--⽇志拆分和归档压缩的 appender 对象-->
<appender name="rollFile" class="ch.olling.RollingFileAppender">
<!-- 指定⽇志⽂件的名称 -->
<file>${file_path}/${appName}.log</file>
<!--⽇志追加到末尾-->
<append>true</append>
<!--⽇志消息格式配置-->
<encoder class="ch.qos.der.PatternLayoutEncoder">
<pattern>${file_pattern}</pattern>
</encoder>
<!--指定拆分规则:按照⽂件⼤⼩-->
<rollingPolicy class="ch.olling.SizeAndTimeBasedRollingPolicy">
<!--按照时间和压缩格式声明拆分的⽂件名-->
<fileNamePattern>${file_path}/%d{yyyy-MM-dd}-${appName}-%i.log</fileNamePattern>
<!--按照⽂件⼤⼩拆分-->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
</appender>
<!--异步⽇志-->
<appender name="async" class="ch.qos.logback.classic.AsyncAppender">
<!--指定某个具体的 appender-->
<appender-ref ref="rollFile"/>
</appender>
<!--
root与logger是⽗⼦关系,没有特别定义则默认为root,任何⼀个类只会和⼀个logger对应,
要么是定义的logger,要么是root,判断的关键在于到这个logger,然后判断这个logger的appender和level。<!--root:如果有⼦logger将以⼦logger的level为基础-->
springboot框架的作用-->
<root level="ALL">
<!--控制台-->
<appender-ref ref="console"/>
<!--⽂件-->
<appender-ref ref="file_log"/>
<!--按照⽂件⼤⼩归档-->
<appender-ref ref="async"/>
<!--按照⽇期归档-->
<appender-ref ref="appLogAppender"/>
</root>
<!--
logger主要⽤于存放⽇志对象,也可以定义⽇志类型、级别
name:⽤来指定受此loger约束的某⼀个包或者具体的某⼀个类。
level:要记录的⽇志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR
additivity:作⽤在于children-logger是否使⽤ rootLogger配置的appender进⾏输出,
false:表⽰只⽤当前logger的appender-ref,
true:表⽰当前logger的appender-ref和rootLogger的appender-ref都有效
-->
<logger name="dewhite" level="info" additivity="false">
<appender-ref ref="console"/>
</logger>
<!--屏蔽某个包的⽇志-->
<logger name="packageName" level="OFF"></logger>
<!--myibatis log configure-->
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- Spring framework logger -->
<logger name="org.springframework" level="DEBUG" additivity="false"></logger>
</configuration>
Springboot使⽤⾃带配置:
#logging.path=
# 不指定路径在当前项⽬下⽣成springboot.log⽇志
# 可以指定完整的路径;
#logging.file=G:/springboot.log
#  在控制台输出的⽇志的格式
sole=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
# 指定⽂件中⽇志输出的格式
logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n
# 指定⾃定义 logger 对象⽇志级别
dewhite=trace
# 指定存放⽇志⽂件的具体路径
# logging.file=/logs/springboot.log
# 指定⽇志⽂件存放的⽬录,默认的⽂件名 spring.log
logging.file.path=/logs/springboot/
# 指定项⽬使⽤的具体环境
spring.profiles.active=pro
logging.file logging.path Example Description
(none)(none)只在控制台输出
指定⽂件名(none)my.log输出⽇志到my.log⽂件
(none)指定⽬录/var/log输出到指定⽬录的 spring.log ⽂件中
2、指定配置
给类路径下放上每个⽇志框架⾃⼰的配置⽂件即可;SpringBoot就不使⽤他默认配置的了
Logging System Customization
l, vy, l vy
JDK (Java Util Logging)logging.properties
<appender name="stdout"class="ch.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<!-- dev 使⽤以下的格式-->
<springProfile name="dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}---->[%thread]--->%-5level %logger{50}-%msg%n</pattern>
</springProfile>
<!--不是dev 使⽤以下的格式-->
<springProfile name="!dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}====[%thread]====%-5level %logger{50}-%msg%n</pattern>
</springProfile>
</layout>
</appender>
Springboot切换⽇志框架
切换为log4j2:依赖