使用 Log4J 进行日志操作

1. 使用 Log4J 进行日志操作

1.2 Log4J 简介

Log4J主要由三大组件构成:

  • Logger:负责生成日志,并能够对日志信息分类筛选。
  • Appender:定义了日志信息输出的目的地,这些地方可以是控制台、文件和网络设备等。
  • Layout:指定日志信息的输出格式。

一个Logger可以有多个Appender,这意味着日志信息可以同时输出到多个设备,每个Appender都对应一种Layout,Layout决定了输出日志信息的格式。

1.2.1 Logger 组件

Logger是Log4J的核心组件,他代表了Log4J的日志记录器,他能够对日志信息进行分类筛选,决定什么日志信息应该被输出,什么日志信息应该被忽略。

//打印各种级别的日志的方法
public void trace(Object message);
public void debug(Object message);
public void info(Object message);
public void warn(Object message);
public void error(Object message);
public void fatal(Object message);

//打印日志的通用方法
public void log(Level level, Object message);

org.apache.logging.log4j.LogManager 类提供了获得 Logger 实例的静态方法:

//返回根 Logger 对象
public static Logger getRootLogger();
//根据参数指定的名字返回特定的 Logger 对象
public  static Logger getLogger(String name);

可以在 Log4J 的 XML 格式的配置文件中配置自己的Logger 组件,例如以下代码配置了一个Logger组件,名为helloappLogger:

<Logger name="helloappLogger" level="warn" additivity="false">
	<AppenderRef ref="console"/>
</Logger>

以上代码定义了一个Logger组件。名为helloappLogger,并为它分配了一个日志级别(LEVEL),取值为“WARN”。一共有六种日志级别:FATAL、ERROR、WARN、INFO、DEBUG、TRACE,其中 FATAL 的日志级别最高。

只有当打印日志的级别大于或等于Logger组件配置的日志级别时,日志打印方法才会被执行。

例如对于以上配置的helloappLogger,它的日志级别为 WARN,那么在程序中,他的 fatal()、error() 和 warn() 方法会被执行,而 info()、debug() 和 trace() 方法不会被执行,对于 log() 方法,只有当他的 Level类型的参数level指定的日志级别大于或等于 WARN,这个方法才会被执行。

helloapplogger.log(Level.WARN, "This is a warn message!");

例如以上 log() 方法的 level 参数为Level.WARN,因此该方法会被执行。

假如不需要输出级别为WARN的日志信息,可以在配置文件中把helloappLogger 组件的级别调高。比如调到ERROR或FATAL级别,这样WARN级别以及以下级别的日志就不会输出了。

1.2.2 Appender 组件

目前,Log4J 的 Appender 支持将日志信息输出到以下目的地:

  • 控制台(Console)
  • 文件(File)
  • 远程套接字服务器(Remote socket server)
  • NT 的事件记录器
  • 远程 UNIX Syslog 守护进程(Remote UNIX Syslog daemon)

一个 Logger可以同时对应多个Appender 。例如要为 helloappLogger 配置两个Appender 。一个是file,一个是console,则可以采用如下配置代码:

<Logger name="helloappLogger" level="warn" additivity="false">
	<AppenderRef ref="file"/>
	<AppenderRef ref="console"/>
</Logger>

1.2.3 Layout 组件

Layout组件用来决定日志的输出格式,他有以下几种类型:

  • org.apache.log4j.PatternLayout(可以灵活的指定布局模式)
  • org.apache.log4j.HTMLLayout(以HTML形式布局)
  • org.apache.log4j.XMLLayout(以XML形式布局)
  • org.apache.log4j.SerializedLayout(产生可以序列化的信息)

PatternLayout 可以让开发者依照 Conversion Pattern(转换模式)去定义输出格式。Conversion Pattern 有点像C语言的print打印函数,开发者可以通过一些预定的符号来指定日志的内容和和格式,这些符号的说明参见表1-1

表1-1 PatternLayout的格式
符号描述
%r自程序开始运行到输出当前日志信息所消耗的毫秒数
%t输出产生该日志的线程全名
%level输出当前日志的级别
%d输出当前日志的日期和时间,默认为 ISO8601,也可以指定格式,如:%d{yyyy年MM月dd日 HH:mm:ss}
%logger输出当前日志的 Logger 的名称
%msg%n输出日志信息的内容

例如,要为名为 “file” 的 Appender 配置的 PatternLayout 布局,可以采用如下配置代码:

<File name="file" fileName="app.log">
	<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</File>

采用以上PatternLayout 布局,从日志文件中看到的输出日志的形式如下:

11:10:06.758 [main] WARN helloappLogger - 
This is a log message from the helloappLogger

以上日志内容中,PatternLayout 的预定符号与具体内容的对应关系如下:

  • “d” 对应 “11:10:06.758”
  • “%t”对应 “main”
  • “%-5level” 中的“-5”设定日志级别在显示时占用五个空格位。
  • “%logger{36}” 对应 “helloapplogger”
  • “%msg%n” 对应具体的日志信息

1.2.4 Logger 组件的继承性

Log4J 提供了一个root Logger,它是所有Logger组件的“祖先”,以下是配置root Logger的代码:

<Root level="info">
	<AppenderRef ref="console"/>
</Root>

用户可以在配置文件中方便的配置存在继承关系的Logger组件,凡是在符号“.” 后面的Logger组件都会成为在符号“.” 前面的Logger组件的子类。例如:

<Logger name="helloappLogger。childLogger" level="INFO" additivity="false">
	<AppenderRef ref="console"/>
</Logger>

对于以上配置,childLogger就是helloappLogger的子类Logger组件。

Logger组件的继承关系有以下特点:

  • 如果子类Logger组件没有配置日志级别,则将继承父类的日志级别。
  • 如果子类Logger组件配置了日志级别,就不会继承父类的日志级别。
  • 默认情况下,子类Logger组件会继承父类所有的所有的Appender ,把它们加入到自己的Appender 清单中。
  • 如果在配置文件中把子类Logger组件的additivity属性设为false,那么他就不会继承父类的Appender 。additivity标志的默认值为true。

建议在配置文件中把子类的additivity属性设为false。否则,会导致子类Logger组件在输出日志信息时,除了会通过自身的Appender 输出日志,还会用父类的Appender 输出日志,这可能会导致重复输出日志的现象。

1.3 Log4J 的基本使用方法

首先需要在一个配置文件中配置Log4J 的各个组件,然后就可以在程序中通过lLog4J API来操作日志。

1.3.1 创建 Log4J 的配置文件

Log4J 支持 XML 格式的配置文件,这个配置文件的默认名为:log4j2.xml。这个配置文件的默认存放路径是 classpath 的根路径。如下例程1-1的log4j2.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>
    
    <File name="file" fileName="app.log">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
    </File>
  </Appenders>
  
  <Loggers>
    <Root level="info">    
      <AppenderRef ref="console" /> 
    </Root>
    
    <Logger name="helloappLogger" level="warn" additivity="false">	
      <AppenderRef ref="file" />
      <AppenderRef ref="console" />
    </Logger>
    
    <Logger name="helloappLogger.childLogger" level="debug" additivity="false">
      <AppenderRef ref="console" />		
    </Logger>
 </Loggers>
</Configuration>

比如Web应用的classpath 的根路径为 /WEB-INF/classes 目录。如果要存放到其他目录下,那么还需要在 web.xml文件中通过<context-param>元素进行配置:

<context-param>
	<param-name>log4jConfiguration</param-name>
	<param-value>/WEB-INF/conf/log4j2.xml</param-value>
</context-param>

以上配置代码表明Log4J的配置文件 log4j2.xml 存放在 WEB-INF/conf 目录下。

1.3.2 在程序中使用 Log4J

需要用到Log4J 的JAR文件。Log4J的下载地址为https://logging.apache.org/log4j。下载了Log4J 的压缩文件 apache-log4j-X-bin.zip后,解压后的目录中包含了Log4J的所有JAR文件。

程序中使用Log4J包含以下步骤:

(1)获得日志记录器

(2)输出日志信息

  1. 获得日志记录器

    //获得 root Logger
    Logger rootLogger = LogManager.getRootLogger();
    
    //获得用户自定义的 Logger
    Logger helloappLogger = Logger.getLogger("helloappLogger");
    Logger childLogger = LogManager.getLogger("helloappLogger.childLogger");
    

    以上的getRootLogger() 和getLogger() 方法会根据 Log4J 的配置文件中的信息来创建并返回相应的Logger对象。

    如果不存在配置文件那么rootLogger以及子类 Logger会采用以下默认的配置。他的日志级别为error:

    <?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>
    
  2. 输出日志信息

    获得了日志记录器Logger对象以后,就可以在程序代码中需要生成日志的地方。调用Logger的各种输出日志方法来输出不同级别的日志,例如:

    helloapplogger.warn("This is a log message from the " + helloapplogger.getName());
    
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值