日志系统 Log4j 的使用

一、Log4j 简介

Log4j 是 Apache 的一个开放源代码项目,通过使用 Log4j,我们可以控制日志信息输送的目的地(控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIXSyslog守护进程等);我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码

Log4j 是 Apache 为 Java 提供的日志管理工具。他与 System.out.println() 的作用相似,用来跟踪、调试、维护程序。

二、Log4j 原理

Log4j设计实现为分层结构,每一层都提供了不同的类,实现不同功能的对象执行不同的任务,在实际的使用中可以根据自己的具体需求灵活的进行扩展。不同组件的框架图如下:

在这里插入图片描述
如上图所示,log4j 框架中有两种对象:
(1)核心对象:框架的支撑对象,是框架必不可少的组成部分。

核心对象包括下面几种类型:
logger 对象:是最高的层,负责获取不同级别日志信息,将不同的风格转化日志信息,他提供给appender对象发布前的信息。(这里的层是指所处的位置)
layout 对象:用于提供格式化不同风格的日志信息,在发布日志信息前,使其变得可读,可重用。
appender 对象:这个对象属于底层的对象,它负责发布信息到不同的目的地,比如数据库,文件,控制台,UNIXsyslog等等。

(2)支撑对象:这些都是框架可选的对象,用于提供额外重要的工作。

level 对象:用于定义日志的级别(粒度和优先级),有七种级别:

off 最高等级,用于关闭所有日志记录。
fatal 指出每个严重的错误事件将会导致应用程序的退出。
error 指出虽然发生错误事件,但仍然不影响系统的继续运行。
warm 表明会出现潜在的错误情形。
info 一般和在粗粒度级别上,强调应用程序的运行全程。
debug 一般用于细粒度级别上,对调试应用程序非常有帮助。
all 最低等级,用于打开所有日志记录。

过滤器对象用于分析日志信息并决定日志信息是否输出。每个 appender 对象可以有几个过滤器对象协同工作,当日志信息到达特定的 appender 时,所有的过滤器会帮助appender在其发布到目的地之前进行过滤操作

对象渲染器:提供一段字符用于识别发送日志的不同对象,这个对象也用于layout对象准备常量信息。
日志管理器:用于管理日志框架,它负责从初始化配置中读取信息,这个配置可能是文件配置,也可能是类的配置

三、Log4j 使用

Log4j 的使用主要有两个步骤,首先定义 Log4j 的配置文件,然后在代码中获取 Log4j 日志记录器。
配置文件主要支持两种文件格式,XML 格式和 Java 键-值格式的配置文件。这里以第一种格式为例。

1、定义 Log4j 的配置文件

Log4j.properties 文件是 Log4j 的配置文件,默认情况下放到 src 目录下即会自动查找到。

(1)配置根 Logger

log4j.rootLogger = [ level ] , appenderName1, appenderName2, …

● level 指定日志的级别,高于等于error级别的日志信息都会输出;
● appenderName 指定相应级别日志的输出目的地及一些属性;

(2)配置日志信息输出目的地 Appender

log4j.appender.appenderName = fully.qualified.name.of.appender.class  
log4j.appender.appenderName.option1 = value1   …  
log4j.appender.appenderName.option = valueN   

Log4j 提供的 appender 有以下几种:

org.apache.log4j.ConsoleAppender(控制台),  
org.apache.log4j.FileAppender(文件),  
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),  
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方) 
org.apache.log4j.JDBCAppender(把日志输出到特定的数据库中)

把日志输出到特定的数据库中时要配置的属性有:

● bufferSize 设置buffer的大小,默认是1
● driver 设置数据库的驱动字符串,比如:com.mysql.jdbc.Driver
● layout 设置使用的layout,默认是org.apache.log4j.PatternLayout
● password 设置数据库的密码
● sql 设置每次日志产生的时候执行的sql语句,可以是insert,update,detele
● url 是指数据库的url
● user 设置数据库的用户名
示例:

log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.URL=jdbc:mysql://localhost/DBNAME
log4j.appender.DB.driver=com.mysql.jdbc.Driver
log4j.appender.DB.user=user_name log4j.appender.DB.password=password
log4j.appender.DB.sql=INSERT INTO LOGS
VALUES('%x','%d','%C','%p','%m')
log4j.appender.DB.layout=org.apache.log4j.PatternLayout     

(3)配置日志信息的格式(布局)

log4j.appender.appenderName.layout= fully.qualified.name.of.layout.class  
log4j.appender.appenderName.layout.option1 = value1   …  
log4j.appender.appenderName.layout.option = valueN   

Log4j 提供的 layout 有以下几种:

org.apache.log4j.HTMLLayout(以HTML表格形式布局),  
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),  
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),  
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息) 

使用org.apache.log4j.PatternLayout布局时需要指定输出的格式,定义为:

log4j.appender.E.layout.ConversionPattern = value 

ConversionPattern参数的格式含义类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:

%m 输出代码中指定的消息 %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL   
%r 输出自应用启动到输出该log信息耗费的毫秒数   
%c 输出所属的类目,通常就是所在类的全名   
%t 输出产生该日志事件的线程名   
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”   
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921   
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.jav

2、Java 类中使用 log4j

(1)获取日志记录器

使用Log4j, 第一步就是获取日志记录器, 这个记录器将负责控制日志信息。日志类提供了很多方法处理日志活动,它不允许我们自己实例化一个logger,但是提供给我们两种静态方法,获得logger对象。

public static Logger getRootLogger();
public static Logger getLogger(String name);
public static Logger getLogger(Class clazz) 
// getLogger( Class class) 其实调用的是getLogger(class.getName())

第一种方法返回应用实例的根 Logger,它没有名字。
第二种方法通过名字获得日志对象 Logger,一般取日志信息所在类的名字
第三种方法通过 class 对象获得日志对象 Logger,用来指定打印出日志信息所在类。如:

static Logger logger = Logger.getLogger (ServerWithLog4j.class)

日志器的名称不只是一个名称而已,日志器的名称说明了日志器之间的父子关系。子日志器会继承父日志器的 Appender 和 Level
日志器的父子关系是通过日志器的名称来决定的,例如名称为 com.chj 的日志器是 com.chj.logger 的日志器的爸爸。com.chj.logger会继承com.chj的Appender以及Level。

(2)读取配置文件

当获得了日志记录器之后,第二步将配置 Log4j 环境,其语法为:

BasicConfigurator.configure ()  // 自动快速地使用缺省Log4j环境。  
PropertyConfigurator.configure ( String configFilename)   // 读取使用Java的特性文件编写的配置文件。  
DOMConfigurator.configure ( String filename )   // 读取XML形式的配置文件。

(3)插入记录信息(格式化日志信息)

当上两个必要步骤执行完毕,您就可以轻松地使用不同优先级别的语句插入到您想记录日志的任何地方,其语法如下:

Logger.debug ( Object message ) ;  
Logger.info ( Object message ) ;  
Logger.warn ( Object message ) ;  
Logger.error ( Object message ) ;

四、Web 项目中使用 Log4j

上面代码描述了 Log4j 的简单应用,其实使用 Log4j 也就是这样简单方便。当然除了上面的配置方法,还有其它,比如做一个 J2EE 应用,在 J2EE 应用使用 Log4j,必须先在启动服务时加载 Log4j 的配置文件进行初始化,可以在 web.xml 中进行。

web.xml 配置 log4j 的方式:

新建一个servlet,这个 servlet 在 init 函数中为 log4j 执行配置。一般就是读入配置文件,所以需要在 web.xml 中为这个 servlet 配置,同时设定 load-on-startup为1。 配置文件位置在 web.xml 中配置一个 param 即可,路径一般是相对于 web 的 root 目录。web 容器在启动服务时加载 Log4j 的配置文件然后调用 configure 函数进行初始化(文件在哪里、正确的文件类型)

web.xml配置如下:

<!--用来启动 log4jConfigLocation的servlet -->  
<servlet>  
	<servlet-name>Log4JInitServlet</servlet-name>  
	<servlet-class>com.mucfc.Log4JInitServlet</servlet-class>  
	<init-param>  
		<param-name>log4j-properties-location</param-name>  
		<param-value>/WEB-INF/classes/log4j.properties</param-value>  
	</init-param>  
	<load-on-startup>1</load-on-startup>  
</servlet>  

五、Log4j 示例

1、添加依赖

<dependency>
	<groupId>log4j</groupId>
	<artifactId>log4j</artifactId>
	<version>1.2.17</version>
</dependency>

2、配置文件

<!-- 指定级别为 error,高于等于 error 级别的日志信息都会输出 -->
log4j.rootLogger = error,stdout,E 

<!-- 配置 stdout,日志输出到控制台 -->
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
<!-- 配置 stdout,日志输出格式采用 PatternLayout 格式 -->
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

<!-- 配置 E,以文件形式输出,指定DailyRollingFileAppender根据时间对日志进行切割 -->
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
<!-- 配置输出文件位置 -->
log4j.appender.E.File =F://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
<!-- 配置以小时分隔日志文件,即就是一个小时产生一个日志文件 -->
log4j.appender.T.DatePattern='.'yyyy-MM-dd-HH   
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

3、Java 类

package test;
import org.apache.log4j.Logger;     // 不要导错包

public class Log4j_test {
    
    
    static Logger LOG = Logger.getLogger(Log4j_test.class);   // 获取日志记录器
    public static void main(String[] args) {
    
    
        LOG.debug("hello");   // 指定日志信息
        LOG.error("hello");
        LOG.fatal("fatal");
        LOG.warn("warn");
    }
}

因为指定的日志级别是 error,所以只有 error 和 fatal 级别日志会输出,程序输出如下:
在这里插入图片描述
因为指定了输出文件,所以可以在 F://logs/ 目录中发现文件 error.log。
在这里插入图片描述

六、SpringBoot 集成 Log4j 日志框架

1、常用日志框架

● java.util.logging:是JDK在1.4版本中引入的Java原生日志框架
● Log4j:Apache的一个开源项目,可以控制日志信息输送的目的地是控制台、文件、GUI组件等,可以控制每一条日志的输出格式,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。虽然已经停止维护了,但目前绝大部分企业都是用的log4j。
● LogBack:是Log4j的一个改良版本 Log4j2:Log4j2已经不仅仅是Log4j的一个升级版本了,它从头到尾都被重写了

2、日志门面 slf4j

上述介绍的是一些日志框架的实现,这里我们需要用日志门面来解决系统与日志实现框架的耦合性。SLF4J,即简单日志门面(Simple Logging Facade for Java),它不是一个真正的日志实现,而是一个抽象层( abstraction layer),它允许你在后台使用任意一个日志实现。
在这里插入图片描述
(1)解耦合

前面介绍的几种日志框架都一样,每一种日志框架都有自己单独的API,要使用对应的框架就要使用其对应的API,这就大大的增加应用程序代码对于日志框架的耦合性。

使用了 slf4j 后,对于应用程序来说,无论底层的日志框架如何变,应用程序不需要修改任意一行代码,就可以直接使用了

实际上,SLF4J 所提供的核心 API 是一些接口以及一个 LoggerFactory 的工厂类。从某种程度上,SLF4J有点类似JDBC,不过比JDBC更简单,在JDBC中,你需要指定驱动程序,而在使用SLF4J的时候,不需要在代码中或配置文件中指定你打算使用那个具体的日志系统。如同使用 JDBC 基本不用考虑具体数据库一样,SLF4J 提供了统一的记录日志的接口,只要按照其提供的方法记录即可,最终日志的格式、记录级别、输出方式等通过具体日志系统的配置来实现,因此可以在应用中灵活切换日志系统

(2)SLF4J有以下几点优势:

● Log4j 提供 TRACE、DEBUG、INFO、WARN、ERROR 和 FATAL 六种纪录等级,但是 SLF4J 认为 ERROR 与 FATAL 并没有实质上的差别,所以拿掉了 FATAL 等级,只剩下其他五种。

● 大部分人在程序里面会去写 logger.error(exception),其实这个时候 Log4j 会去把这个exception tostring。真正的写法应该是logger(message.exception);而 SLF4J 就不会使得程序员犯这个错误。

● Log4j 间接的在鼓励程序员使用 string 相加的写法(这种写法是有性能问题的),而 SLF4J 就不会有这个问题,你可以使用 logger.error(“{} is+serviceid”,serviceid);

● 使用 SLF4J 可以方便的使用其提供的各种集体的实现的jar。(类似commons-logger)

● 从 commons–logger 和 Log4j merge 非常方便,SLF4J 也提供了一个 swing 的 tools 来帮助大家完成这个merge。

● SLF4J 只支持 MDC,不支持 NDC。

● 提供字串内容替换的功能,会比较有效率,如:

// 传统的字符串产生方式,如果没有要记录 Debug 等级的信息,就会浪费时间在产生不必要的信息上
logger.debug("There are now " + count + " user accounts: " + userAccountList);   
// 为了避免上述问题,我们可以先检查是不是开启了 Debug 信息记录功能,只是程序的编码会比较复杂
if (logger.isDebugEnabled()) {
     
         
	logger.debug("There are now " + count + " user accounts: " + userAccountList); 
  }   
// 如果 Debug 等级没有开启,则不会产生不必要的字符串,同时也能保持程序编码的简洁
logger.debug("There are now {} user accounts: {}", count, userAccountList); 

3、为什么选用 log4j2

相比与其他的日志系统,log4j2丢数据的情况少;在多线程环境下,disruptor技术性能高于logback等10倍以上;利用jdk1.5并发的特性,减少了死锁的发生

在这里插入图片描述
可以看到在同步日志模式下, Logback的性能是最糟糕的。
log4j2 的性能无论在同步日志模式还是异步日志模式下都是最佳的。
在这里插入图片描述

log4j2 优越的性能其原因在于 log4j2 使用了 LMAX,用一个无锁的线程间通信库代替 logback 和 log4j 的队列,并发性能大大提升

4、整合日志框架 log4j2

(1)导入依赖

springboot 默认使用 logback 日志框架的,所以需要排除 logback,不然会出现 jar 依赖冲突的报错

<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-web</artifactId> 
    <!-- 去掉 springboot 默认日志框架配置 --> 
    <exclusions>  
        <exclusion>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-logging</artifactId>  
        </exclusion>  
    </exclusions>   
</dependency> 

<!-- 引入log4j2依赖 -->   
<dependency> 
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-log4j2</artifactId>   
</dependency>  

(2)配置文件

1)方式一:springboot 中 log4j2 的配置文件默认名为 log4j2-spring.xml,这样就不用再在application.yml 中进行配置。
2)方式二:如果自定义了配置文件名称,则需要在 application.yml 或 Java 代码中配置:

yml 文件:

logging:   
	config: xxxx.xml   
	level:
    	cn.jay.repository: trace 

Java 代码:

PropertyConfigurator.configure("conf/log4j.properties"); 

PropertyConfigurator.configure() 函数加载指定位置的 log4j 配置文件。如果没有自定,默认会读取包下面的 log4j.properties 配置。

log4j2 配置文件 xml 模板:

<?xml version="1.0" encoding="UTF-8"?>
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--> 
<configuration monitorInterval="5">   
	<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->

    <!--变量配置-->  
  <Properties>
    <!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
    <!-- %logger{36} 表示 Logger 名字最长36个字符 -->
    <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
    <!-- 定义日志存储的路径 -->
    <property name="FILE_PATH" value="更换为你的日志路径" />
    <property name="FILE_NAME" value="更换为你的项目名" />   
  </Properties>


  <appenders>
  
    <console name="Console" target="SYSTEM_OUT">
      <!--输出日志的格式-->
      <PatternLayout pattern="${LOG_PATTERN}"/>
      <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
      <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
    </console>

    <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
    <File name="Filelog" fileName="${FILE_PATH}/test.log" append="false">
      <PatternLayout pattern="${LOG_PATTERN}"/>
    </File>

    <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
    <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log"
filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
      <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
      <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
      <PatternLayout pattern="${LOG_PATTERN}"/>
      <Policies>
        <!--interval属性用来指定多久滚动一次,默认是1 hour-->
        <TimeBasedTriggeringPolicy interval="1"/>
        <SizeBasedTriggeringPolicy size="10MB"/>
      </Policies>
      <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
      <DefaultRolloverStrategy max="15"/>
    </RollingFile>

    <!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
    <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log"
filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
      <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
      <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
      <PatternLayout pattern="${LOG_PATTERN}"/>
      <Policies>
        <!--interval属性用来指定多久滚动一次,默认是1 hour-->
        <TimeBasedTriggeringPolicy interval="1"/>
        <SizeBasedTriggeringPolicy size="10MB"/>
      </Policies>
      <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
      <DefaultRolloverStrategy max="15"/>
    </RollingFile>

    <!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
    <RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log"
filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
      <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
      <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
      <PatternLayout pattern="${LOG_PATTERN}"/>
      <Policies>
        <!--interval属性用来指定多久滚动一次,默认是1 hour-->
        <TimeBasedTriggeringPolicy interval="1"/>
        <SizeBasedTriggeringPolicy size="10MB"/>
      </Policies>
      <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
      <DefaultRolloverStrategy max="15"/>
    </RollingFile>

  </appenders>

  <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->  
<!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->   <loggers>

    <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
    <logger name="org.mybatis" level="info" additivity="false">
      <AppenderRef ref="Console"/>
    </logger>
    <!--监控系统信息-->
    <!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
    <Logger name="org.springframework" level="info" additivity="false">
      <AppenderRef ref="Console"/>
    </Logger>

    <root level="info">
      <appender-ref ref="Console"/>
      <appender-ref ref="Filelog"/>
      <appender-ref ref="RollingFileInfo"/>
      <appender-ref ref="RollingFileWarn"/>
      <appender-ref ref="RollingFileError"/>
    </root>   </loggers>

</configuration> 

log4j2 配置参数介绍:
(1)根节点 Configuration 有两个属性 status 和 monitorinterval。

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

● monitorinterval 用于指定 log4j 自动重新配置的监测间隔时间,单位是s,最小是5s。

(2)根节点 Configuration 有两个子节点:Appenders 和 Loggers(表明可以定义多个Appender和Logger)。

● Appenders 节点常见的有三种子节点 Console、RollingFile、File。

1)Console 节点用来定义输出到控制台的Appender

name 指定Appender的名字;
target 为 SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认SYSTEM_OUT。
PatternLayout 指定输出格式,不设置默认为 %m%n。

2)File 节点用来定义输出到指定位置的文件的Appender

name:指定Appender的名字;
fileName:指定输出日志的目的文件带全路径的文件名;
PatternLayout:输出格式,不设置默认为:%m%n。

3)RollingFile 节点用来定义超过指定条件自动删除旧的创建新的Appender

name 指定 Appender 的名字;
fileName 指定输出日志的目的文件带全路径的文件名;
PatternLayout 指定输出格式,不设置默认为:%m%n;
filePattern 指定当发生Rolling时,文件的转移和重命名规则;
Policies 指定滚动日志的策略,就是什么时候进行新建日志文件输出日志;
TimeBasedTriggeringPolicy 是 Policies 子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour;modulate=true 用来调整时间,比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am…而不是7am;
SizeBasedTriggeringPolicy 是 Policies 子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小;
DefaultRolloverStrategy 用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max属性)。

● Loggers节点,常见的有两种 Root和Logger。

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

level 指定日志输出级别;
AppenderRef 为 Root 的子节点,用来指定该日志输出到哪个Appender。

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

level 指定日志输出级别;
name 指定该 Logger 所适用的类或者类所在的包全路径,继承自Root节点;
AppenderRef 是 Logger的子节点,用来指定该日志输出到哪个 Appender,如果没有指定,就会默认继承自Root,如果指定了,那么会在指定的这个 Appender 和 Root 的 Appender 中都会输出,此时我们可以设置 Logger 的 additivity=“false” 只在自定义的 Appender 中进行输出。

(3)Controller 中使用 log4j2

1)方式一:非 Slf4j 门面模式

import org.apache.log4j.Logger;

@RestController //声明Rest风格的控制器
@RequestMapping("/logging")
public class LogController {
    
    
    Logger logger=Logger.getLogger(LogController.class);

    @RequestMapping("logtest")
    @ResponseBody
    public String logtest(){
    
    
        logger.fatal("致命错误");
	logger.error("严重警告");
	logger.warn("警告");
	logger.info("普通信息");
	logger.debug("调试信息");
	return "";
    }
}

2)方式二:@Slf4j 门面模式

● Java 代码

 import org.apache.log4j.PropertyConfigurator; 
 import org.slf4j.Logger; 
 import org.slf4j.LoggerFactory;

@RestController //声明Rest风格的控制器 
@RequestMapping("/logging") 
public class LogController {
     
     
    
    try {
     
     
    		PropertyConfigurator.configure("conf/log4j.properties");
    		// 使用指定类初始化日志对象,在日志输出的时候,可以打印出日志信息所在类
    		Logger logger = LoggerFactory.getLogger(LogController.class);
    		logger.info("test");
    	} catch (Exception ex) {
     
     
    		System.out.println( ex.getMessage());
    	} 	
    } 

● @Slf4j 注解

lombok 中的 @Slf4j 注解可以很方便的使用 org.slf4j.Logger 对象。日常开发尽量使用 Slf4j 门面来处理日志,尽量避免使用具体的日志框架。

@Slf4j 
@RestController 
@RequestMapping("/logging") 
public class LogController {
     
         
	
	@GetMapping("/do")  
	public String log() {
     
     
    	log.info("log4j2 test date: {} info: {}", LocalDate.now(), "日志框架学习");    
    	return "log4j2";  
    }    
  } 

猜你喜欢

转载自blog.csdn.net/IT__learning/article/details/119790307