首页 » java

Log4j 官方文档翻译

   发表于:java评论 ()   热度:88

一、基本介绍

简介

log4j是使用java语言编写的可靠的、快速的、灵活的日志框架,它是基于Apache的license。

log4j支持c,c++,c#,perl,python,ruby等语言。在运行时通过额外的配置文件配置,提供不同的日志级别以及多种日志输出种类,比如数据库,文件,控制台,syslog等等。

log4j有三个主要部分:

  1. loggers 负责捕获日志信息
  2. appenders 负责输出信息到不同的目的地
  3. layouts 负责使用不同的样式输出日志

log4j的特性:

  • 线程安全
  • 优化速度
  • 基于命名的日志层次
  • 支持每个日志多个输出
  • 支持国际化internationalization
  • 不需要任何的预定义
  • 日志行为可以在运行的时候通过配置文件改变
  • 设计用来解决java启动时的异常
  • 有多种日志级别,比如ALL,TRACE,DEBUG,INFO,WARN,ERROR和FATAL
  • 通过扩展layout类,可以简单的格式化日志输出形式
  • 日志输出的目的地可以通过改变appender的实现策略来改变
  • 尽管log4j可以保证发送消息,但是它并不保证每一条消息都顺利的到达(只管发,不管接)

日志是软件开发中的重要组成部分,一个好的日志代码能够帮助快速调试,简单定位,结构化存储应用运行时的信息

日志不支持回溯,它会降低应用的运行速度。
如果输出详细的信息,可能会造成冗余。
针对这些问题,log4j被设计为可信的、快速的、以扩展的框架。

由于一般日志都不会作为应用的焦点,因此log4j的api尽量简单、易于使用。

LOG4J安装

step 1

log4j-x.x.x.jar

step 2

  • JavaMail API:支持e-mail日志特性
  • JavaBeans Activation Framework:Java Mail API也需要JavaBeans Activation Frameworkactivation.jar
  • Java Message Service:JMS特性需要
  • XML Parser:如果需要JAXP编译解析XML文件,那么需要使用这个

step 3

把它放在CLASSPATH和PATH中

在Eclipse中的使用

step 1

引入jar包

step 2

配置log4j.properies

step 3

初始化配置文件

step 4

使用logger打印日志

二、架构设计

log4j遵循层次化架构,每个层都有不同的对象来执行不同的任务。这种层次话的结构灵活设计、易于未来的扩展。

log4j框架中有两种对象:

  • 核心对象:框架的支撑对象,是框架必不可少的组成部分。
  • 支撑对象:这些是框架可选的对象,用于提供额外重要的工作。


核心对象包括下面几种类型:

  1. logger对象,是最高的层,负责通过不同的风格转化日志信息。它提供给appender对象发布前的信息。(这里的层是指所处的位置)
  2. layout对象,用于提供格式化日志信息的风格,在发布日志信息前,使其变得可读、可重用。
  3. appender对象,这个对象属于底层的对象,它负责发布信息到不同的目的地,比如数据库、文件、控制台、UNIXsyslog等等。


下面就是log4j的架构组成图:



支撑对象,他们在log4j框架中扮演了很关键的角色:

  1. level对象:级别对象定义来日志信息的粒度和优先级,有七种级别:OFF,DEBUG,INFO,ERROR,WARN,FATAL和ALL。
  2. 过滤器对象:用于分析日志信息并决定日志信息是否输出。每个appender对象可以有几个过滤器对象协同工作,当日志信息到达特定的appender时,所有的过滤器会功能帮助appender在其发布到目的地之前进行过滤操作。
  3. 对象渲染器:提供一段字符串用于识别发送日志的不同对象,这个对象也用于为layout对象准备常量信息。
  4. 日志管理器:用于管理日志框架,它负责从初始化配置中读取信息,这个配置可能是文件配置、也可能是类的配置。

三、配置

  之前的章节介绍了log4j的核心组件,本章将会通过配置文件介绍一下核心组建的配置。

  主要在配置文件中配置log4j的日志级别,定义appender、layout等。

  log4j.properties是log4j的配置文件,它采用键值对的方式定义。

  默认情况下,logManager对象会在CLASSPATH目录下寻找log4j.properties

先看看基本的配置模板

# Define the root logger with appender X
log4j.rootLogger = DEBUG, X
# Set the appender named X to be a File appender
log4j.appender.X=org.apache.log4j.FileAppender
# Define the layout for X appender
log4j.appender.X.layout=org.apache.log4j.PatternLayout
log4j.appender.X.layout.conversionPattern=%m%n

  看看这个配置文件都做了什么:

  • 首先日志的级别是DEBUG,另外还添加来一个appender,名字是X。
  • 设置appender的名字是X,并且定义该appender的实现为org.apache.log4j.FileAppender,即文件读写方式
  • 为X设置显示的方式——layout

真实样例

# Define the root logger with appender file
log4j.rootLogger = DEBUG, FILE
# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/log.out
# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

  上面的配置文件又做了什么呢?

  • 日志的root级别为DEBUG,DEBUG的appender名字是FILE。
  • 设置FILE的实现为org.apache.log4j.FileAppender,它会把日志信息写入日志目录中叫log.out的文件。
  • layout的格式定义为%m%n,意思是每条日志都会跟随一个换行符。

  需要注意的是log4j支持UNIX风格的变量引用,比如${variableName}

Appenders

  log4j提供了多种的Appender对象,用于输出日志消息到不同的目的地,比如控制台,文件,系统事件日志等等。每个appender对象都有不同的配置属性,这些属性定义来对象的行为。

  • layout    appender使用这个layout对象转换日志信息的格式
  • target    目标可能是控制台、文件、也可能依赖于其他的appender
  • level    用于设定过滤日志的级别
  • threshhold    appender可以设置阈值,与日志的级别有关。日志会忽略掉所有低于该级别的日志
  • filter    过滤器对象能够分析日志信息,然后决定日志请求由某个appender处理还是丢掉

  可以通过下面的方式,给logger添加appender

log4j.logger.[logger-name]=level, appender1,appender..n

  当然如果在XML也可以通过下面的方式:

<logger name="com.apress.logging.log4j" additivity="false">

    <appender-ref ref="appender1"/>

    <appender-ref ref="appender2"/>

</logger>

如果想在程序中添加appender,则可以调用下面的方法:

public void addAppender(Appender appender);


像例子中展示的,它可以同时配置多个appender,每个日志都会独立的发送不到不同的目的地  这个addAppender()方法向logger对象中添加appender。


  上面只展示来FileAppender的用法,log4j还有下面的appender以供使用:

  • AppenderSkeleton
  • AysncAppender
  • ConsoleAppender
  • DailyRollingFileAppender
  • ExternallyRolledFileAppender
  • FileAppender
  • JDBCAppender
  • JMSAppender
  • LF5Appender
  • NTEventLogAppender
  • NullAppender
  • RollingFileAppender
  • SMTPAppender
  • SocketAppender
  • SocketHubAppender
  • SyslogAppender
  • TelnetAppender
  • WriterAppender

layout

  上面使用过PatternLayout,下面还有其他的选项:

  • DateLayout
  • HTMLLayout
  • PatternLayout
  • SimpleLayout
  • XMLLayout

  不同的appenders和layout用法,后续会慢慢更新。

四、如何在java中输出日志消息

我们已经创建来配置文件,本章详细的介绍下如何生成调试信息,并把他们转化成文本文件。

基本的例子

下面就是创建的一个基本的例子:

log4j.properties的内容为:


log = /usr/home/log4j
log4j.rootLogger = DEBUG, FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/log.out
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

看看它都做了什么工作:

  • root logger的级别是DEBUG,并且绑定了一个名字叫做FILE的appender。
  • appender FILE定义为org.apache.log4j.FileAppender,并且把内容写到log.out文件中。
  • layout格式定义为%m%n,意思是每条信息都会跟随一个换行符

在java程序中使用log4j

下面的java类中简单的进行了初始化、使用、log4j日志输出等工作:


import org.apache.log4j.Logger;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class log4jExample{
/* Get actual class name to be printed on */
static Logger log = Logger.getLogger(log4jExample.class.getName());
public static void main(String[] args)throws IOException,SQLException{
log.debug("Hello this is a debug message");
log.info("Hello this is an info message");
}
}

编译与执行

这里是编译与执行上面代码的步骤:保证你在执行前设置了PATH和CLASSPATH等变量

所有的类库文件都应该放在CLASSPATH里面,你的log4j.properties文件也应该放在PATH里面.然后按照下面的步骤:

  • 创建log4j.properties
  • 创建log4jExample.java并且编译它
  • 执行log4jExample二进制文件

你可以在/usr/home/log4j/log.out文件中,得到下面的信息:


Hello this is a debug message
Hello this is an info message

 

五、日志输出的方法

日志类提供了很多方法用于处理日志活动,它不允许我们自己实例化一个logger,但是提供给我们两种静态方法获得logger对象:

  • public static Logger getRootLogger();
  • public static Logger getLogger(String name);

第一种方法返回应用实例的根logger,它没有名字。

第二种方法可以通过名字获得日志对象logger,类的名字是你传递的class的名字,通常是一个class的类名或者包名。
static Logger log = Logger.getLogger(log4jExample.class.getName());

日志方法

我们一旦获得了日志实例,就可以通过它的几个方法输出消息。Logger类拥有下面几种打印日志的方法:

  • public void debug(Object message)
    使用Level.DEBUG级别输出信息
  • public void error(Object message)
    使用Level.ERROR级别输出信息
  • public void fatal(Object message)
    使用Level.FATAL级别输出信息
  • public void info(Object message)
    使用Level.INFO级别输出信息
  • public void warn(Object message)
    使用Level.WARN级别输出信息
  • public void trace(Object message)
    使用Level.TRACE级别输出信息

所有的级别都定义在org.apache.log4j.Level中,上面提到的方法可以像下面一样调用:


import org.apache.log4j.Logger;
public class LogClass {
private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class);
public static void main(String[] args) {
log.trace("Trace Message!");
log.debug("Debug Message!");
log.info("Info Message!");
log.warn("Warn Message!");
log.error("Error Message!");
log.fatal("Fatal Message!");
}
}

当执行上面的代码,就会得到:


Debug Message!
Info Message!
Warn Message!
Error Message!
Fatal Message!

在下一章将会着重讲解各种级别。

六、日志的级别

org.apache.log4j.Level 类提供了下面几种日志级别,你也可以通过继承这些类,自定义级别

  • ALL 所有日志级别都包括
  • DEBUG 指定信息事件的粒度是DEBUG,在调试应用的时候会有帮助
  • ERROR 指定错误事件,并且这些事件还会保证应用继续运行
  • FATAL 指定严重的错误事件,该事件会导致应用暂停
  • INFO 指定信息消息,强调应用粗粒度的运行情况
  • OFF 最高等级,相当与关闭了日志
  • TRACE 指定比DEBUG更细粒度的调试日志
  • WARN 输出具有潜在风险的信息

如何使用不同的级别

log4j中日志的级别是排好序的,一般的标准是
ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF
如果日志本身使用的是WARN输出,但是log4j设置的级别是FATAL,则不会输出;相反,如果设置的是DEBUG,则会输出。

下面这个例子,展示了如何过滤DEBUG和INFO消息。


import org.apache.log4j.*;
public class LogClass {
private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class);
public static void main(String[] args) {
log.setLevel(Level.WARN);
log.trace("Trace Message!");
log.debug("Debug Message!");
log.info("Info Message!");
log.warn("Warn Message!");
log.error("Error Message!");
log.fatal("Fatal Message!");
}
}

当编译后执行,会得到如下的结果:


Warn Message!
Error Message!
Fatal Message!

在配置文件中设置级别

log4j支持在配置文件中设置日志的默认级别,这样就不用修改源代码,就可以改变日志的级别了。

下面就给出了一个配置文件的例子,与上面log.setLevel(Level.WARN)方法相同的工作:


log = /usr/home/log4j
log4j.rootLogger = WARN, FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/log.out
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

然后运行下面的代码:


import org.apache.log4j.*;
public class LogClass {
private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class);
public static void main(String[] args) {
log.trace("Trace Message!");
log.debug("Debug Message!");
log.info("Info Message!");
log.warn("Warn Message!");
log.error("Error Message!");
log.fatal("Fatal Message!");
}
}

运行上述的代码,就会得到:


Warn Message!
Error Message!
Fatal Message!

七、日志格式化

apache log4j提供各种layout对象,然后根据自己指定的layouts对象转化日志信息。通常来说都是应用量身定制layout对象转换信息格式。

所有的layout对象从Appender对象中接收一个LoggingEvent对象。然后通过LoggingEvent对象解析信息,再通过合适的ObjectRenderer获得相应的字符串。

Layout类型

最顶层的抽象类是org.apache.log4j.Layout,这是log4jAPI中layout的基类。

Layout类定义为一个抽象类,我们不能够直接使用;只能通过下面的实例使用:

  • DateLayout
  • HTMLLayout
  • PatternLayout
  • SimpleLayout
  • XMLLayout

Layout方法

这个类为所有的一般操作提供了基本的框架,以及两个抽象方法:
public abstract boolean ignoresThrowable()

它声明是否把java.lang.Throwable.object当作是日志输出的一部分。如果layout处理这个异常对象,那么就不会忽略这个消息;反之,就会忽略。

public abstract String format(LoggingEvent event)

个人自定义的layout转换格式

除了这些抽象方法,layout类也提供了一系列的接口:

public String getContentType()

它返回了layout的类型,基类返回的是text/plain作为默认的文本类型

public String getFooter()

获取日志信息的尾部

public String getHeader()

获取日志信息的头部

八、文件输出

使用org.apache.log4j.FileAppender可以把日志写到文件中:

FileAppender配置

  • immediateFlush 这个标志默认为true,是否每次有消息产生都自动flush到文件中
  • encoding 字符编码
  • threshold appender的阈值threshold
  • Filename 日志文件的名称
  • fileAppend 默认设置为true,所有的日志都输出到相同的文件
  • bufferedIO 是否启用缓冲区,默认是false
  • bufferSize 如果启用了缓冲区,设置缓冲区的大小。默认是8kb.

下面是log4j.properties中FileAppender的相关配置:


##### Define the root logger with appender file
log4j.rootLogger = DEBUG, FILE
##### Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
##### Set the name of the file
log4j.appender.FILE.File=${log}/log.out
##### Set the immediate flush to true (default)
log4j.appender.FILE.ImmediateFlush=true
##### Set the threshold to debug mode
log4j.appender.FILE.Threshold=debug
##### Set the append to false, overwrite
log4j.appender.FILE.Append=false
##### Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

如果是配置XML的配置文件,可以参考如下:

``

log4j:configuration

``

多文件输出——日志轮转

如果需要把日志文件写入到多个文件中,例如,按照文件的大小,到达一定的阈值后,就写入另一个文件。

那么你可以使用apache.log4j.RollingFileAppender类,它继承了FileAppender,并能设置一些属性达到上面的需求。

添加的属性如下:

  • maxFileSize 这是日志轮转的关键属性,设置了日志的大小阈值,默认是10MB
  • maxBackupIndex 这个属性设置了文件会被备份的数目,默认是1

log4j.properties的配置如下


##### Define the root logger with appender file
log4j.rootLogger = DEBUG, FILE
##### Define the file appender
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
##### Set the name of the file
log4j.appender.FILE.File=${log}/log.out
##### Set the immediate flush to true (default)
log4j.appender.FILE.ImmediateFlush=true
##### Set the threshold to debug mode
log4j.appender.FILE.Threshold=debug
##### Set the append to false, should not overwrite
log4j.appender.FILE.Append=true
##### Set the maximum file size before rollover
log4j.appender.FILE.MaxFileSize=5KB
##### Set the the backup index
log4j.appender.FILE.MaxBackupIndex=2
##### Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

如果你希望配置xml文件,那么只要把RollingFileAppender以及它的两个属性添加进去就可以了。

上面的文件中,最大的文件大小为5kb,当超过这个大小后,就会创建新的文件;然后这个文件被命名为log.1;同理,如果有log.2就会重命名为log.3。如果索引数目最多设置为5,并且已经存在了log.5,那么log.5会被直接删除。

多问键输出——日期轮转

如果想要每天更新一下日志文件,那么可以使用org.apache.log4j.DailyRollingFileAppender。

它增加的属性如下:

  • DatePattern 这个属性声明了命名规则,默认是每一天的半夜24点更新一次

这个属性可以按照下面的方式书写:

  • '.'yyyy-MM 在每个月刚开始的时候更新一次
  • '.'yyyy-MM-dd 每天半夜24点的时候更新
  • '.'yyyy-MM-dd-a 每天12点和24点更新
  • '.'yyyy-MM-dd-HH 每个小时更新一次
  • '.'yyyy-MM-dd-HH-mm 每分钟更新一次
  • '.'yyyy-ww 每周的第一天更新

log4j.properties的配置如下


##### Define the root logger with appender file
log4j.rootLogger = DEBUG, FILE
##### Define the file appender
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
##### Set the name of the file
log4j.appender.FILE.File=${log}/log.out
##### Set the immediate flush to true (default)
log4j.appender.FILE.ImmediateFlush=true
##### Set the threshold to debug mode
log4j.appender.FILE.Threshold=debug
##### Set the append to false, should not overwrite
log4j.appender.FILE.Append=true
##### Set the DatePattern
log4j.appender.FILE.DatePattern='.' yyyy-MM-dd-a
##### Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

同样,如果在xml中配置,添加相关的属性即可。

九、输出到数据库

log4j提供了org.apache.log4j.JDBCAppender对象,可以把日志输出到特定的数据库。

常用的属性:

  • bufferSize 设置buffer的大小,默认是1
  • driver 设置数据库的驱动字符串,比如sun.jdbc.odbc.OdbcDriver
  • layout 设置使用的layout,默认是org.apache.log4j.PatternLayout
  • password 设置数据的密码
  • sql 设置每次日志产生的时候执行的sql语句,可以是INSERT,UPDATE,DELETE
  • URL 设置JDBC URL
  • user 设置数据库的用户名

在输出日志之前,还应该创建数据库中的表,执行下面的SQL语句


CREATE TABLE LOGS
(USER_ID VARCHAR(20) NOT NULL,
DATED
DATE NOT NULL,
LOGGER VARCHAR(50) NOT NULL,
LEVEL
VARCHAR(10) NOT NULL,
MESSAGE VARCHAR(1000) NOT NULL
);

log4j.properties文件配置

下面是JDBCAppender的相关配置:


log4j.rootLogger = DEBUG, DB
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

对于MySQL数据库来说,当创建了LOGS表后你还需要使用dbname,user_name,password。

如果在xml中配置可以参考如下:
``

log4j:configuration

``

代码样例

下面这个例子,在java代码中使用了Log4j输出:


import org.apache.log4j.Logger;
import java.sql.*;
import java.io.*;
import java.util.*;
public class log4jExample{
/* Get actual class name to be printed on */
static Logger log = Logger.getLogger(log4jExample.class.getName());
public static void main(String[] args)throws IOException,SQLException{
log.debug("Debug");
log.info("Info");
}
}

编译和执行

执行后就可以查询结果了:


mysql > select * from LOGS;
+---------+------------+--------------+-------+---------+
| USER_ID | DATED
| LOGGER
| LEVEL | MESSAGE |
+---------+------------+--------------+-------+---------+
|
| 2010-05-13 | log4jExample | DEBUG | Debug
|
|
| 2010-05-13 | log4jExample | INFO | Info
|
+---------+------------+--------------+-------+---------+
2 rows in set (0.00 sec)

 

 

 

 

 

 

 

(。・v・。)
喜欢这篇文章吗?欢迎分享到你的微博、QQ群,并关注我们的微博,谢谢支持。