log4j简介(一)

其实最好的入门方法就是去看:
http://logging.apache.org/log4j/1.2/manual.html

这里我将这篇入门文章的关键点提出来,让大家快速明白log4j中的基础概念。

首先log4j是干嘛的:
Log4j allows the developer to control which log statements are output with arbitrary granularity. It is fully configurable at runtime using external configuration files.
Log4j允许开发人员以任意粒度控制log的输出。而且它在运行期间完全是可配置的,通过使用外部配置文件。配置文件默认为log-config.xml。

同时log4j has been ported to the C, C++, C#, Perl, Python, Ruby, and Eiffel languages.

下面开始了啊~~最重要的部分!
Log4j有4个最关键的概念: loggers, logging request, appenders and layouts.
简单的说logger是记日志的主体。而log4j允许将log记录到多个目的地,这是通过appender实现的。layout则控制log的format。一切定义完成后,在代码中提交一个logging request的时候,将实现log功能。

创建一个logger后,在代码中调用类似logger.info("")的方法(a logging request),则实现了记录log。但是log将被写到哪里去,比如需要同时写到controller.log和gmi.log中,则需要有两个appender,分别是controller.log和gmi.log的appender。而每个appender都有自己的layout来控制实际输出日志时的格式,因为controller.log和gmi.log中日志的格式可能是不同的。

这些信息可以写在代码中,但是更常见的是使用配置文件。log4j会自动寻找可用的配置文件,匹配的过程参考下面链接中的“automatic configuration”

http://logging.apache.org/log4j/2.x/manual/configuration.html



logger
logger是记日志的主体。同时logger具有hierarchy层次的特性。且层次是通过logger的名字实现的。
比如一个名字为com.company的logger就是所有com.company.*的logger的祖先。
而所有logger的祖先就是rootLogger。
The most important logger you need to configure is the root logger. 下面是log-config.xml中关于rootlogger的一段:
<root>
        <level value="info"/>
        <appender-ref ref="rootlogfile_arch"/>
        <appender-ref ref="console"/>
</root>
再看一个普通logger的定义:
<logger name="com.company">
        <level value="info"
               class="com.company.gmi.GMILevel"/>
        <appender-ref ref="localgmilogfile_arch"/>
</logger>
注意rootlogger和logger的定义要素都是一样的。
并不是说logger必须在configuration file中定义。在代码中定义也是一样的:
Logger consoleLogger = Logger.getLogger(test.class);
logger的名字是consoleLogger.getName();

那么logger实现层次的目的是什么呢?也就是说一个logger从祖先那里继承的是什么呢?
答案是level,且只有level。

//默认appenders也会从父logger继承。但是可以修改这一行为。
只有当logger没有被assign level时,才会继承logger,且仅继续它父一级logger的level。

The set of possible levels, that is: trace, debug, info, warn, error, fatal.
但是完全可以自定义level。

logging request
通过使用the printing methods来提交一个logging request。已有的printing methods有:
debug, info, warn, error, fatal and log.

使用print method: logger.info("");
而printing method决定了一个logging request的level. 例如,c.info("..") is a logging request of level INFO.
可以想到,printing ,method就是logger class中提供的方法。因此,如果是自定义的logger class,则需要在class主体中提供可使用的print method供使用。
但是当调用了logger.info()这样的方法时,并不意味着一定会记log。这是因为logger level属性的限制。
A log request of level p in a logger with (either assigned or inherited, whichever is appropriate) level q, is enabled if p >= q.
This rule is at the heart of log4j.也是level存在的现实意义。即,只有和logger的level级别相等或更重要的log才会被记录下来。这样也实现了写日志的集中控制。
下面这点也非常重要:

 Logger x = Logger.getLogger("wombat");
Logger y = Logger.getLogger("wombat");

x and y refer to exactly the same logger object.
Thus, it is possible to configure a logger and then to retrieve the same instance somewhere else in the code without passing around references.
也就是说,一旦创建了一个logger的实例,我们就可以在其他地方简单的使用它,而不需要再创建实例。理由是显而易见的:logger request可能会分散在代码的各个角落,而每次有logger request时都不得不先实例化一个logger再使用,显然过于浪费了。而且也不利于集中控制。getLogger方法据我的理解是如果不存在一个同名的logger实例,则创建一个;如果存在,则返回logger的实例。

在实际的代码中,时常会看见在很多class的开头都会定义以该类命名的logger,如:
Logger consoleLogger = Logger.getLogger(test.class);
这是一种使用的惯例吧。


到此为止你已经掌握了log4j的基本概念。
Congratulations~~~~~
在下一篇再继续介绍appender和layout。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值