spring boot 整合log4j2 日志框架

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控制台颜色日志的输出服务器

正文

log4j2

 目前有关服务器日志输出的框架有不少,如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

依赖jar包并解决jar包冲突

须要将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配置文件

主要结构,和咱们用到的大体以下 

 

咱们来看一篇复杂的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的配置文件,几乎一致。

配置参数详解

1.关于配置文件的名称以及在项目中的存放位置

    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便可。

2.缺省默认配置文件

<?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>

3.配置文件节点解析    

    (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中进行输出。

4.关于日志level

      共有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。

设置是否输出第三方框架的日志,和日志等级。

指定须要输出日志的包/类,和他们的输出等级。