风行天下

JAVA太极
posts - 4, comments - 10, trackbacks - 0, articles - 55
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Apache commons简介

Posted on 2005-04-26 10:55 风太少 阅读(4883) 评论(0)  编辑  收藏

Apache Commons是一个非常有用的工具包,解决各种实际的通用问题,下面是一个简述表,详细信息访问http://jakarta.apache.org/commons/index.html

BeanUtils
Commons-BeanUtils 提供对 Java 反射和自省API的包装

Betwixt
Betwixt提供将 JavaBean 映射至 XML 文档,以及相反映射的服务.

Chain
Chain 提供实现组织复杂的处理流程的“责任链模式”.

CLI
CLI 提供针对命令行参数,选项,选项组,强制选项等的简单API.

Codec
Codec 包含一些通用的编码解码算法。包括一些语音编码器, Hex, Base64, 以及URL encoder.

Collections
Commons-Collections 提供一个类包来扩展和增加标准的 Java Collection框架

Configuration
Commons-Configuration 工具对各种各式的配置和参考文件提供读取帮助.

Daemon
一种 unix-daemon-like java 代码的替代机制

DBCP
Commons-DBCP 提供数据库连接池服务

DbUtils
DbUtils 是一个 JDBC helper 类库,完成数据库任务的简单的资源清除代码.

Digester
Commons-Digester 是一个 XML-Java对象的映射工具,用于解析 XML配置文件.

Discovery
Commons-Discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。.

EL
Commons-EL 提供在JSP2.0规范中定义的EL表达式的解释器.

FileUpload
FileUpload 使得在你可以在应用和Servlet中容易的加入强大和高性能的文件上传能力

HttpClient
Commons-HttpClient 提供了可以工作于HTTP协议客户端的一个框架.

IO
IO 是一个 I/O 工具集

Jelly
Jelly是一个基于 XML 的脚本和处理引擎。 Jelly 借鉴了 JSP 定指标签,Velocity, Cocoon和Xdoclet中的脚本引擎的许多优点。Jelly 可以用在命令行, Ant 或者 Servlet之中。

Jexl
Jexl是一个表达式语言,通过借鉴来自于Velocity的经验扩展了JSTL定义的表达式语言。.

JXPath
Commons-JXPath 提供了使用Xpath语法操纵符合Java类命名规范的 JavaBeans的工具。也支持 maps, DOM 和其他对象模型。.

Lang
Commons-Lang 提供了许多许多通用的工具类集,提供了一些java.lang中类的扩展功能

Latka
Commons-Latka 是一个HTTP 功能测试包,用于自动化的QA,验收和衰减测试.

Launcher
Launcher 组件是一个交叉平台的Java 应用载入器。 Commons-launcher 消除了需要批处理或者Shell脚本来载入Java 类。.原始的 Java 类来自于Jakarta Tomcat 4.0 项目

Logging
Commons-Logging 是一个各种 logging API实现的包裹类.

Math
Math 是一个轻量的,自包含的数学和统计组件,解决了许多非常通用但没有及时出现在Java标准语言中的实践问题.

Modeler
Commons-Modeler 提供了建模兼容JMX规范的 Mbean的机制.

Net
Net 是一个网络工具集,基于 NetComponents 代码,包括 FTP 客户端等等。

Pool
Commons-Pool 提供了通用对象池接口,一个用于创建模块化对象池的工具包,以及通常的对象池实现.

Primitives
Commons-Primitives提供了一个更小,更快和更易使用的对Java基本类型的支持。当前主要是针对基本类型的 collection。.

Validator
The commons-validator提供了一个简单的,可扩展的框架来在一个XML文件中定义校验器 (校验方法)和校验规则。支持校验规则的和错误消息的国际化。

10:20 | 评论 (0)

2005年3月17日

JAR 文件就是 Java Archive File,是 Java 的文档格式。JAR 文件非常类似 ZIP 文件——准确的说,它就是 ZIP 文件,所以叫它文件包。JAR 文件与 ZIP 文件唯一的区别就是在 JAR 文件的内容中,包含了一个 META-INF/MANIFEST.MF 文件,这个文件是在生成 JAR 文件的时候自动创建的。

创建可运行的 JAR 文件包 
制作一个可执行的 JAR 文件包来发布你的程序是 JAR 文件包最典型的用法。 创建可执行的 JAR 文件包,需要使用带 cvfm 参数的 jar 命令,以 Example 目录为例,命令如下: 

jar cvfm Example.jar manifest.mf Example 

这里 Example.jar 和 manifest.mf 两个文件,分别是对应的参数 f 和 m,其重点在 manifest.mf。因为要创建可执行的 JAR 文件包,光靠指定一个 manifest.mf 文件是不够的,因为 MANIFEST 是 JAR 文件包的特征,可执行的 JAR 文件包和不可执行的 JAR 文件包都包含 MANIFEST。关键在于可执行 JAR 文件包的 MANIFEST,其内容包含了 Main-Class 一项。这在 MANIFEST 中书写格式如下: 
Main-Class: 可执行主类全名(包含包名) 

例如,假设 HelloWorld.class 是属于 Examples包的,而且是可执行的类 (定义了 public static void main(String[]) 方法),那么这个 manifest.mf 可以编辑如下: 
Main-Class: Example.HelloWorld <回车> 

这个 manifest.mf 可以放在任何位置,也可以是其它的文件名,只需要有 Main-Class: test.Test 一行,且该行以一个回车符结束即可。使用 jar 命令创建 JAR 文件包之后,这个 Example.jar 就是执行的 JAR 文件包。运行时只需要使用 java -jar test.jar 命令即可。 
需要注意的是,创建的 JAR 文件包中需要包含完整的、与 Java 程序的包结构对应的目录结构,而 Main-Class 指定的类,也必须是完整的、包含包路径的类名,如上例的 Example.HelloWorld。 
  

15:43 | 评论 (0)

2005年3月11日

草稿中。。

13:50 | 评论 (0)

在现实世界中的系统经常不得不同时处理多个客户端请求。在这样的一个典型的多线程的系统中,不同的线程将处理不同的客户端。一个常见的区分每个客户端所输出的Logging的方法是为每个客户端实例化一个新的独立的Logger。这导致Logger的大量产生,管理的成本也超过了logging本身。
 
嵌套诊断环境NDC 
在多用户并发的环境下,通常是由不同的线程分别处理不同的客户端请求。此时要在日志信息中区分出不同的客户端,区分两个客户的日志输出的常用方法是单独为每个客户端实例化新类别。但是,该方法会增加类别数量,并增加日志记录的管理开销。

Log4J巧妙地使用了Neil Harrison提出的“NDC(嵌套诊断环境)”机制来解决这个问题。Neil Harrison(请参阅参考资料)想出了一个简便方法,可以唯一标记从同一个客户机交互启动的每一个日志记录请求。Log4J为同一类别的线程生成一个Logger,多个线程共享使用,而它仅在日志信息中添加能够区分不同线程的信息,该信息可能是发出请求的主机名、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  {
   // 将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.

在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 {}
}


  log4jinit 
   org.javaresearch. log4j.Log4JInit        
   
    log4j-config-file  
   /properties/log4j.properties 
   

   1
  


注意:上面的load-on-startup应设为1,以便在Web容器启动时即装入该Servlet。log4j.properties文件放在根的properties子目录中,也可以把它放在其它目录中。应该把.properties文件集中存放,这样方便管理。 

Use log4j in J2EE

    在J2EE 服务器中使用log4j包需要注意的是:1)基于J2EE服务器jar包加载机制的特殊性,必须将log4j的jar包拷贝到%JAVAHOME\jre\lib\ext\目录下。仅仅放到CLASSPATH中是不起作用的。2)因为J2EE服务器对文件操作进行了严格的控制,所以Log文件时只能写到%J2EE_HOME%\logs目录下,除非修改server.policy文件指定别的可写目录。下面我举这个很简单的例子说明一下如何在J2EE服务器中使用上log4j开发工具包,例子中涉及的文件如下:

bonus.html



Bonus Calculation


ACTION="BonusAlias">


Enter social security Number:




Enter Multiplier:











上面的bonus.html接受用户输入的社会保险号和投保金额。
BonusServlet.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import Beans.*;
public class BonusServlet extends HttpServlet {
CalcHome homecalc;
public void init(ServletConfig config)
throws ServletException{
//Look up home interface
try{
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("calcs");
homecalc =(CalcHome)PortableRemoteObject.narrow(
objref,CalcHome.class);
} catch (Exception NamingException) {
NamingException.printStackTrace();
}
}
public void doGet (HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
String socsec = null;
int multiplier = 0;
double calc = 0.0;
PrintWriter out;
response.setContentType("text/html");
String title = "EJB Example";
out = response.getWriter();
out.println("");
try{
Calc theCalculation;
//Get Multiplier and Social Security Information
String strMult = request.getParameter("MULTIPLIER");
Integer integerMult = new Integer(strMult);
multiplier = integerMult.intValue();
socsec = request.getParameter("SOCSEC");
//Calculate bonus
double bonus = 100.00;
theCalculation = homecalc.create();
calc = theCalculation.calcBonus(multiplier, bonus);
} catch(Exception CreateException){
CreateException.printStackTrace();
}
//Display Data
out.println("

Bonus Calculation

");
out.println("

Soc Sec: " + socsec + "

");
out.println("

Multiplier: " + multiplier + "

");
out.println("

Bonus Amount: " + calc + "

");
out.println("");
out.close();
}
public void destroy() {
System.out.println("Destroy");
}
}


BonusServlert.java得到从bonus.html中传过来的社会保险号和金额,并调用EJB程序对数据进行处理并将结果显示给客户端。

EJB 的Home接口:

package Beans;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface CalcHome extends EJBHome {
Calc create() throws CreateException,RemoteException;
}

EJB 的Remote 接口:
package Beans;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Calc extends EJBObject {
public double calcBonus(int multiplier,double bonus)
throws RemoteException;
}

EJB 的业务处理逻辑:
package Beans;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class CalcBean implements SessionBean {
public double calcBonus(int multiplier,double bonus) {
double calc = (multiplier*bonus);
return calc;
}
//These methods are described in more
//detail in Lesson 2
public void ejbCreate() { }
public void setSessionContext(
SessionContext ctx) { }
public void ejbRemove() { }
public void ejbActivate() { }
public void ejbPassivate() { }
public void ejbLoad() { }
public void ejbStore() { }
}

    成功发布后就可以在代码中加入Log4j的测试代码了。想详细了解上面的应用程序的发布步骤请叁照我最近写的一篇文章“Say ‘Hello World’ to EJB”。接下来我们在EJB中使用Log4j包(由于Servlet 中使用Log4j的方法和前面提到的例子中的使用方法相同,这里不在重复)。
1. 首先在EJB的Remote接口中增加名为logtest的方法声明:
package Beans;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Calc extends EJBObject {
public double calcBonus(int multiplier,double bonus)
throws RemoteException;
public void logtest() throws RemoteException;
}

2.在 EJB的业务处理Bean中实现logtest()方法:
package Beans;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import org.apache.log4j.Category;
import org.apache.log4j.Logger;
import org.apache.log4j.*;
import org.apache.log4j.NDC;

public class CalcBean implements SessionBean {
static Logger logger = Logger.getLogger(CalcBean.class.getName());
public double calcBonus(int multiplier,double bonus) {
logger.debug("Entering calcBeans() method"); 
logtest();
double calc = (multiplier*bonus);
logger.debug("Exitint calcBeans() method");
return calc;
}
public void logtest(){
logger.debug("Enter logtest method");
NDC.push("Client #45890"); 
logger.debug("Exiting logtest method.");
}
//These methods are described in more
//detail in Lesson 2
public void ejbCreate() { 
PropertyConfigurator.configure("F:/example.properties"); 
}
public void setSessionContext(
SessionContext ctx) { }
public void ejbRemove() { }
public void ejbActivate() { }
public void ejbPassivate() { }
public void ejbLoad() { }
public void ejbStore() { }
}


这里假设log配置文件为F:盘下的example.properties文件。
接下来就是配置文件的设置问题了。
Example.properties
# Attach appender A1 to root. Set root level to Level.DEBUG.
log4j.rootLogger=DEBUG, A1

# A1 is set to be a FileAppender sending its output to
# a log file. However, only error messages and above will be printed
# in A1 because A1's threshold is set to Level.ERROR.

# The fact that the root level is set to Prority.DEBUG only influences
# log requests made to the root logger. It has no influence on the
# *appenders* attached to root.
# Appender A1 writes to the file "test" in J2EE's allow write DIR ex logs direstory.
log4j.appender.A1=org.apache.log4j.FileAppender
log4j.appender.A1.File=E:/j2sdkee1.3/logs/test.log

# Truncate 'test' if it aleady exists.
log4j.appender.A1.Append=false

# Appender A1 uses the PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%5r %-5p [%t] %c{2} - %m%n
# Set the level of the logger named "Beans.CalcBean" to 
# Level.DEBUG(also INFO WARN ERROR etc.),auto attach appender A1.
log4j.category.Beans.CalcBean=debug


这样重新发布这个EJB就回在%J2EE_HOME%\logs 目录下生成名为test.log的log文件。

13:48 | 评论 (0)

2005年3月1日

背景
对于有经验的开发者来说,日志记录的重要性显而易见。例如程序中的异常处理和安全性都依赖于Logging的功能来帮助履行它们的指责。应用程序中的日志记录主要基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作;跟踪代码运行时轨迹,作为日后审计的依据;担当集成开发环境中的调试器的作用,向文件或控制台打印代码的调试信息。经验表明日志记录是开发周期中的重要组成部分。

最简单的做法就是在代码中嵌入许多的打印语句,但是这样打印语句会充斥代码的主体,显然不是一个好方法。因此,使用成熟的框架例如Log4j,则会更具灵活性。

Log4j简介
Log4j 框架是用 Java 语言编写的标准日志记录框架。作为 Jakarta 项目的一部分,它在 Apache 软件许可证(Apache Software License)下分发,以速度和灵活性为中心概念:Log4j 环境是完全可配置的,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

Log4j由三个重要的部件构成:记录器(Loggers)、输出源(Appenders)和布局(Layouts)。

记录器按照布局中指定的格式把日志信息写入一个或多个输出源。输出源可以是控制台、文本文件、XML文件或Socket,甚至还可以把信息写入到Windows事件日志或通过电子邮件发送。我们可以通过配置文件来部署这些组件。

其实您也可以完全不使用配置文件,而是在代码中配置Log4j环境。但是,使用配置文件将使您的应用程序更加灵活。本文从描述 log4j 体系结构的主要组件着手。然后是描述基本用法和配置的简单示例。

定义配置文件
Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件(键=值)。下面我们介绍使用Java特性文件做为配置文件的方法:

一、 配置记录器。

Log4j允许程序员定义多个记录器,每个记录器有自己的名字。但有一个记录器叫根记录器,它永远存在,且不能通过名字检索或引用,在配置文件中,可以如下定义根记录器:

  log4j.rootLogger = [ level ] , appenderName, appenderName, … 

Level是记录器的级别,它是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别:ERROR、WARN、INFO、DEBUG:

  DEBUG  <  INFO  <  WARN  <  ERROR  <  FATAL

右边的级别比左边的高。如果一条log信息的级别,大于等于记录器的级别值,那么记录器就会记录它。例如level被设置为INFO级别,那么应用程序中所有的DEBUG的日志信息将不被打印出来。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。

 appenderName是输出源的名字,它指定日志信息输出到哪个地方。您可以为一个记录器指定多个输出源。

在一些配置文件中,你可能会看到下面的语句:

  log4j.rootCategory = [ level ] , appenderName, appenderName, … 

在早期的Log4j版本中,org.apache.Category实现了记录器的功能,为了提高向后兼容性,Logger扩展了Category,因此rootCategory和rootLogger是可以互换的,但最后Category将从类库中删除,因此请使用Logger类。

除了根记录器之外,log4j允许程序员定义多个记录器,每个记录器有自己的名字:

  log4j.logger.loggerName = [ level ] , appenderName, appenderName, … 

在Log4J中Logger是具有层次关系的,Log4j支持配置的记录器之间的“父子关系”,记录器之间通过名字来表明隶属关系(或家族关系),它们有一个共同的根,位于最上层,其它Logger遵循类似包的层次:记录器a.b,与记录器a.b.c之间是父子关系,而记录器a与a.b.c之间是祖先与后代的关系。例如:

    static Logger root = Logger.getRootLogger();
       static Logger log1 = Logger.getLogger("cc");
       static Logger log2 = Logger.getLogger("cc.ejb");
       static Logger log3 = Logger.getLogger("cc.ejb.my.TestApp");
 
上面代码中,log1是log2的父亲,是log3的祖先,而root是所有log1、log2、log3的祖先,它们都从root中继承。所以,一般情况下,仅需要配置好rootLogger,其它子记录器都会从中继承rootLogger的配置。如果修改了rootLogger的配置,其它所有的子记录器也会继承这种变化。这样就大大地方便了配置。
 
如果一个应用中包含了上千个类都需要日志,那么我们是否需要配置上千个Logger呢?我们通过一个简单的办法来解决这个问题: 用每一个java类文件名(包含该类的包名)定义一个记录器,这是一种有用并且直观的记录器实例名的定义方式。例如在配置文件中定义了一个com.foo的记录器:
  log4j.logger.com.foo=WARN
在com.foo中的一个java类bar,我们通过其本类的名字获得一个记录器“com.foo.Bar”:

package com.foo;
class Bar{
static Logger log=Logger.getLogger(bar.Class.getName());
.....
}

由于记录器com.foo.Bar 没有指定的级别,它从com.foo(在配置文件中其级别设置成WARN) 继承级别。并且这样我们就能方便的从大量log信息中判断出它们各自的来源。当然了,这不是硬性规定的,实际上Log4j没有对设置记录器的实例名做什么限制,程序员可以根据自己的喜好随意定义。

二、日志信息输出源Appender
log4j 还允许日志记录请求打印到多个输出目的地,按 log4j 的叫法是输出源。一个记录器可以有多个输出源。一条log信息如果可被这个记录器处理,则该记录器会把这条信息送往每个它所拥有的输出源,以及层次结构中更高级的输出源。例如,根记录器以控制台作为输出源,则所有可被纪录的日志都将至少打印到控制台。

配置日志信息输出源,其语法为:

  log4j.appender.appenderName = fully.qualified.name.of.appender.class


  log4j.appender.appenderName.option1 = value1 
  … 
  log4j.appender.appenderName.option = valueN 

Log4j提供的appender有以下几种: 

  • org.apache.log4j.ConsoleAppender(控制台)
  • org.apache.log4j.FileAppender(文件) 
  • org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
  • org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件) 
  • org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方) 
  • org.apache.log4j.SocketAppender (Socket)
  • org.apache.log4j.NtEventLogAppender   (NT的Event Log) 
  • org.apache.log4j.JMSAppender   (电子邮件)

请注意,可以通过覆盖缺省行为,这样就不再附加累积的输出源:

  log4j.additivity.loggerName=false

注意,不要把一个输出源附加到多个记录器上,否则会得到“Attempted to append to closed appender named xxx”的信息。


三、配置日志信息的格式(布局),其语法为:

  log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class 
  log4j.appender.appenderName.layout.option1 = value1 
  … 
  log4j.appender.appenderName.layout.option = valueN 

其中,Log4j提供的layout有以下几种: 

  • org.apache.log4j.HTMLLayout(以HTML表格形式布局)
  • org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
  • org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
  • org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

如果采用了PatternLayout, 则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 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10) 

四、例子
下面是一个完整的Log4j配置文件,这个配置文件指定了两个输出源stdout和R。前者把日志信息输出到控制台,后者是一个轮转日志文件。最大的文件是100KB,当一个日志文件达到最大尺寸时,Log4J会自动把example.log重命名为example.log.1,然后重建一个新的example.log文件,依次轮转。

log4j.rootLogger=debug, stdout, R

log4j.appender.stdout=org.apache.log4j.FileAppender
log4j.appender.stdout.File=System.out
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

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log

log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

log4j.logger.cc.ejb.my=error,out

log4j.appender.out=org.apache.log4j.ConsoleAppender
log4j.appender.out.layout=org.apache.log4j.PatternLayout
log4j.appender.out.layout.ConversionPattern=%p %t %c - %m%n

log4j.logger.cc.ejb.my.son=debug
log4j.additivity.cc.ejb.my.son=false

在代码中使用Log4j 

一、得到记录器
使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。其语法为: 

  public static Logger getLogger( String name) 

通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字,比如: 

  static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )

二、读取配置文件 
当获得了日志记录器之后,第二步将配置Log4j环境,其语法为:

  BasicConfigurator.configure (): 自动快速地使用缺省Log4j环境。
  PropertyConfigurator.configure ( String configFilename) :读取使用Java的特性文件编写的配置文件。
  DOMConfigurator.configure ( String filename ) :读取XML形式的配置文件。

三、插入记录信息(格式化日志信息)
当上两个必要步骤执行完毕,您就可以轻松地使用不同优先级别的日志记录语句插入到您想记录日志的任何地方,其语法如下:

  Logger.debug ( Object message ) ;
  Logger.info ( Object message ) ;
  Logger.warn ( Object message ) ;
  Logger.error ( Object message ) ;

四、例子

我们通过下面这个简单的例子,来演示在程序如何使用Log4j,您可以修改配置文件以得到不同日志信息。

package cc.ejb.my;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import my.son.Foo;
public class TestApp {

    static Logger logger=Logger.getLogger(TestApp.class.getName());

    public static void main(String[] args) {
       
        PropertyConfigurator.configure("log4j.properties");
        logger.info("Applcaiton Starts");
        logger.warn("Bar Starts");
        Bar bar=new Bar();
        logger.error("Bar Errors");
        bar.doIt();
        logger.warn("Bar  Exits");
        logger.info("Foo Starts");
        Foo foo=new Foo();
        logger.error("Foo Errors");
        foo.doit();
        logger.warn("Foo exits ");
        logger.info("Applcaition Exits");
       
    }

}

class Bar
{
    static Logger logger = Logger.getLogger(Bar.class.getName());
    public void doIt() {
      logger.debug("Did it again!");
    }
  }

package cc.ejb.my.son;

import org.apache.log4j.Logger;

public class Foo {
    private Logger log=Logger.getLogger(Foo.class.getName());
    public Foo() {
        log.info("Foo Initialzie");
    }
    public void doit()
    {
        log.debug("Do it in Foo");
    }

}


只有注册用户登录后才能发表评论。


网站导航: