spring boot 1.5.4 整合log4j2(十一)-阿里云开发者社区

开发者社区> 技术小阿哥> 正文

spring boot 1.5.4 整合log4j2(十一)

简介:
+关注继续查看

Spring Boot整合log4j2

spring boot整合log4j2项目spring-boot-jsp源码:

spring-boot相关项目源码,

码云地址:https://git.oschina.net/wyait/springboot1.5.4.git

github地址https://github.com/wyait/spring-boot-1.5.4.git


1.1  log4j2概要

对于我们开发人员来说,日志记录往往不被重视。在生产环境中,日志是查找问题来源的重要依据。日志可记录程序运行时产生的错误信息、状态信息、调试信息和执行时间信息等多种多样的信息。可以在程序运行出现错误时,快速地定位潜在的问题源。

 

目前常用的日志框架有java.util.loggingcommons loggingslf4jlog4j1.xlogbacklog4j2.x 等若干种,这里我们使用log4j2框架进行日志管理,先介绍下日志框架的发展史以及优点。

1.1.1     java日志框架发展史

 

  • 1996年早期,欧洲安全电子市场项目组决定编写它自己的程序跟踪API(Tracing API)。经过不断的完善,这个API终于成为一个十分受欢迎的Java

日志软件包,即log4j。后来log4j成为Apache基金会项目中的一员。

期间log4j近乎成了Java社区的日志标准。据说Apache基金会还曾经建议Sun引入log4j到java的标准库中,但Sun拒绝了。

 

  • 2002年Java1.4发布,Sun推出了自己的日志库jul(java util logging),其实现基本模仿了log4j的实现。在JUL出来以前,log4j就已经成为

一项成熟的技术,使得log4j在选择上占据了一定的优势。

接着,Apache推出了jakarta commons logging,jcl只是定义了一套日志接口(其内部也提供一个simple log的简单实现),支持运行时动态加载日志组件的实现,也就是说,在你的应用代码里,只需调用commons logging的接口,底层实现可以是log4j,也可以是java util logging。

 

  • 后来(2006年),Ceki Gülcü(Gulcu)不适应Apache的工作方式,离开了Apache。然后先后创建了slf4j(日志门面接口,类似于commons logging)

和logback(slf4j的实现)两个项目,并回瑞典创建了QOS公司,QOS官网上是这样描述logback的:The Generic,Reliable Fast&FlexibleLogging Framework(一个通用,可靠,快速且灵活的日志框架)。

 

  • 现今,Java日志领域被划分为两大阵营:commons logging阵营和slf4j阵营。 commons logging在Apache大树的笼罩下,有很大的用户基数。

但有证据表明,形式正在发生变化。2013年底有人分析了GitHub上30000个项目,统计出了最流行的100个Libraries,可以看出slf4j的发展

趋势更好。如下图所示:

wKioL1nNohGDPUoEAAEuljEPugo210.png

 

Apache眼看有被logback反超的势头,于2012年7月重写了log4j 1.x,成立了新的项目log4j2.x。log4j2在各个方面都与logback非常相似。

 

1.1.2     常用日志框架介绍

这些日志系统有什么区别,开发时如何选择适合自己项目的日志系统呢?日志系统可分为两类。

 

一类:只提供接口不提供实现,如 Apache Commons Logging 和 slf4j。这类日志系统需要和具体的日志系统一起使用,优点是可以自由切换不同的日志实现系统。如果你的项目以后要打成 jar 包被别的系统使用或者你以后可能更换日志系统,通常使用这一类日志系统。

 

另一类:是具体的日志系统实现。如 log4j1.x、logback、log4j2.x、java.util.logging等。

 

下图清晰的展示了 slf4j 和其它日志系统的关系:

wKiom1nNolzRdtxCAAFmo8zIkco476.png

 

slf4j(SimpleLogging Facade for Java),面向 java 的简单日志门面,人如其名,slf4j 是其他日志的门面,它提供统一的接口,并不提供实现,不是具体的日志系统。

 

log4j1 曾经被广泛使用,2015年8月已停止更新,logback和log4j2作为它的替代者,拥有更好的性能,有很多的改进,下面重点讲一下 logback 和 log4j2 的特性。

 

1.1.3  logback相比 log4j1 的优点

 

1、 性能的提升。Logback 的内核重写了,在某些特定的场景上性能提升 10 倍以上,同时所需的内存更加少。

2、 非常充分的测试。Logback经过了几年,数不清小时的测试,与log4j1的测试相比不在同一个级别,因此 logback 更稳定可靠。

3、 非常自然的实现了slf4j。而log4j1 和 slf4j 一起使用需要适配层。

4、 自动重新加载配置文件。当配置文件修改了,Logback-classic能自动重新加载配置文件,不需要重启服务器。

5、 优雅地从I/O错误中恢复。如果一个文件服务器临时宕机,你不需要重启应用,日志功能就能正常工作。

6、 配置文件可适应多环境。通常在开发、测试、生产环境,需要变换日志的配置文件。而在不同环境下,配置文件只有一些很小的不同,为了避免重复,logback支持使用,和进行条件处理,同一个配置文件就可以在不同的环境中使用了。

7、 过滤器。生产环境中,有时需要低级别的日志来查明问题,在log4j1 中,只有降低日志级别,这样的话会打出大量的日志而影响性能。而logback 中,你可以继续保持那个日志级别而除掉某种特殊情况。

8、 自动压缩归档日志文件。压缩通常是异步执行的,所以即使是很大的日志文件,你的应用都不会因此而被阻塞。

9、 通过配置自动去除旧的日志文件。

 

1.1.4     log4j2 的优点

log4j2在各个方面都与logback非常相似,那么为什么我们还需要log4j 2呢?

 

1、  可配置的审计型日志。log4j1和logback在重新配置的时候会丢失之前的日志文件,log4j2不会。log4j2自身内部报的exception会被发现,但是log4j1和logback不会。

 

2、  下一代异步logger。log4j 2是基于LMAXDisruptor库的(一个用于在线程间通信的高效低延迟且简单的框架),在多线程场景下,它的日志吞吐量比其他框架多出10倍以上。

 

3、  可运行在免垃圾收集模式。这样可以减少垃圾收集器的压力和提供更好的响应时间性能。

 

4、  插件式结构。可根据自己的需要扩展框架,可以实现自己的logger、appenders、filters、layouts、lookups 和patternconverters,而无需对log4j2做任何更改。

 

5、 Java 5的并发性。log4j2利用Java 5中的并发特性支持,尽可能地执行最低层次的加锁,log4j1中存留的死锁问题,很多已经在logback中解决,但logback的很多类仍然保持着较高层次的同步。如果你的程序仍然饱受内存泄漏的折磨,请毫不犹豫地试一下log4j2。

 

下图为Apache Logging PMC成员Christian Grobmeier 在2013年7月发表的一篇标题为《Log4j2:性能几近于疯狂》的文章;

wKioL1nNoiayjRTlAACxJeuHaVE278.png

1.2    spring boot集成log4j2

使用spring-boot-jsp项目,项目源码:spring-boot-jsp

  • 导入依赖

<!-- 导入log4j2依赖 -->

      <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-log4j2</artifactId>

      </dependency>

      <!-- log4j2支持异步日志,导入disruptor依赖 -->

      <dependency>

        <groupId>com.lmax</groupId>

        <artifactId>disruptor</artifactId>

        <version>3.3.6</version>

      </dependency>

  • 配置文件:在项目目录/resources资源文件根目录下创建 log4j2.xml 文件,详细配置如下:

 

<?xmlversion="1.0" encoding="UTF-8"?>

<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE >ALL -->

<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出;可以设置成OFF(关闭)Error(只输出错误信息)-->

<!--monitorIntervalLog4j2能够自动检测修改配置文件和重新配置本身,设置间隔秒数-->

<Configurationstatus="WARN" monitorInterval="30">

   <Properties>

   <!-- 缺省配置(用于开发环境),配置日志文件输出目录和动态参数。其他环境需要在VM参数中指定;

      sys:”表示:如果VM参数中没指定这个变量值,则使用本文件中定义的缺省全局变量值 -->

      <Propertyname="instance">spring-boot-log</Property>

      <Propertyname="log.dir">D:\log\logs</Property>

   </Properties>

   <!-- 定义所有的appender -->

   <Appenders>

      <!--这个输出控制台的配置-->

      <Console name="Console"target="SYSTEM_OUT">

        <!--输出日志的格式-->

        <PatternLayout

           pattern="[%date{yyyy-MM-ddHH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n" />

      </Console>

      <!-- info及以上级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->

      <RollingRandomAccessFilename="infoLog"

        fileName="${log.dir}/${instance}-info.log"

        filePattern="${log.dir}/%d{yyyy-MM}/${instance}-info-%d{yyyy-MM-dd}-%i.log.gz"

        append="true">

        <PatternLayout

           pattern="[%date{yyyy-MM-ddHH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n" />

        <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch-->

        <Filters>

           <ThresholdFilterlevel="info" onMatch="ACCEPT"

              onMismatch="NEUTRAL"/>

        </Filters>

        <Policies>

           <!-- 基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour -->

           <TimeBasedTriggeringPolicyinterval="1"

              modulate="true" />

           <!-- 基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小 -->

           <SizeBasedTriggeringPolicysize="1MB" />

           <!-- DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性) -->

        </Policies>

      </RollingRandomAccessFile>

  

      <!-- warn级别的日志信息 -->

      <RollingRandomAccessFilename="warnLog"

        fileName="${log.dir}/${instance}-warn.log"

        filePattern="${log.dir}/%d{yyyy-MM}/${instance}-warn-%d{yyyy-MM-dd}-%i.log.gz"

        append="true">

        <Filters>

           <ThresholdFilterlevel="error" onMatch="DENY"

              onMismatch="NEUTRAL"/>

           <ThresholdFilterlevel="warn" onMatch="ACCEPT"

              onMismatch="DENY" />

        </Filters>

         <PatternLayout

           pattern="[%date{yyyy-MM-ddHH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n" />

        <Policies>

           <TimeBasedTriggeringPolicyinterval="1"

              modulate="true" />

           <SizeBasedTriggeringPolicysize="1MB" />

        </Policies>

      </RollingRandomAccessFile>

     

      <!-- error级别的日志信息 -->

      <RollingRandomAccessFilename="errorLog"

        fileName="${log.dir}/${instance}-error.log"

        filePattern="${log.dir}/%d{yyyy-MM}/${instance}-error-%d{yyyy-MM-dd}-%i.log.gz"

        append="true">

        <Filters>

           <ThresholdFilterlevel="ERROR" onMatch="ACCEPT"

              onMismatch="DENY" />

        </Filters>

        <PatternLayout

           pattern="[%date{yyyy-MM-ddHH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n" />

        <Policies>

           <TimeBasedTriggeringPolicyinterval="1"

              modulate="true" />

           <SizeBasedTriggeringPolicysize="1MB" />

        </Policies>

      </RollingRandomAccessFile>

   </Appenders>

  

   <!-- 全局配置,默认所有的Logger都继承此配置 -->

   <!-- 用来配置LoggerConfig,包含一个root logger和若干个普通logger

   additivity指定是否同时输出log到父类的appender,缺省为true

   一个Logger可以绑定多个不同的Appender。只有定义了logger并引入的appenderappender才会生效。 -->

   <Loggers> <!-- 第三方的软件日志级别 -->

      <loggername="org.springframework" level="info"additivity="true">

        <AppenderRef ref="warnLog"/>

        <AppenderRef ref="errorLog"/>

      </logger>

      <loggername="java.sql.PreparedStatement" level="debug"

        additivity="true">

        <AppenderRef ref="Console"/>

      </logger>

      <!-- root logger 配置 -->

      <Root level="info"includeLocation="true">

        <AppenderRef ref="infoLog"/>

        <AppenderRef ref="Console"/>

        <AppenderRef ref="errorLog"/>

      </Root>

      <!-- AsyncRoot - 异步记录日志 - 需要LMAXDisruptor的支持 -->

      <!-- <AsyncRootlevel="info" additivity="false">

        <AppenderRef ref="Console"/>

        <AppenderRef ref="infoLog"/>

        <AppenderRef ref="errorLog"/>

      </AsyncRoot> -->

   </Loggers>

</Configuration>

 

用于测试,所以SizeBasedTriggeringPolicy日志文件大小最大设置为1MB;实际使用根据情况调整;

 

Controller类:

   @RequestMapping("/wyait")

   @ResponseBody

   public String getMsg(HttpServletResponseresponse) {

      LOGGER.debug("===========debug信息>>>>"+ paramProperties);

      LOGGER.info("===========info信息>>>>"+ paramProperties);

      LOGGER.trace("I am trace log.");

      LOGGER.debug("I am debug log.");

      LOGGER.warn("I am warn log.");

      LOGGER.error("I am error log.");

      // 手动异常

      System.out.println(1 / 0);

      // 会有中文乱码问题 TODO

      return paramProperties.getWyaitName() +" 正在写"

           + paramProperties.getWyaitTitle() +"!总结:"

           + paramProperties.getWyaitMessage();

   }

 

启动项目,访问:http://127.0.0.1:8080/cat/wyait

wKiom1nNonfwQiEfAAArEdlm5co581.png

 

查看日志目录:

wKiom1nNon_AinPFAAAegQpysMM118.png

1.1    log4j2配置属性详解

(1)根节点Configuration有两个属性:statusmonitorinterval,有两个子节点:AppendersLoggers(表明可以定义多个AppenderLogger).

 

    status用来指定log4j本身的打印日志的级别.

    monitorinterval用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s.(如果更改配置文件,不用重启系统)

 

(2)Appenders节点,常见的有三种子节点:ConsoleRollingFileFile.

 

    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 hourmodulate=true用来调整时间:比如现在是早上3aminterval4,那么第一次滚动是在4am,接着是8am12am...而不是7am.

        SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小.

        DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性)

 

(3)Loggers节点,常见的有两种:RootLogger.

 

    Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出

        level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn <Error < Fatal < OFF.

        AppenderRefRoot的子节点,用来指定该日志输出到哪个Appender.

 

    Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。

        level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn <Error < Fatal < OFF.

        name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.

        AppenderRefLogger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个AppenderRootAppender中都会输出,此时我们可以设置Loggeradditivity="false"只在自定义的Appender中进行输出。

 

(4)关于日志level.

 

共有8个级别,按照从低到高为:All< Trace < Debug < Info < Warn < Error < Fatal < OFF.

 

        All:最低等级的,用于打开所有日志记录.

        Trace:是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出.

        Debug:指出细粒度信息事件对调试应用程序是非常有帮助的.

        Info:消息在粗粒度级别上突出强调应用程序的运行过程.

        Warn:输出警告及warn以下级别的日志.

        Error:输出错误信息日志.

        Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志.

        OFF:最高等级的,用于关闭所有日志记录.

 

程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少。



本文转自 wyait 51CTO博客,原文链接:http://blog.51cto.com/wyait/1969613,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
7996 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
2673 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
10396 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
9763 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
11739 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
8291 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
4508 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
21137 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
6480 0
13694
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载