log4j 1.x基础教程

前言

Log4j 1.x已经不再维护,1.x最新版本是Log4j  1.2,请尽快升级到Apache Log4j 2。不过目前依然有不少旧项目使用1.x版本。Log4j有三个主要组件:logger, appender和layout。这三类组件一起工作使得开发者可以按消息的类别和等级来输出消息,并且在运行时控制这些消息怎么格式化和在哪里输出这些信息。


logger

自从 Log4j 的1.2版本,Logger类已经取代了Category类,对那些熟悉Log4j 早期版本的人来说,Logger类可以被认为仅仅是Category类的别名。logger是被命名的实体,logger名是大小写敏感的,并且它们遵循如下层次规则:一个logger可以说是另一个logger的祖先,假如logger的名称加上圆点是后代logger的前缀,如果它们之间没有其他的祖先,则logger是后代logger的父logger。例如:名称为“com.foo”的logger是名称为“com.foo.bar”的父logger。相似的是,“java”是“java.util”的父logger,是“java.util.vector”的祖先。这个命名规则对大多数的开发人员来说应该是很熟悉的。
root logger处于层次的顶端,它总是存在的,并且无法通过名称获得。
Logger.getRootLogger获得root logger,其他的使用Logger.getLogger获得。logger可以被设置级别,可能的级别包括TRACE、DEBUG,、INFO、 WARN、 ERROR、FATAL,这些级别被定义在org.apache.log4j.Level类中。一些常用方法如下:
package org.apache.log4j;

  public class Logger {

    // Creation & retrieval methods:
    public static Logger getRootLogger();
    public static Logger getLogger(String name);

    // printing methods:
    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);

    // generic printing method:
    public void log(Level l, Object message);
}
假如一个logger没有指定级别,它将从它最近的祖先继承,如果祖先级别为空,则继续往上查询,直到第一个级别非空的logger。root logger必须指定一个级别。
记录请求是通过调用一个日志实例的打印方法,如trace、debug等方法来实现的。假如记录请求的等级大于等于logger的级别,那么这个记录请求就是有效的,反之无效。
这个规则是Log4j的核心,级别排序DEBUG < INFO < WARN < ERROR < FATAL.。

appender

基于logger的选择性的启用或禁用记录请求的能力仅仅是描述的一部分,Log4j允许记录请求输出到多个目标,一个输出目标就被称为appender。目前,appender包括console, files, GUI components, remote socket servers, JMS, NT Event Loggers, remote UNIX Syslog daemons,它也可以异步地记录日志。一个logger可以添加多个appender。appender也是可以被继承的,logger的additivity属性就是用于设置是否输出到父appender,默认是true。例如:有一个logger叫做p,p是c的父logger,如果p的additivity是false,那么c的日志就会输出到c的所有appender和p的所有appender,不会再输出到p的父logger的appender上。
threshold属性和logger的level差不多,它的作用是在level的基础上再次过滤,可以达到每个appender输出的日志级别不一样的效果,threshold大于等于level。

org.apache.log4j.ConsoleAppender

Threshold=DEBUG:指定日志消息的输出最低层次。
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。

org.apache.log4j.RollingFileAppender

Encoding:输出文件的编码。
Threshold=DEBUG:指定日志消息的输出最低层次。
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
File=mylog.txt:指定消息输出到mylog.txt文件,可以调用System.setProperty方法配置某个路径,在这里用${xxxx}引用系统变量。
Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。
MaxFileSize=100KB:后缀可以是KB,、MB 或者是 GB。 在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件。
MaxBackupIndex=2:指定可以产生的滚动文件的最大数。

org.apache.log4j.DailyRollingFileAppender

Encoding:输出文件的编码。
Threshold=DEBUG:指定日志消息的输出最低层次。
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
File=mylog.txt:指定消息输出到mylog.txt文件,可以调用System.setProperty方法配置某个路径,在这里用${xxxx}引用系统变量。
Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。
DatePattern:文件命名规则和更新时间。
'.'yyyy-MM 在每个月刚开始的时候更新一次
'.'yyyy-MM-dd 每天半夜24点的时候更新
'.'yyyy-MM-dd-a 每天12点和24点更新
'.'yyyy-MM-dd-HH 每个小时更新一次
'.'yyyy-MM-dd-HH-mm 每分钟更新一次
'.'yyyy-ww 每周的第一天更新

org.apache.log4j.AsyncAppender

AsyncAppender允许异步地记录日志,它可以附加几个appender,工作原理是搜集记录事件然后派送到附属于它的appender上,必须使用xml方式配置才可以。
BufferSize:搜集的事件数,默认128。
<appender name="ASYNC_FILE_LOG" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="256"/>
        <param name="LocationInfo" value="true"/>
        <appender-ref ref=appenderName/>
</appender>

layout

通常,用户不仅需要自定义输出目标,也需要自定义输出格式,这是通过给appender设置一个layout来达到目的。PatternLayout是Log4j标准发行包的一部分,允许我们通过conversion属性来定义格式,语法类似于C的printf。例如:设置为"%r [%t] %-5p %c - %m%n",那么会输出:176 [main] INFO  org.foo.Bar - Located nearest gas station。
(1)org.apache.log4j.HTMLLayout(以HTML表格形式布局)
(2)org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
(3)org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
(4)org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
HTMLLayout选项:
LocationInfo=true:输出java文件名称和行号,默认值是false。
Title=My Logging: 默认值是Log4J Log Messages。
PatternLayout选项:
ConversionPattern=%m%n:设定以怎样的格式显示消息。
%p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL。
%d:输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}。
%r:输出自应用程序启动到输出该log信息耗费的毫秒数。
%t:输出产生该日志事件的线程名。
%l:输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.java:10)。
%c:输出日志信息所属的类目,通常就是所在类的全名。
%M:输出产生日志信息的方法名。
%F:输出日志消息产生时所在的文件名称。
%L::输出代码中的行号。
%m::输出代码中指定的具体日志信息。
%n:输出一个回车换行符,Windows平台为"rn",Unix平台为"n"。
%x:输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
%%:输出一个"%"字符。
另外,还可以在%与格式字符之间加上修饰符来控制其最小长度、最大长度、和文本的对齐方式。如:
c:指定输出日志所属类的名称,最小的长度是20,如果日志所属类的名称长度小于20的话,默认的情况下右对齐。
2)%-20c:"-"号表示左对齐。
3)%.30c:指定输出日志所属类的名称,最大的长度是30,如果日志所属类的名称长度大于30的话,就会将左边多出的字符截掉,但小于30的话也不会补空格。

解析配置文件

调用BasicConfigurator.configure方法,创建了一个相当简单的Log4j设置。这个方法为root logger添加了ConsoleAppender,PatternLayout被设置为"%-4r [%t] %-5p %c %x - %m%n"。默认root logger级别是DEBUG。
调用PropertyConfigurator.configure方法,解析配置文件,配置文件可以是java的properties和xml文件。如果用spring,那么配置监听器org.springframework.web.util.Log4jConfigListener来解析配置文件,默认是classpath路径,。建议使用xml文件,可读性高。

Log4jConfigListener

1:动态的改变记录级别和策略,不需要重启Web应用。 
2:配置文件不需要写绝对路径。 
有几个属性需要注意:
webAppRootKey:默认是webapp.root,如果同一个jvm下有多个应用使用Log4jConfigListener,那么需要修改这个属性,让每个应用不一样,否则会导致后续应用启动失败。
log4jConfigLocation:配置文件路径,相对web根目录。
log4jRefreshInterval:单位毫秒,多长时间扫描配置文件,这样就不用重启web服务。
<context-param>
        <param-name>webAppRootKey </param-name>
        <param-value>some.web.root </param-value>
</context-param>
<context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>WEB-INF/log4j.properties</param-value>
</context-param>
<context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>60000</param-value>
</context-param>
<listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

示例

# 控制台
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 日志文件
log4j.appender.logFile=org.apache.log4j.FileAppender
log4j.appender.logFile.Threshold=DEBUG
log4j.appender.logFile.ImmediateFlush=true
log4j.appender.logFile.Append=true
log4j.appender.logFile.File=D:/logs/log.log4j
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 滚动文件
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.Threshold=DEBUG
log4j.appender.rollingFile.ImmediateFlush=true
log4j.appender.rollingFile.Append=true
log4j.appender.rollingFile.File=D:/logs/log.log4j
log4j.appender.rollingFile.MaxFileSize=200KB
log4j.appender.rollingFile.MaxBackupIndex=50
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 定期滚动日志文件
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.Threshold=DEBUG
log4j.appender.dailyFile.ImmediateFlush=true
log4j.appender.dailyFile.Append=true
log4j.appender.dailyFile.File=D:/logs/log.log4j
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyFile.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 应用于socket
log4j.appender.socket=org.apache.log4j.RollingFileAppender
log4j.appender.socket.RemoteHost=localhost
log4j.appender.socket.Port=5001
log4j.appender.socket.LocationInfo=true
# Set up for Log Factor 5
log4j.appender.socket.layout=org.apache.log4j.PatternLayout
log4j.appender.socket.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000

# 发送日志到指定邮件
log4j.appender.mail=org.apache.log4j.net.SMTPAppender
log4j.appender.mail.Threshold=FATAL
log4j.appender.mail.BufferSize=10
log4j.appender.mail.From = [email protected]
log4j.appender.mail.SMTPHost=mail.com
log4j.appender.mail.Subject=Log4J Message
log4j.appender.mail.To= [email protected]
log4j.appender.mail.layout=org.apache.log4j.PatternLayout
log4j.appender.mail.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

# 应用于数据库
log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.database.URL=jdbc:mysql://localhost:3306/test
log4j.appender.database.driver=com.mysql.jdbc.Driver
log4j.appender.database.user=root
log4j.appender.database.password=
log4j.appender.database.sql=INSERT INTO LOG4J (Message) VALUES('=[%-5p] %d(%r) --> [%t] %l: %m %x %n')
log4j.appender.database.layout=org.apache.log4j.PatternLayout
log4j.appender.database.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n

配置根Logger
log4j.rootLogger = [ level ] , appenderName1, appenderName2, …

配置Logger
log4j.logger.loggerName= [ level ] , appenderName1, appenderName2, …

配置appender
log4j.appender.appenderName = 完全限定类名

配置layout
log4j.appender.appenderName.layout = 完全限定类名
log4j.appender.appenderName.layout.ConversionPattern=格式

xml格式示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM
        "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<!--instruct log4j to also output internal debugging messages on the console-->
<log4j:configuration>
    <appender name="FILE_LOG" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="Encoding" value="UTF-8"/>
        <param name="Threshold" value="DEBUG"/>
        <param name="File" value=""/>
        <param name="Append" value="true"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d [%x] %t [%-5p] (%F,%L) - %m%n"/>
        </layout>
    </appender>

    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
        <param name="Threshold" value="DEBUG"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d [%x] %t [%-5p](%c %F,%L) - %m%n"/>
        </layout>
    </appender>

    <appender name="ASYNC_FILE_LOG" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="256"/>
        <param name="LocationInfo" value="true"/>
        <appender-ref ref="FILE_LOG"/>
    </appender>

    <appender name="ASYNC_CONSOLE" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="64"/>
        <param name="LocationInfo" value="true"/>
        <appender-ref ref="CONSOLE"/>
    </appender>

    <root>
        <level value="INFO"/>
        <appender-ref ref="ASYNC_CONSOLE"/>
        <appender-ref ref="ASYNC_FILE_LOG"/>
    </root>
</log4j:configuration> 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章