slf4j为spring boot 的日志功能定义了一套统一的接口,方便各类日志框架去实现。html
SLF4J——Simple Logging Facade For Java,它是一个针对于各种Java日志框架的统一Facade抽象。Java日志框架众多——经常使用的有java.util.logging, log4j, logback,commons-logging, Spring框架使用的是Jakarta Commons Logging API (JCL)。而SLF4J定义了统一的日志抽象接口,而真正的日志实现则是在运行时决定的——它提供了各种日志框架的binding。java
spring boot默认使用的日志框架是logback,它的maven jar包名称叫程序员
spring-boot-starter-loggingspring
这里咱们谈谈spring boot 整合log4j2日志框架。apache
固然,logback,log4j和log4j2,确定都是实现了slf4j接口的日志框架。json
这里要注意,以前看其余文章,有人说过spring boot 版本超过1.4,就再也不支持log4j了,须要使用log4j2框架。springboot
本文解决如下问题:
- 为什么使用log4j2
- springboot下log4j2日志的使用
- 控制台日志显示的级别和文件保存的日志不一样
- idea控制台颜色日志的输出服务器
目前有关服务器日志输出的框架有不少,如log4j、sl4j和log4j2,为何我选择使用log4j2呢,看完下面两篇性能的对比,相信你也会选择log4j2
http://www.jianshu.com/p/483a9cf61c36
https://blog.souche.com/logback-log4j-log4j2shi-ce/?utm_source=tuicool&utm_medium=referralmybatis
大意就是从不一样角度看,log4j2的性能提高比较大。app
须要将springboot内置的日志剃掉,而后引入log4j2,pom以下
<!-- 支持log4j2日志框架 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
而后须要在resource下面添加log4j2.xml配置文件,固然了若是你不添加,springboo会提示你没有对应文件,并使用默认的配置文件,这个时候级别能够在application.properties中配置
logging.level.root=error
控制台打印结果
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/E:/ide/maven-jar/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/E:/ide/maven-jar/org/apache/logging/log4j/log4j-slf4j-impl/2.7/log4j-slf4j-impl-2.7.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder] . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.18.RELEASE) 2019-01-11 16:56:04.582 INFO 7640 --- [ main] com.example.demo.Demo1Application : Starting Demo1Application on 16101281-6 with PID 7640 (E:\ide\workspace\demo-1\target\classes started by Administrator in E:\ide\workspace\demo-1) 2019-01-11 16:56:04.586 INFO 7640 --- [ main] com.example.demo.Demo1Application : No active profile set, falling back to default profiles: default 2019-01-11 16:56:05.038 INFO 7640 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1dd02175: startup date [Fri Jan 11 16:56:05 CST 2019]; root of context hierarchy 2019-01-11 16:56:06.844 INFO 7640 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$76665e5c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2019-01-11 16:56:07.654 INFO 7640 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 82 (http) 2019-01-11 16:56:07.697 INFO 7640 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2019-01-11 16:56:07.698 INFO 7640 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.35
注意最上面的几行日志,有警告,缘由是项目中同时存在logback和log4j2的依赖包,它们都实现了slf4j接口,因此冲突了。
而logback框架是依赖于spring-boot-starter-logging这个jar包的。这个jar包,你会发现咱们pom里面没有主动引入它。可是有jar包依赖了它,maven就会把logging下载到依赖它的jar包中。
咱们经过下面的操做,把依赖logging的jar包,找出来,解除它对logging的依赖,同时项目又加入了log4j2的jar包。那么在输出日志的时候,就不会冲突了。
这里我分享一个eclipse的小技巧,如何查看pom.xml里面jar包的关联关系。
打开pom.xml文件,打开Dependency Hierarchy选项卡,将logging这个jar包,输入filter中,就能够看到pom里面谁依赖了它。
咱们能够经过eclipse提供的功能,让eclipse帮咱们解除pom中的jar包,对logging这个包的依赖
右键spring-boot-strater-logging包,选择项
这时候,咱们会发现pom.xml发生了变化:
<!-- 支持JDBC --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>
关联logback输出日志的jar包,都添加了
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
标签来取消依赖。
重启项目,发现警告没有消失!
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.18.RELEASE) 2019-01-11 18:17:16.314 INFO 5272 --- [ main] c.e.d.Demo1Application : Starting Demo1Application on 16101281-6 with PID 5272 (E:\ide\workspace\demo-1\target\classes started by Administrator in E:\ide\workspace\demo-1) 2019-01-11 18:17:16.322 INFO 5272 --- [ main] c.e.d.Demo1Application : No active profile set, falling back to default profiles: default 2019-01-11 18:17:16.676 INFO 5272 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3eb25e1a: startup date [Fri Jan 11 18:17:16 CST 2019]; root of context hierarchy 2019-01-11 18:17:18.258 INFO 5272 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$6c96c533] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2019-01-11 18:17:18.954 INFO 5272 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 82 (http)
主要结构,和咱们用到的大体以下
咱们来看一篇复杂的log4j2配置:
<?xml version="1.0" encoding="UTF-8"?> <!-- 日志级别 trace: 是追踪,就是程序推动如下,你就能够写个trace输出,因此trace应该会特别多,不过不要紧,咱们能够设置最低日志级别不让他输出。 debug: 调试么,我通常就只用这个做为最低级别,trace压根不用。是在没办法就用eclipse或者idea的debug功能就行了么。 info: 输出一下你感兴趣的或者重要的信息,这个用的最多了。 warn: 有些信息不是错误信息,可是也要给程序员的一些提示,相似于eclipse中代码的验证不是有error 和warn(不算错误可是也请注意,好比如下depressed的方法)。 error: 错误信息。用的也比较多。 fatal: 级别比较高了。重大错误,这种级别你能够直接中止程序了,是不该该出现的错误么!不用那么紧张,其实就是一个程度的问题。 --> <Configuration status="OFF"> <!-- 定义日志存放目录 --> <properties> <property name="logPath">logs</property> <!-- 输出日志的格式 --> <!-- %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间 %p : 日志输出格式 %c : logger的名称 %m : 日志内容,即 logger.info("message") %n : 换行符 %C : Java类名 %L : 日志输出所在行数 %M : 日志输出所在方法名 hostName : 本地机器名 hostAddress : 本地ip地址 --> <property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} %L %M - %msg%xEx%n</property> </properties> <!--先定义全部的appender(输出器) --> <Appenders> <!--输出到控制台 --> <Console name="ConsoleLog" target="SYSTEM_OUT"> <!--只输出level及以上级别的信息(onMatch),其余的直接拒绝(onMismatch) --> <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY" /> <!--输出日志的格式,引用自定义模板 PATTERN --> <PatternLayout pattern="${PATTERN}" /> </Console> <!--输出到文件 --> <!--文件会打印出全部信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 --> <!--append为TRUE表示消息增长到指定文件中,false表示消息覆盖指定的文件内容,默认值是true --> <File name="TestLog" fileName="${logPath}/test.log" append="false"> <PatternLayout pattern="${PATTERN}" /> </File> <!-- 把error等级记录到文件 通常不用 --> <File name="FileLog" fileName="${logPath}/error.log"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout pattern="${PATTERN}" /> </File> <!--输出到循环日志,每次大小超过size,则这size大小的日志会自动存入按年份-月份创建的文件夹下面并进行压缩,做为存档 --> <RollingFile name="RollingFileLog" fileName="${logPath}/app.log" filePattern="${logPath}/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout pattern="${PATTERN}" /> <SizeBasedTriggeringPolicy size="10MB" /> </RollingFile> </Appenders> <!--而后定义logger,只有定义了logger并引入的appender,appender才会生效 --> <!--而后定义logger,只有定义了logger并引入的appender,appender才会生效 --> <Loggers> <!--创建一个默认的Root的logger,记录大于level高于warn的信息,若是这里的level高于Appenders中的,则Appenders中也是以此等级为起点,好比,这里level="fatal",则Appenders中只出现fatal信息 --> <!-- 生产环境level>=warn --> <Root level="debug"> <!-- 输出器,可选上面定义的任何项组合,或全选,作到可随意定制 --> <appender-ref ref="ConsoleLog" /> <appender-ref ref="TestLog" /> <appender-ref ref="FileLog" /> <appender-ref ref="RollingFileLog" /> </Root> <!-- 第三方日志系统 --> <!--过滤掉spring和mybatis的一些无用的DEBUG信息,也能够在spring boot 的logging.level.org.springframework=FATAL设置--> <!-- <logger name="org.springframework" level="INFO"></logger> --> <!-- <logger name="org.mybatis" level="INFO"></logger> --> <!-- <logger name="org.apache.http" level="warn" /> --> </Loggers> </Configuration>
该配置文件的,参数配置方式,与logback-spring.xml的配置文件,几乎一致。
log4j 2.x版本再也不支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为".xml",".json"或者".jsn".
系统选择配置文件的优先级(从先到后)以下:
(1).classpath下的名为log4j2-test.json 或者log4j2-test.jsn的文件.
(2).classpath下的名为log4j2-test.xml的文件.
(3).classpath下名为log4j2.json 或者log4j2.jsn的文件.
(4).classpath下名为log4j2.xml的文件.
咱们通常默认使用log4j2.xml进行命名。若是本地要测试,能够把log4j2-test.xml放到classpath,而正式环境使用log4j2.xml,则在打包部署的时候不要打包log4j2-test.xml便可。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
(1).根节点Configuration有两个属性:status和monitorinterval,有两个子节点:Appenders和Loggers(代表能够定义多个Appender和Logger).
status用来指定log4j自己的打印日志的级别.
monitorinterval用于指定log4j自动从新配置的监测间隔时间,单位是s,最小是5s.
(2).Appenders节点,常见的有三种子节点:Console、RollingFile、File.
Console节点用来定义输出到控制台的Appender.
name:指定Appender的名字.
target:SYSTEM_OUT 或 SYSTEM_ERR,通常只设置默认:SYSTEM_OUT.
PatternLayout:输出格式,不设置默认为:%m%n.
File节点用来定义输出到指定位置的文件的Appender.
name:指定Appender的名字.
fileName:指定输出日志的目的文件带全路径的文件名.
PatternLayout:输出格式,不设置默认为:%m%n.
RollingFile节点用来定义超过指定大小自动删除旧的建立新的的Appender.
name:指定Appender的名字.
fileName:指定输出日志的目的文件带全路径的文件名.
PatternLayout:输出格式,不设置默认为:%m%n.
filePattern:指定新建日志文件的名称格式.
Policies:指定滚动日志的策略,就是何时进行新建日志文件输出日志.
TimeBasedTriggeringPolicy:Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:好比如今是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am.
SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每一个日志文件的大小.
DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,建立新的(经过max属性)。
(3).Loggers节点,常见的有两种:Root和Logger.
Root节点用来指定项目的根日志,若是没有单独指定Logger,那么就会默认使用该Root日志输出
level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
AppenderRef:Root的子节点,用来指定该日志输出到哪一个Appender.
Logger节点用来单独指定日志的形式,好比要为指定包下的class指定不一样的日志级别等。
level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.
AppenderRef:Logger的子节点,用来指定该日志输出到哪一个Appender,若是没有指定,就会默认继承自Root.若是指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时咱们能够设置Logger的additivity="false"只在自定义的Appender中进行输出。
共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
All:最低等级的,用于打开全部日志记录.
Trace:是追踪,就是程序推动如下,你就能够写个trace输出,因此trace应该会特别多,不过不要紧,咱们能够设置最低日志级别不让他输出.
Debug:指出细粒度信息事件对调试应用程序是很是有帮助的.
Info:消息在粗粒度级别上突出强调应用程序的运行过程.
Warn:输出警告及warn如下级别的日志.
Error:输出错误信息日志.
Fatal:输出每一个严重的错误事件将会致使应用程序的退出的日志.
OFF:最高等级的,用于关闭全部日志记录.
程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少。
划重点:application.properties中配置日志
#要扫描的包记录日志信息 logging.config=classpath:log4j2.xml # 定义记录某个包内日志的级别,高于等于则记录,能够多个 logging.level.org.springframework=FATAL
在须要的地方使用
mport org.slf4j.Logger; import org.slf4j.LoggerFactory; ... private static Logger logger = LoggerFactory.getLogger(xx.class); ... logger.info("------xxxx-------");
日志的配置,主要体现为
设置日志文件的路劲和名称,
设置日志文件的输出格式,
设置日志文件,在console中,和file中的,输出的日志等级,和扫描的不一样的包/类。
设置日志文件的切片维度和保存策略,好比指定日志文件的大小,按天保存,最大保存多少天,最大保存多少MB。
设置是否输出第三方框架的日志,和日志等级。
指定须要输出日志的包/类,和他们的输出等级。