你有一份Log4j学习指南,请查收!

简介

开源项目Log4j是一个功能强大的日志组件,提供方便的日志记录功能,能够根据配置将日志输出到不同的地方。日志在任何程序系统是不可缺少的,好的日志记录一定会给系统的维护带来巨大的帮助。
更多的介绍可以参考官方链接:

官网Log4j 1.x
官网Log4j 2.x
1.x 版本已经不再更新了,现在都是转为2.x (包括支持Lambda)

简单的例子

首先通过一个简单的例子,我们来认识下log4j的配置。

pom dependency

创建一个maven项目,以1.2.17版本为例,在pom.xml 文件中增加以下配置: maven会自动下载log4j-1.2.17.jar 到项目中

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

配置文件

Log4j支持两种格式的配置文件:

.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <!-- Appenders 日志信息输出目的地 -->

    <!-- ConsoleAppender -->
    <!-- 每个ConsoleAppender都有一个target,表示它的输出目的地。 -->
    <!-- 它可以是System.out,标准输出设备(缓冲显示屏) -->
    <!-- 或者是System.err,标准错误设备(不缓冲显示屏) -->
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.out" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %c - %m%n" />
        </layout>
    </appender>

    <!-- RollingFileAppender 回滚文件 -->
    <!-- ImmediateFlush, 一旦有新日志,马上写入文件,如果日志很多,会有性能问题,为了提高日志写入文件的性能,可以结合使用BufferedIO和BufferSize -->
    <!-- Append true,默认每次启动系统,日志继续输出到原来的文件 -->
    <!-- MaxFileSize 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件 -->
    <!-- MaxBackupIndex 最多20个 -->
    <!-- PatternLayout 控制日志输出的格式化 -->
    <!-- filter 级别范围过滤器 -->
    <!-- levelMin levelMax 范围 -->
    <appender name="all" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="D:/logs/all.log" />
        <param name="ImmediateFlush" value="true"/>
        <param name="Append" value="true"/>
        <param name="MaxFileSize" value="10MB"/>
        <param name="MaxBackupIndex" value="20"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %c - %m%n" />
        </layout>
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <param name="levelMin" value="DEBUG" />
            <param name="levelMax" value="ERROR" />
            <param name="AcceptOnMatch" value="true" />
        </filter>
    </appender>

    <!-- 为了测试 -->
    <appender name="File" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="D:/logs/log.log" />
        <param name="Append" value="true"/>
        <param name="MaxFileSize" value="10MB"/>
        <param name="MaxBackupIndex" value="20"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %c - %m%n" />
        </layout>
    </appender>

    <!-- 下面这些就是根据 这些路径来控制对应包下的文件的日志输出级别,基本上都是输出error日志-->
    <logger name="org.springframework.core">
        <level value="error" />
    </logger>

    <logger name="org.springframework.beans">
        <level value="error" />
    </logger>

    <logger name="org.springframework.context">
        <level value="error" />
    </logger>

    <logger name="org.springframework.http">
        <level value="error" />
    </logger>

    <logger name="org.springframework.web">
        <level value="error" />
    </logger>

    <logger name="org.elasticsearch.client.transport">
        <level value="debug" />
    </logger>

    <logger name="org.springframework.data.mongodb">
        <level value="error" />
    </logger>

    <!-- 这个就是自定义的一个logger -->
    <!-- additivity 这个默认是true,即继承父类 root logger -->
    <!-- 也就是说,你的这个日志也会在root的logger里面输出的,我这里配置false,就是不继承,各走各的。 -->
    <!-- appender-ref 也就是说这个logger的输出目的地是哪里,ref就是关联到上面声明的一个all,一个console -->
    <logger name="allLog" additivity="false">
        <level value="debug" />
        <appender-ref ref="all" />
        <appender-ref ref="console" />
    </logger>

    <!-- 根logger -->
    <!-- 输出级别是info级别及以上的日志,下面的ref关联的两个appender没有filter设置,所以,info及以上的日志都是会输出到这2个appender中 -->
    <root>
        <priority value="info" />
        <appender-ref ref="console" />
        <appender-ref ref="File" />
    </root>

</log4j:configuration>

实战经验:
上面定义了很多logger,对于包名(一般是自己项目真实的包)的判断,我们可以写一个公共方法来根据规则截取特定内容,然后通过下面的方式来获得Logger,然后将日志输出到特定文件:

例如:
static Logger logger2 = Logger.getLogger("org.springframework.core");

另一种方式:
如果只想要将某些包或者类下的日志输出到指定日志文件,可以使用category属性:

<category name="com.xxx.xxx" additivity="false">
	<level value="INFO" />
	<appender-ref ref="all" />
</category>
.properties文件

使用的较多一些
示例:log4j.properties文件,其中以 ### 开头表示是注释

log4j.rootLogger = debug, stdout, D, E

### 输出信息到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
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

### 输出DEBUG级别及以上级别的日志到 D:\logs\log.log文件中 ###
log4j.appender.D = org.apache.log4j.RollingFileAppender
### 文件目录及文件 ###
log4j.appender.D.File = D:\\logs\\log.log
### 最大文件大小 ###
log4j.appender.D.MaxFileSize = 100kb
### 备份文件个数 ###
log4j.appender.D.MaxBackupIndex = 10
### 往后追加 ###
log4j.appender.D.Append = true
### 可以指定日志level,例如这里就是输出DEBUG级别及以上级别的日志###
log4j.appender.D.Threshold = DEBUG
### 日志布局格式 ###
log4j.appender.D.layout = org.apache.log4j.PatternLayout
### 日志输出格式 ###
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %c - %m%n

### 输出ERROR 级别以上的日志到 D:\logs\error.log 文件中 ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =D:\\logs\\error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %c - %m%n

注意appender的Threshold 属性的作用,上面有注释说明。

使用

在代码中使用,步骤如下:

获取日志记录器

一般情况下,在一个类中,会通过该类名来获取,或者,根据logger名字来获取,如下例子,在maven项目中的App.java类中

static Logger logger = Logger.getLogger(App.class.getName());
或者
static Logger logger2 = Logger.getLogger("allLog");
// allLog是上面log4j.xml中定义的logger
读取配置文件

笔者测试时,是创建的maven项目,需要注意下面:
当配置文件放在src/main/resources的目录下时,直接可以写入log信息(从log4j 0.8.5版本起, 在类初始化的时候, log4j.properties(log4j.xml)文件将从用于加载类的路径中被查找,如果配置文件被发现,那将调用configure()方法来初始化log4j)。

public class App {

    static Logger logger = Logger.getLogger(App.class.getName());

    public static void main(String[] args) throws IOException {
        System.out.println("Hello World!");
        logger.debug("debug message");
        logger.info("info message");
        logger.warn("warn message");
        logger.error("error message");
    }
}

当配置文件不是直接放在src/main/resources的目录下时,需要加载properties文件,例如在src/main/resources/logging文件夹下,使用下面的方式来加载,当然这里也可以使用绝对路径

public class App {

    static Logger logger = Logger.getLogger(App.class.getName());

    public static void main(String[] args) throws IOException {

        PropertyConfigurator.configure("src/main/resources/logging/log4j.properties");

        System.out.println("Hello World!");
        logger.debug("debug message");
        logger.info("info message");
        logger.warn("warn message");
        logger.error("error message");
    }
}
写入log信息

调用下面的方法即可:

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

如果使用log4j.xml配置文件,可以做下面的测试,使用2个Logger,然后观察log输出情况:

public class App {

    static Logger logger = Logger.getLogger(App.class.getName());

    static Logger logger2 = Logger.getLogger("allLog");

    public static void main(String[] args) throws IOException {

        System.out.println("Hello World!");
        logger.debug("debug message");
        logger.info("info message");
        logger.warn("warn message");
        logger.error("error message");

        logger2.debug("debug message");
        logger2.info("info message");
        logger2.warn("warn message");
        logger2.error("error message");
    }
}

可以观察console的输出、产生的log文件名及内容。
在这里插入图片描述
其中logger使用了root的Logger定义,产生文件D:/logs/log.log,包括INFO级别以上的日志信息,如图:
在这里插入图片描述

其中logger2使用了allLog的Logger定义,产生文件D:/logs/all.log,包DEBUG到ERROR级别的日志信息,如图:
在这里插入图片描述
注意到,格式%c产生的效果也是不同的

三大组件

Logger

根logger主要定义log4j支持的日志级别及输出目的地,其语法为:

log4j.rootLogger = [ level ] , appenderName, appenderName, …

其中,level 是日志记录的优先级,下面列出的级别(优先级从高到低)或者自定义的级别。不区分大小写。
Log4J推荐使用:DEBUG, INFO, WARN, ERROR

OFF 	为最高等级 关闭了日志信息  
FATAL  	为可能导致应用中止的严重事件错误  
ERROR 	为严重错误 主要是程序的错误  
WARN 	为一般警告,比如session丢失  
INFO 	为一般要显示的信息,比如登录登出  
DEBUG 	为程序的调试信息  
TRACE 	为比DEBUG更细粒度的事件信息  
ALL 	为最低等级,将打开所有级别的日志

appenderName指定日志信息输出到哪个地方,可同时指定多个输出目的地。需在控制台输入,只需将其中一个appender定义为stdout即可。
注意: rootLogger 默认是对整个工程生效的。

Appender

Appender主要定义日志信息输出在什么位置,主要语法为:

log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
…
log4j.appender.appenderName.optionN = 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(将日志信息保存到数据库中)

以ConsoleAppender为例,如:

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out

Layout

Layout 负责格式化Appender的输出格式,其语法为:

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

其中,Log4j提供的layout有以下几种:

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

注意日志输出格式:

例如:
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%.30t] %c %x - %m%n

%c 输出日志信息所属的类的全名
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy-M-dd HH:mm:ss },输出类似:2002-10-18- 22:10:28
%f 输出日志信息所属的类的类名
%l 输出日志事件的发生位置,即输出日志信息的语句处于它所在的类的第几行
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL。如果是调用debug()输出的,则为DEBUG,依此类推,例如,用法%-5p,固定优先级的长度为5个字符
%r 输出自应用启动到输出该日志信息所耗费的毫秒数
%t 输出产生该日志事件的线程名, 例如,用法 [%.30t],限制线程名的长度为最后39个字符。
%x 按NDC(Nested Diagnostic Context,线程堆栈)顺序输出日志
%m 输出代码中指定的信息,如log(message)中的message
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”

Web应用中使用

简单的例子说明在web中的使用。

定义一个Initialization servlet
import org.apache.log4j.PropertyConfigurator;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.IOException;

public class Log4jInit extends HttpServlet {

  public
  void init() {
    String prefix =  getServletContext().getRealPath("/");
    String file = getInitParameter("log4j-init-file");
    // if the log4j-init-file is not set, then no point in trying
    if(file != null) {
      PropertyConfigurator.configure(prefix+file);
    }
  }

  public
  void doGet(HttpServletRequest req, HttpServletResponse res) {
  }
}
在web.xml文件中申明
<servlet>
    <servlet-name>log4j-init</servlet-name>
    <servlet-class>com.foo.Log4jInit</servlet-class>

    <init-param>
      <param-name>log4j-init-file</param-name>
      <param-value>WEB-INF/classes/log4j.properties</param-value>
    </init-param>

    <load-on-startup>1</load-on-startup>
  </servlet>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值