1.1 Log4j简介
log4j是一个Java日志包, 每一个大型的应用程序都需要有日志或者跟踪API,据此,1996年 E. U. SEMPER 项目开发了自己的日志API,这就是log4j API的前身。后来经过多次的修改、润色以至重写,这个API发展成了现在Apache Public License下的完善的日志API。
Log4j是Apache的一个开放源代码项目(Open source project),通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
此外,通过Log4j其他语言接口,您可以在C、C++、.Net、PL/SQL程序中使用Log4j,其语法和用法与在Java程序中一样,使得多语言分布式系统得到一个统一一致的日志组件模块。而且,通过使用各种第三方扩展,您可以很方便地将Log4j集成到J2EE、JINI甚至是SNMP应用中。
目前最新的版本是Log4j 1.2.8。
1.2 Log4j的基本组成
Log4J有三个主要部件组成,它们是记录器(Loggers)、输出源(Appenders)和布局(Logouts)。
1.2.1 Loggers
记录器(loggers)按照布局中指定的格式把日志信息写入一个或多个输出源。
1.2.2 Appenders
输出源(Appenders)可以是控制台、文本文件、XML文件或Socket,甚至还可以把信息写入到Windows事件日志或通过电子邮件发送,这都需要相应的类来处理,这些相关的类是:
ConsoleAppender(控制台)、
FileAppender(文件)、
SocketAppende(发送loggingevent 到一个远端的服务器)
DailyRollingFileAppender(每天产生一个日志文件)
RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
WriterAppender(将日志信息以流格式发送到任意指定的地方)
NtEventLogAppender
JMSAppender 等等。
具体见http://jakarta.apache.org/log4j/docs/api/index.html
1.2.3 Layout
布局(layout):所有集成Layout类的类定义了日志信息的布局,所谓布局就是日志信息的格式,log4j预定义的布局类有
DateLayout (以日期表格形式布局)
HTMLLayout (以HTML表格形式布局)
PatternLayout(可以灵活地指定布局模式)
SimpleLayout(包含日志信息的级别和信息字符串)
XMLLayout (以XML表格形式布局)
TCCLayout(包含日志产生的时间、线程、类别等等信息)
你也可以定义自己的布局类。Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数见表如下所示:
%m | 输出代码中指定的消息 |
%p | 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL |
%r | 输出自应用启动到输出该log信息耗费的毫秒数 |
%c | 输出所属的类目,通常就是所在类的全名 |
%t | 输出产生该日志事件的线程名 |
%n | 输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n” |
%d | 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921 |
%l | 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例: |
1.3 Log4j的级别
Log4J中的一个核心概念是日志级别是有序的。Log4J内置了5种日志级别为: DEBUG < INFO < WARN < ERROR < FATAL,右边的级别比左边的高。
1.3.1 fatal
fatal() 输出ERROR级别的调试信息
1.3.2 error
error() 输出ERROR级别的调试信息
1.3.3 warn
warn() 输出WARN级别的调试信息
1.3.4 info
info() 输出INFO 级别的调试信息
1.3.5 debug
debug() 输出INFO 级别的调试信息
1.4 Log4j优点
绝大多数的大型开发项目都有它们自己专门用于记录程序日志和对程序跟踪调试的API。许多经验证明,调试信息的管理在软件开发过程中扮演了十分重要的角色。日志管理通常提供了以下的几点好处:首先,它能在程序运行过程中精确的提供运行时的上下文(context)方便开发人员找到 BUG,一旦在程序中加入了Log 输出的代码,程序运行过程中就能自动的生成并输出logging信息。其次,log信息可以输出到不同的地方(控制台,文件,日志服务器等等)以备时候研究。最后,除了在开发过程中发挥它的作用外,一个功能足够强大的日志记录开发包能当作一个审计工具(audit tool)使用。
Log4j 具体优点如下:
(1)、它提供关于运行程序的准确的环境。
(2)、一旦代码被插入,不需要人工干预就可以产生调试信息。
(3)、日志输出可以被有计划的保存在永久媒体中以便日后研究。
另外,除了在开发周期中,一个充分详尽的日志包可以被用来作为以后的统计工具。
1.5 Log4j缺点
因为日志信息时嵌入到java元代码中,所以运行的时候,对运行效率有一定的影响。加入的日志代码必然要占用资源,而日志多有io操作,速度可能会较慢。它影响了程序运行的速度,增加了代码的开销,增加了许多无谓的输出。
2 Log4j 原理分析
2.1 Log4j快速入门
先看一段代码,看看Log4J是多么易于上手,代码如下:
package org.javaresearch.log4j;
import org.apache.log4j.*;
public class TestLog4J {
static Logger log = Logger.getLogger(TestLog4J.class.getName());
public static void main(String args[]) {
BasicConfigurator.configure();//Log4J提供的一个基本配置类BasicConfigurator对Log4J进行初始化
// logging的各种方法
log.debug("Start of main()");
log.info("Just testing a log message with priority set to INFO");
log.warn("Just testing a log message with priority set to WARN");
log.error("Just testing a log message with priority set to ERROR");
log.fatal("Just testing a log message with priority set to FATAL");
// 另一种不方便的格式
log.log(Priority.DEBUG, "Testing a log message use a alternate form");
log.debug("End of main().");
}
}
把这段代码保存在一个目录下,编译运行(注意要把log4j-1.2.7.jar包含入类路径中),程序输出如下:
0 [main] DEBUG TestLog4J - Start of main()
10 [main] INFO TestLog4J - Just testing a log message with priority set to INFO
20 [main] WARN TestLog4J - Just testing a log message with priority set to WARN
30 [main] ERROR TestLog4J - Just testing a log message with priority set to ERROR
30 [main] FATAL TestLog4J - Just testing a log message with priority set to FATAL
40 [main] DEBUG TestLog4J - Testing a log message use a alternate form
50 [main] DEBUG TestLog4J - End of main().
首先解释一下上面输出结果的意义。第一个数字是指程序开始运行到运行该日志语句所经历的毫秒数(用来做一点运行效率分析也不错);“[main]”是日志事件发生的线程;随后的“DEBUG”、“INFO”等信息是相应日志信息的优先级别;“TestLog4”是当前Logger的实例名;最后是日志信息。
在这段程序中,使用了Log4J提供的一个基本配置类BasicConfigurator对Log4J进行初始化。但在实际使用时通常不这么做,因为这多少有点“硬”编码。今后如果要修改Log4J的配置,就需要修改、重新编译代码,这通常不是大家所希望的。通常,我们都提供一个名为log4j.properties的文件,在第一次调用到Log4J时,Log4J会在类路径中定位这个文件,并读入这个文件完成的配置。这个配置文件告诉Log4J以什么样的格式、把什么样的信息、输出到什么地方。我们来看一个简单的log4j.properties配置文件的示例,代码如下:
log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern= "%-4r [%t] %-5p %c %x - %m%n
把上面的内容存储为log4j.properties,并放到和TestLog4J.class同一目录下(当然也可以放到其它任何目录,只要该目录被包含到类路径中即可)。具体这些配置文件中每行的意义,在以后章节会有详细的说明,现在可以先跳过。现在你可以注释掉上面程序中的“BasicConfigurator. configure();”语句,然后使用log4j.properties属性文件完成Log4J的配置,重新编译、运行,就得到和上面一样的结果。
这样做有什么好处呢?现在就初步领略一些Log4J的灵活、强大功能。比如系统要上线了,希望输出一些警告和错误信息,这时仅需要修改log4j.properties文件中的“log4j.rootCategory=DEBUG, A1”即可,然后设置日志输出的最低级别是WARN,设置为“log4j.root Category=WARN, A1”。此时不需要修改任何代码,重新运行系统,输出结果就变成了:
20 [main] WARN TestLog4J - Just testing a log message with priority set to WARN
30 [main] ERROR TestLog4J - Just testing a log message with priority set to ERROR
30 [main] FATAL TestLog4J - Just testing a log message with priority set to FATAL
2.2 Log4j原理分析
Log4J有三个主要部件,它们是记录器(Loggers)、输出源(Appenders)和布局(Logouts)。记录器按照布局中指定的格式把日志信息写入一个或多个输出源。输出源可以是控制台、文本文件、XML文件或Socket,甚至还可以把信息写入到Windows事件日志或通过电子邮件发送,这都需要相应的类来处理,这些相关的类是ConsoleAppender、FileAppender、SocketAppender、NtEventLogAppender和JMSAppender。
2.2.1 记录器(logger)
首先让我们看Logger类,代码如下:
package org.apache.log4j;
public class Logger {
//创建和恢复方法
public static Logger getRootLogger();
public static Logger getLogger(String name);
public static Logger getLogger(Class clazz);
// 打印方法
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);
// 常用打印方法
public void log(Level l, Object message);
}
从这段代码中可以看出Logger的基本使用。首先需要获取一个Logger对象,获取Logger对象的语句为:
Logger logger = Logger.getLogger(JavaLoggingExample.class.getName());
有了这个Logger对象,就可以在需要的地方方便地输出日志信息。对于这些信息是否输出、输出的格式等,都可以通过配置文件方便地配置,而不需要修改代码,这就是Log4J带来的方便之处。
2.2.2 记录器的层次结构
使用Log4J的Logger.getLogger()方法时会得到一个Logger的实例。如果一个应用中包含了上千个类,那么也几乎需要上千个Logger实例。如何对这上千个Logger实例进行方便地配置,就是一个很重要的问题。Log4J采用了一种树状的继承层次巧妙地解决了这个问题。在Log4J中Logger是具有层次关系的。它有一个共同的根,位于最上层,其它Logger遵循类似包的层次,比如:
static Logger root = Logger.getRootLogger();
static Logger log1 = Logger.getLogger("org");
static Logger log2 = Logger.getLogger("org.javaresearch");
static Logger log3 = Logger.getLogger("org.javaresearch.log4j.TestLog4J");
上面代码中,log1是log2的父亲,是log3的祖先,而root是所有log1、log2、log3的祖先,它们都从root中继承。所以,一般情况下,仅需要配置好rootLogger,其它子记录器都会从中继承rootLogger的配置。如果修改了rootLogger的配置,其它所有的子记录器也会继承这种变化。这样就大大地方便了配置。现在回头看看在“快速入门”中的配置文件,我们仅配置了rootLogger,就可以控制所有的Logger的行为。
2.2.3 级别(Level)
Log4J中的一个核心概念是日志级别是有序的。Log4J内置了5种日志级别为:
DEBUG < INFO < WARN < ERROR < FATAL
右边的级别比左边的高。每一个Logger实例都有一个日志级别,上面的5种输出方法就是对应于5种不同级别的日志请求。比如,如果c是一个Logger实例,c.info("some information")就是一个INFO级别的日志请求。一个日志请求会不会输出,取决于该Logger实例的日志级别和该日志请求级别的比较。规则如下:
假如在一个级别为p的Logger实例中发生一个级别为q的日志请求,则当q >= p时请求才会启用。
我们先来看实例2代码如下:
// 得到一个logger 实例 "com.foo"
Logger logger = Logger.getLogger("com.foo")
// 现在设置logger的级别,但正常情况是不需要刻意设置lgger级别的,因为它已经在配置文件中完成了
logger.setLevel(Level.INFO);
Logger barlogger = Logger.getLogger("com.foo.Bar");
//因为 WARN >= INFO,这个请求是可以实现的
logger.warn("Low fuel level.");
// 因为DEBUG < INFO,所以这个请求是无法实现的
logger.debug("Starting search for nearest gas station.");
// logger实例"com.foo.Bar"将从"com.foo"继承级别,这样,因为INFO >=
INFO,所以可以实现下面的请求
barlogger.info("Located nearest gas station.");
//因为DEBUG < INFO,这个请求是不能实现的
barlogger.debug("Exiting gas station search");
2.3 log4j配置
现在来看log4j.properties配置文件的意义。第一行指定了根Logger的级别是DEBUG,并将此指定输出到A1。A1就是第二行定义的org.apache.log4j.ConsoleAppender,此行表示将A1输出到控制台。第三行规定了输出到A1的格式为org.apache.log4j.PatternLayout。第四行规定了输出到A1格式的转换模式为org.javaresearch.log4j.TestLog4J。
多成熟的服务器类的软件日志信息会输出到控制台,同时输出到日志文件备查。使用Log4J可以在不改变任何代码的情况下,仅通过修改配置文件就可以轻松地完成这项功能。相关配置文件如下:
#### Use two appenders, one to log to console, another to log to a file
log4j.rootCategory=debug, stdout, R
# Print only messages of priority WARN or higher for your category
log4j.category.your.category.name=WARN
#### First appender writes to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
#### Second appender writes to a file
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
# Control the maximum log file size
log4j.appender.R.MaxFileSize=100KB
# Archive log files (one backup file here)
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
这个配置文件指定了两个输出源stdout和R。前者把日志信息输出到控制台,后者是一个轮转日志文件。最大的文件是100KB,当一个日志文件达到最大尺寸时,Log4J会自动把example.log重命名为example.log.1,然后重建一个新的example.log文件,依次轮转。
2.4 log4j在web上使用
在Web应用中,应该在哪儿对Log4J进行配置呢?首先要明确,Log4J必须在应用的其它代码执行前完成初始化。因为Servlet是在Web服务器启动时立即装入的,所以,在Web应用中一般使用一个专门的Servlet来完成Log4J的配置,并保证在web.xml的配置中,这个Servlet位于其它Servlet之前。下面是一个例子,代码如下
package org.javaresearch.log4j;
import java.io.*;
import javax.servlet.*;
import org.apache.log4j.*;
public class Log4JInit extends HttpServlet {
public void init() throws ServletException {
String prefix = getServletContext().getRealPath("/");
String file = getServletConfig().getInitParameter("log4j-config-file");
// 从Servlet参数读取log4j的配置文件
if (file != null) {
PropertyConfigurator.configure(prefix + file);
}
}
public void doGet(HttpServletRequest request,HttpServletResponse response)throws
IOException, ServletException {}
public void doPost(HttpServletRequest request,HttpServletResponse response)throws
IOException, ServletException {}
}
web.xml配置文件如下:
servlet>
<servlet-name>log4jinit</servlet-name>
<servlet-class>org.javaresearch. log4j.Log4JInit</servlet-class>
<init-param>
<param-name> log4j-config-file </param-name>
<param-value>/properties/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
注意:上面的load-on-startup应设为1,以便在Web容器启动时即装入该Servlet。log4j.properties文件放在根的properties子目录中,也可以把它放在其它目录中。应该把.properties文件集中存放,这样方便管理。
3 log4j高级应用
3.1 性能
在记录一些日志信息时,会一定程度地影响系统的运行效率,这时日志工具是否高效就是一个关键。Log4J的首要设计目标就是高效,一些关键组件都重写过很多次以不断提高性能。根据Log4J项目小组的报告,在AMD Duron 800MHz + JDK1.3.1的环境下,Log4J判断一条日志语句是否需要输出仅需要5纳秒。实际的日志语句执行的也非常快速,从使用SimpleLayout的21微秒(几乎与System.out.println一样快),到使用TTCCLayout的37微秒不等。
3.2 嵌套诊断环境(NDC)
在多用户并发的环境下,通常是由不同的线程分别处理不同的客户端请求。此时要在日志信息中区分出不同的客户端,你可以为每一个线程生成一个Logger,从而从一堆日志信息中区分出哪些信息是属于哪个线程的,但这种方式并不高效。Log4J巧妙地使用了Neil Harrison提出的“NDC(嵌套诊断环境)”机制来解决这个问题。Log4J为同一类别的线程生成一个Logger,多个线程共享使用,而它仅在日志信息中添加能够区分不同线程的信息。NDC是什么?举例来说,如果一个Servlet接到并发请求时,为每一个客户端创建一个新的线程,然后分配一个用于保存该请求上下文的NDC堆栈。该上下文可能是发出请求的主机名、IP地址或其它任何可以用于标识该请求的信息。这样,由于不同的客户端处理线程具有不同的NDC堆栈,即使这个Servlet同时生成多个线程处理不同的请求,这些日志信息仍然可以区分出来,就好像Log4J为每一个线程都单独生成了一个Logger实例一样。在Log4J中是通过org.apache.log4j.NDC实现这种机制的。使用NDC的方法也很简单,步骤如下:
1. 在进入一个环境时调用NDC.push(String),然后创建一个NDC;
2. 所做的日志操作输出中包括了NDC的信息;
3. 离开该环境时调用NDC.pop方法;
4. 当从一个线程中退出时调用NDC.remove方法,以便释放资源。
下面是一个模拟记录来自不同客户端请求事件的例子,代码如下:
import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
public class TestNDC {
static Logger log = Logger.getLogger(TestNDC.class.getName());
public static void main(String[] args) {
log.info("Make sure %x is in your layout pattern!");
// 从客户端获得IP地址的例子
String[] ips = {"192.168.0.10","192.168.0.27"};
for (int i = 0; i<ips.length ; i++) // 模拟一个运行方法
{
// 将IP放进 NDC中
NDC.push(ips[i]);
log.info("A NEW client connected, who's ip should appear in this log message.");
NDC.pop();
}
NDC.remove();
log.info("Finished.");
}
}
注意配置文件中的布局格式中一定要加上%x。系统输出如下:
INFO - Make sure %x is in your layout pattern!
INFO 192.168.0.10 - A NEW client connected, who's ip should appear in this log
message.
INFO 192.168.0.27 - A NEW client connected, who's ip should appear in this log
message.
INFO - Finished.
3.3 Log4j与JDK logging API 的比较
JDK 1.4.0开始,引入了java.util.logging包。虽然Log4J小组曾竭力游说JCP(Java Community Process)采用Log4J作为JDK 1.4的“标准”日志API,虽然最终因Sun的日志API规范的负责人Graham Hamilton的一句“Merlin的开发已经到了最后阶段,这时不允许再对主要API做出改变”而没有被采纳,但Log4J还是对新的日志API产生了重要影响。那么,我们到底应该采用Log4J还是java.util.logging包呢?下面仅对两者做一简单的比较。
1. Log4J更加成熟,从1999年10月开始至今已经有3年的时间,并且已经在许多项目中有着成熟的应用。而JDK中的logging包是在1.4之后才引入的,并且不能运行于JDK 1.3之前的版本。Log4J则可以良好地运行于JDK 1.1之后的所有版本。
2. Log4J已经被移植到多种环境下,包括log4c(C)、log4cpp(C++)、log4perl(Perl)、log4net(.net)等。在这些环境下,可以感受到几乎一致的配置和使用方式。这是JDK中的logging API所不能比拟的。
3. Log4J还具有更加强力的格式化系统,可以使记录输出时实现简单的模式。但是,它不会增加类而导致格式化工具的扩展。众多的附加程序和处理器使得Log4J数据包成为一个绝佳的选择,所有你所需要的都可能加以实现。
4. Log4J在性能上做了最大的优化。
Logging API对于简单的使用是足够的,但它缺少了许多Log4J所具有的功能。所以,如果你需要一个强力的logging机制,就应坚持使用Log4J;而如果只是需要一些简单的控制或文件记录,那么可以使用已经内建在JDK之中的logging API。
虽然Log4J和JDK logging API是一种竞争关系,但在logging API还在JCP中讨论(JSR47)时,两者之间就已经开始相互影响了。
4 Log4j具体应用
4.1 配置log4j-1.2.8.jar
1、 http://apache.linuxforum.net/dist/jakarta/log4j/ 下载jakarta-log4j-1.2.8.zip 到服务器上,解压,将log4j-1.2.8.jar文件放到Apache Tomcat 4.0/lib目录下(在安装Tomcat 的时候,自己可以随便改变Apache Tomcat 4.0的名字)。
2、 启动jbuilder 8,点击ProjectàProject perproties,选择Required librarys,点击Add,将log4j-1.2.8.jar增加在Required librarys里面(具体配置自己设置)。1.2.8.jar放在classpath里面。
4.2 初始化log4j
Log4J必须在应用的其它代码执行前完成初始化。具体操作如下:
在工程下面,新建Log4Jinit.java,具体源代码如下:(代码不需要修改即可以使用)
import java.io.*;
import javax.servlet.*;
import org.apache.log4j.*;
import javax.servlet.http.*;
import org.apache.log4j.jdbc.JDBCAppender;
public class Log4JInit extends HttpServlet {
public void init() throws ServletException {
String prefix = getServletContext().getRealPath("/");
String file = getServletConfig().getInitParameter("log4j-config-file");
// 从Servlet参数读取log4j的配置文件
if (file != null) {
PropertyConfigurator.configure(prefix + file);
}
}
public void doGet(HttpServletRequest request,HttpServletResponse response)throws
IOException, ServletException {}
public void doPost(HttpServletRequest request,HttpServletResponse response)throws
IOException, ServletException {}
}
4.3 配置web.xml
具体的文件放在路径:../webapps/项目名称/WEB-INF/web.xml下面。(代码不需要修改即可以使用)。
具体配置如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>log4jinit</servlet-name>
<servlet-class>com.iss.common.util.Log4JInit</servlet-class>
<init-param>
<param-name>log4j-config-file</param-name>
<param-value>WEB-INF/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Establish the default list of welcome files -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
<error-page>
<error-code>404</error-code>
<location>/FileNoFound.jsp</location>
</error-page>
</web-app>
备注:
上面的<load-on-startup>1</load-on-startup>应设为1,以便在Web容器启动时即装入该Servlet。
log4j.properties文件放在../webapps/项目名称/WEB-INF/log4j.properties下面。
4.4 配置log4j.properties
将Log4j.properties文件放在../webapps/项目名称/WEB-INF/log4j.properties下面.
(根据自己不同的需要设置相应的配置文件)
具体配置如下:
设置输出源到ConsoleAppender、DailyRollingFileAppender、RollingFileAppender中
log4j.rootLogger=debug,stdout
log4j.logger.info=info,R
log4j.logger.error=debug,s
#### First appender writes to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=(%F:%L) - %m%d%n
#### Second appender writes to the underlying file is rolled over at a user chosen frequency.
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
####设置日志文件路径,这里需要修改日志文件生成的路径
#### 如果写成log4j.appender.R.File= localhost_8080.log,localhost_8080.log就会生成到####C:/Documents and Settings/user/「开始」菜单/程序/Apache Tomcat 4.0下面,如果写成下####面这种格式,localhost_8080.log就会生成到下面的目录下面。
log4j.appender.R.File=C:/Program Files/Apache Tomcat 4.0/webapps/log/log_info.log
####生成的日志文件为log_info.log. 2003-06-19.txt格式
log4j.appender.R.DatePattern='.'yyyy-MM-dd'.txt'
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d [%F:%L] - %m /r/n
#### Third appender writes to a file
#### Second appender writes to a file
log4j.appender.s=org.apache.log4j.RollingFileAppender
####具体设置见上面的注释
log4j.appender.s.File= C:/Program Files/Apache Tomcat 4.0/webapps/log/log_error.log
# Control the maximum log file size
log4j.appender.s.MaxFileSize=100KB
# Archive log files (one backup file here)
log4j.appender.s.MaxBackupIndex=1
log4j.appender.s.layout=org.apache.log4j.PatternLayout
log4j.appender.s.layout.ConversionPattern=%p %t %c - %m%n
4.5 log4j在class中的使用
在java源文件中加入
import org.apache.log4j.*;
在类中定义:
static Logger infolog = Logger.getLogger("info");
static Logger errorlog = Logger.getLogger("error");
在需要输入日志信息的地方写上
infolog.info(“”);
errorlog.error(“”);即可以将不同级别的日志信息打印到不同的日志文件中。
如:infolog.info(“”)的日志信息就会生成到log_info.log. 2003-06-19.txt文件中。
errorlog.error(“”)的日志信息就会生成到/log_error.log文件中。