Log4j 官方文档翻译
一、基本介绍
简介
log4j是使用java语言编写的可靠的、快速的、灵活的日志框架,它是基于Apache的license。
log4j支持c,c++,c#,perl,python,ruby等语言。在运行时通过额外的配置文件配置,提供不同的日志级别以及多种日志输出种类,比如数据库,文件,控制台,syslog等等。
log4j有三个主要部分:
- loggers 负责捕获日志信息
- appenders 负责输出信息到不同的目的地
- 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 Framework
activation.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框架中有两种对象:
- 核心对象:框架的支撑对象,是框架必不可少的组成部分。
- 支撑对象:这些是框架可选的对象,用于提供额外重要的工作。
核心对象包括下面几种类型:
- logger对象,是最高的层,负责通过不同的风格转化日志信息。它提供给appender对象发布前的信息。(这里的层是指所处的位置)
- layout对象,用于提供格式化日志信息的风格,在发布日志信息前,使其变得可读、可重用。
- appender对象,这个对象属于底层的对象,它负责发布信息到不同的目的地,比如数据库、文件、控制台、UNIXsyslog等等。
下面就是log4j的架构组成图:
支撑对象,他们在log4j框架中扮演了很关键的角色:
- level对象:级别对象定义来日志信息的粒度和优先级,有七种级别:OFF,DEBUG,INFO,ERROR,WARN,FATAL和ALL。
- 过滤器对象:用于分析日志信息并决定日志信息是否输出。每个appender对象可以有几个过滤器对象协同工作,当日志信息到达特定的appender时,所有的过滤器会功能帮助appender在其发布到目的地之前进行过滤操作。
- 对象渲染器:提供一段字符串用于识别发送日志的不同对象,这个对象也用于为layout对象准备常量信息。
- 日志管理器:用于管理日志框架,它负责从初始化配置中读取信息,这个配置可能是文件配置、也可能是类的配置。
三、配置
之前的章节介绍了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的阈值thresholdFilename
日志文件的名称fileAppend
默认设置为true,所有的日志都输出到相同的文件bufferedIO
是否启用缓冲区,默认是falsebufferSize
如果启用了缓冲区,设置缓冲区的大小。默认是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的配置文件,可以参考如下:
``
``
多文件输出——日志轮转
如果需要把日志文件写入到多个文件中,例如,按照文件的大小,到达一定的阈值后,就写入另一个文件。
那么你可以使用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的大小,默认是1driver
设置数据库的驱动字符串,比如sun.jdbc.odbc.OdbcDriverlayout
设置使用的layout,默认是org.apache.log4j.PatternLayoutpassword
设置数据的密码sql
设置每次日志产生的时候执行的sql语句,可以是INSERT,UPDATE,DELETEURL
设置JDBC URLuser
设置数据库的用户名
在输出日志之前,还应该创建数据库中的表,执行下面的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中配置可以参考如下:
``
``
代码样例
下面这个例子,在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・。)