Log4j 使用简介(从网上得到的)

1.简介
程序开发环境中的日志记录是由嵌入在程序中以输出一些对开发人员有用信息的语句所组成。例如,跟踪语句( trace ),结构转储和常见的 System.out.println printf 调试语句。 log4j 提供分级方法在程序中嵌入日志记录语句。日志信息具有多种输出格式和多个输出级别。
使用一个专门的日志记录包,可以减轻对成千上万的 System.out.println 语句的维护成本,因为日志记录可以通过配置脚本在运行时得以控制。 log4j 维护嵌入在程序代码中的日志记录语句。通过规范日志记录的处理过程,一些人认为应该鼓励更多的使用日志记录并且获得更高程度的效率。
2. 快速入门
在深入介绍 log4j 之前我们先来看一段代码,对 log4j  有一个初步的了解,代码如下:
创建一个类,代码如下:
package TestLog4j;
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.Priority;;

public class TestLog4j 
{
    //
代码( 1
    static Logger logger = Logger.getLogger(TestLog4j.class.getName());
    public TestLog4j(){}
    public static void main(String[] args)
{
     //
代码( 2
        BasicConfigurator.configure();
         //
代码( 3
        logger.debug("Start of the main() in TestLog4j");
        logger.info("Just testing a log message with priority set to INFO");
        logger.warn("Just testing a log message with priority set to WARN");
        logger.error("Just testing a log message with priority set to ERROR");
        logger.fatal("Just testing a log message with priority set to FATAL");
        logger.log(Priority.DEBUG, "Testing a log message use a alternate form");
        logger.debug("End of the main() in TestLog4j");
    }
}

最后运行这个类,你就会看到运行结果为:
0 [main] DEBUG TestLog4j.TestLog4j  - Start of the main() in TestLog4j
10 [main] INFO TestLog4j.TestLog4j  - Just testing a log message with priority set to INFO
10 [main] WARN TestLog4j.TestLog4j  - Just testing a log message with priority set to WARN
21 [main] ERROR TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR
21 [main] FATAL TestLog4j.TestLog4j  - Just testing a log message with priority set to FATAL
111 [main] DEBUG TestLog4j.TestLog4j  - Testing a log message use a alternate form
111 [main] DEBUG TestLog4j.TestLog4j  - End of the main() in TestLog4j


首先解释一下上面输出结果的意义。第一个数字是指程序开始运行到运行该日志语句所经历的毫秒数(用来做一点运行效率分析也不错),“[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
3.安装
为了使用我们即将要安装的日志记录工具,还必须要设置操作环境,只有这样,工具才能知道从哪里找到它所需要的信息,并且操作系统知道从哪里找到这个工具。那么,怎样做呢?实际上,它要求更改操作环境。我有一些这方面的资格文档。 Configuring A Windows Working Environment Configuring A Unix Working Environment.
1.       http://jakarta.apache.org/log4j/docs/download.html 下载 log4j 发行版。
2.       解压存档文件到合适的目录中。
3.       添加文件 dist/lib/log4j-1.2.6.jar CLASSPATH 环境变量中。
4.log4j的基本概念
使用 log4j 大概涉及 3 个主要概念 :
1.       公共类 Logger
Logger 负责处理日志记录的大部分操作。
2.       公共接口 Appender
Appender 负责控制日志记录操作的输出。
3.       公共抽象类 Layout
Layout 负责格式化 Appender 的输出。
4.1.Logger
日志记录器 (Logger) 是日志处理的核心组件。 log4j 具有 5 种正常级别 (Level) 日志记录器 (Logger) 的可用级别 Level ( 不包括自定义级别 Level) 以下内容就是摘自 log4j API (http://jakarta.apache.org/log4j/docs/api/index.html):
·         static Level DEBUG
DEBUG Level 指出细粒度信息事件对调试应用程序是非常有帮助的。
·         static Level INFO
INFO level 表明 消息在粗粒度级别上突出强调应用程序的运行过程。
·         static Level WARN
WARN level 表明会出现潜在错误的情形。
·         static Level ERROR
ERROR level 指出虽然发生错误事件,但仍然不影响系统的继续运行。
·         static Level FATAL
FATAL level 指出每个严重的错误事件将会导致应用程序的退出。
另外,还有两个可用的特别的日志记录级别 : ( 以下描述来自 log4j API http://jakarta.apache.org/log4j/docs/api/index.html):
·         static Level ALL
ALL Level 是最低等级的,用于打开所有日志记录。
·         static Level OFF
OFF Level 是最高等级的,用于关闭所有日志记录。
日志记录器( Logger )的行为是分等级的
ALL (最低等级) < DEBUG < INFO < WARN < ERROR < FATAL < OFF (最高等级)
引入级别后就可通过修改调试的级别来控制某个调试信息是否输出。假设我们有的信息是在开发时才需要输出的(称为测试信息),那么我们把输出测试信息的Logger的级别在开发时设为DEBUG级别的,并用debug(Object message)函数来进行打印。当要发布系统时,只需把相应的Logger的级别调高就可以屏蔽掉测试信息。

. 日志输出等级
日志记录器(Logger)将只输出那些级别高于或等于它的级别的信息。如果没有设置日志记录器(Logger)的级别,那么它将会继承最近的祖先的级别。因此,如果在包 com.foo.bar 中创建一个日志记录器(Logger)并且没有设置级别,那它将会继承在包 com.foo 中创建的日志记录器(Logger)的级别。如果在 com.foo 中没有创建日志记录器(Logger)的话,那么在 com.foo.bar 中创建的日志记录器(Logger)将继承 root 日志记录器(Logger)的级别,root日志记录器(Logger)经常被实例化而可用,它的级别为 DEBUG
有很多方法可以创建一个日志记录器( Logger ),下面方法可以取回 root 日志记录器 :

Logger logger = Logger.getRootLogger();

还可以这样创建一个新的日志记录器 :

Logger logger = Logger.getLogger("MyLogger");

比较常用的用法,就是根据类名实例化一个静态的全局日志记录器 :

static Logger logger = Logger.getLogger(test.class);

所有这些创建的叫 "logger" 的日志记录器都可以用下面方法设置级别 :

logger.setLevel((Level)Level.WARN);

可以使用 7 个级别中的任何一个 ; Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR, Level.FATAL, Level.ALL and Level.OFF.
4.2.Appender
Appender 控制日志怎样输出。下面列出一些可用的 Appender(log4j API 中所描述的 http://jakarta.apache.org/log4j/docs/api/index.html):
1.       ConsoleAppender: 使用用户指定的布局 (layout) 输出日志事件到 System.out 或者 System.err 。默认的目标是 System.out
2.       DailyRollingFileAppender 扩展 FileAppender ,因此多个日志文件可以以一个用户选定的频率进行循环日志记录。
3.       FileAppender 把日志事件写入一个文件
4.       RollingFileAppender 扩展 FileAppender 备份容量达到一定大小的日志文件。
5.       WriterAppender 根据用户的选择把日志事件写入到 Writer 或者 OutputStream
6.       SMTPAppender 当特定的日志事件发生时,一般是指发生错误或者重大错误时,发送一封邮件。
7.       SocketAppender 给远程日志服务器(通常是网络套接字节点)发送日志事件( LoggingEvent )对象。
8.       SocketHubAppender 给远程日志服务器群组(通常是网络套接字节点)发送日志事件( LoggingEvent )对象。
9.       SyslogAppender 给远程异步日志记录的后台精灵程序 (daemon) 发送消息。
10.   TelnetAppender 一个专用于向只读网络套接字发送消息的 log4j appender
还可以实现 Appender 接口,创建以自己的方式进行日志输出的 Appender
4.2.1.使用ConsoleAppender
ConsoleAppender 可以用这种方式创建:

ConsoleAppender appender = new ConsoleAppender(new PatternLayout());

创建了一个控制台 appender ,具有一个默认的 PatternLayout 。它使用了默认的 System.out 输出。
4.2.2.使用FileAppender
FileAppender 可以用这种方式创建 :

          FileAppender appender = null;
 
          try {
 
             appender = new FileAppender(new PatternLayout(),"filename");
 
          } catch(Exception e) {}
 
        

上面用到的构造函数 :

FileAppender(Layout layout, String filename) 
 
          实例化一个FileAppender并且打开变量"filename"指定的文件。
 
        

另一个有用的构造函数是:

FileAppender(Layout layout, String filename, boolean append) 
 
          实例化一个FileAppender并且打开变量"filename"指定的文件。
 
        

这个构造函数还可以选择是否对指定的文件进行追加的方式输出。如果没有指定值,那么默认的方式就是追加。
4.2.3.使用WriterAppender
WriterAppender 可以用这种方式创建 :

          WriterAppender appender = null;
 
          try {
 
            appender = new WriterAppender(new PatternLayout(),new FileOutputStream("filename"));
 
          } catch(Exception e) {}
 
        

这个 WriterAppender 使用的构造函数带有 PatternLayout OutputStream 参数,在这种情况下, FileOutputStream 用于向一个文件输出。当然,它还具有其他可用的构造函数。
4.3.Layout
4.3.1简介
Appender 必须使用一个与之相关联的 Layout ,这样它才能知道怎样格式化它的输出。当前, log4j 具有三种类型的 Layout:
1.       HTMLLayout 格式化日志输出为 HTML 表格。
2.       PatternLayout 根据指定的 转换模式 格式化日志输出,或者如果没有指定任何转换模式,就使用默认的转换模式。
3.       SimpleLayout 以一种非常简单的方式格式化日志输出,它打印级别 Level ,然后跟着一个破折号“ - ,最后才是日志消息。
4.3.2 打印参数
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)
4.4.基本示例
4.4.1.SimpleLayout FileAppender
这里是一个非常简单的例子,程序实现了 SimpleLayout FileAppender:

import org.apache.log4j.Level;
 
import org.apache.log4j.Logger;
 
import org.apache.log4j.SimpleLayout;
 
import org.apache.log4j.FileAppender;
 
public class simpandfile {
 
   static Logger logger = Logger.getLogger(simpandfile.class);
 
   public static void main(String args[]) {
 
      SimpleLayout layout = new SimpleLayout();
 
      FileAppender appender = null;
 
      try {
 
         appender = new FileAppender(layout,"output1.txt",false);
 
      } catch(Exception e) {}
 
      logger.addAppender(appender);
 
      logger.setLevel((Level) Level.DEBUG);
 
      logger.debug("Here is some DEBUG");
 
      logger.info("Here is some INFO");
 
      logger.warn("Here is some WARN");
 
      logger.error("Here is some ERROR");
 
      logger.fatal("Here is some FATAL");
 
   }
 
}
 
        

你可以下载 : simpandfile.java 还可以查看它的输出: output1.txt.
4.4.2.HTMLLayout WriterAppender
这里是一个非常简单的例子,程序实现了 HTMLLayout WriterAppender:

import java.io.*;
 
import org.apache.log4j.Level;
 
import org.apache.log4j.Logger;
 
import org.apache.log4j.HTMLLayout;
 
import org.apache.log4j.WriterAppender;
 
public class htmlandwrite {
 
   static Logger logger = Logger.getLogger(htmlandwrite.class);
 
   public static void main(String args[]) {
 
      HTMLLayout layout = new HTMLLayout();
 
      WriterAppender appender = null;
 
      try {
 
         FileOutputStream output = new FileOutputStream("output2.html");
 
         appender = new WriterAppender(layout,output);
 
      } catch(Exception e) {}
 
      logger.addAppender(appender);
 
      logger.setLevel((Level) Level.DEBUG);
 
      logger.debug("Here is some DEBUG");
 
      logger.info("Here is some INFO");
 
      logger.warn("Here is some WARN");
 
      logger.error("Here is some ERROR");
 
      logger.fatal("Here is some FATAL");
 
   }
 
}
 
        

你可以下载 : simpandfile.java. 还可以查看它的输出: output1.txt.
4.4.3.PatternLayout ConsoleAppender
这里是一个非常简单的例子,程序实现了 PatternLayout ConsoleAppender:

import org.apache.log4j.Level;
 
import org.apache.log4j.Logger;
 
import org.apache.log4j.PatternLayout;
 
import org.apache.log4j.ConsoleAppender;
 
public class consandpatt {
 
   static Logger logger = Logger.getLogger(consandpatt.class);
 
   public static void main(String args[]) {
 
      // Note, %n is newline
 
      String pattern = "Milliseconds since program start: %r %n";
 
             pattern += "Classname of caller: %C %n";
 
             pattern += "Date in ISO8601 format: %d{ISO8601} %n";
 
             pattern += "Location of log event: %l %n";
 
             pattern += "Message: %m %n %n"; 
 
      
 
     PatternLayout layout = new PatternLayout(pattern);
 
      ConsoleAppender appender = new ConsoleAppender(layout);
 
      logger.addAppender(appender);
 
      logger.setLevel((Level) Level.DEBUG);
 
      logger.debug("Here is some DEBUG");
 
      logger.info("Here is some INFO");
 
      logger.warn("Here is some WARN");
 
      logger.error("Here is some ERROR");
 
      logger.fatal("Here is some FATAL");
 
   }
 
}
 
        

你可以下载 :simpandfile.java. 还可以查看它的输出: output2.txt.
5.实例对比
看一个简单的例子,它是一个用 Java实现的客户/服务器网络程序。刚开始我们不使用Log4j,而是使用了一系列的打印语句,然后我们将使用Log4j来实现它的日志功能。这样,大家就可以清楚地比较出前后两个代码的差别。
 
不使用log4j的 客户程序
 
package log4j ;

import java.io.* ;
import java.net.* ;

/**
*
* <p> Client Without Log4j </p>
* <p> Description: a sample with log4j</p>
* @version 1.0
*/
public class ClientWithoutLog4j {

/**
*
* @param args
*/
public static void main ( String args [] ) {

String welcome = null;
String response = null;
BufferedReader reader = null;
PrintWriter writer = null;
InputStream in = null;
OutputStream out = null;
Socket client = null;

try {
client = new Socket ( "localhost", 8001 ) ;
System.out.println ( "info: Client socket: " + client ) ;
in = client.getInputStream () ;
out = client.getOutputStream () ;
} catch ( IOException e ) {
System.out.println ( "error: IOException : " + e ) ;
System.exit ( 0 ) ;
}

try{
reader = new BufferedReader( new InputStreamReader ( in ) ) ;
writer = new PrintWriter ( new OutputStreamWriter ( out ), true ) ;

welcome = reader.readLine () ;
System.out.println ( "debug: Server says: '" + welcome + "'" ) ;

System.out.println ( "debug: HELLO" ) ;
writer.println ( "HELLO" ) ;
response = reader.readLine () ;
System.out.println ( "debug: Server responds: '" + response + "'") ;

System.out.println ( "debug: HELP" ) ;
writer.println ( "HELP" ) ;
response = reader.readLine () ;
System.out.println ( "debug: Server responds: '" + response + "'" ) ;

System.out.println ( "debug: QUIT" ) ;
writer.println ( "QUIT" ) ;
} catch ( IOException e ) {
System.out.println ( "warn: IOException in client.in.readln()" ) ;
System.out.println ( e ) ;
}
try{
Thread.sleep ( 2000 ) ;
} catch ( Exception ignored ) {}
}
}

 
迁移到 Log4j 客户程序
 
package log4j ;

import java.io.* ;
import java.net.* ;

// add for log4j: import some package
import org.apache.log4j.PropertyConfigurator ;
import org.apache.log4j.Logger ;
import org.apache.log4j.Level ;

/**
*
* <p> Client With Log4j </p>
* <p> Description: a sample with log4j</p>
* @version 1.0
*/
public class ClientWithLog4j {

/*
add for log4j: class Logger is the central class in the log4j package.
we can do most logging operations by Logger except configuration.
getLogger(...): retrieve a logger by name, if not then create for it.
*/
static Logger logger = Logger.getLogger
( ClientWithLog4j.class.getName () ) ;

/**
*
* @param args : configuration file name
*/
public static void main ( String args [] ) {

String welcome = null ;
String response = null ;
BufferedReader reader = null ;
PrintWriter writer = null ;
InputStream in = null ;
OutputStream out = null ;
Socket client = null ;

/*
add for log4j: class BasicConfigurator can quickly configure the package.
print the information to console.
*/
BasicConfigurator.configure () ;

// add for log4j: set the level
// logger.setLevel ( ( Level ) Level.DEBUG ) ;

try{
client = new Socket( "localhost" , 8001 ) ;

// add for log4j: log a message with the info level
logger.info ( "Client socket: " + cli
ent ) ;
in = client.getInputStream () ;
out = client.getOutputStream () ;
} catch ( IOException e ) {

// add for log4j: log a message with the error level
logger.error ( "IOException : " + e ) ;

System.exit ( 0 ) ;
}

try{
reader = new BufferedReader ( new InputStreamReader ( in ) ) ;
writer = new PrintWriter ( new OutputStreamWriter ( out ), true ) ;

welcome = reader.readLine () ;

// add for log4j: log a message with the debug level
logger.debug ( "Server says: '" + welcome + "'" ) ;

// add for log4j: log a message with the debug level
logger.debug ( "HELLO" ) ;

writer.println ( "HELLO" ) ;
response = reader.readLine () ;

// add for log4j: log a message with the debug level
logger.debug ( "Server responds: '" + response + "'" ) ;

// add for log4j: log a message with the debug level
logger.debug ( "HELP" ) ;

writer.println ( "HELP" ) ;
response = reader.readLine () ;

// add for log4j: log a message with the debug level
logger.debug ( "Server responds: '" + response + "'") ;

// add for log4j: log a message with the debug level
logger.debug ( "QUIT" ) ;

writer.println ( "QUIT" ) ;
} catch ( IOException e ) {

// add for log4j: log a message with the warn level
logger.warn ( "IOException in client.in.readln()" ) ;

System.out.println ( e ) ;
}
try {
Thread.sleep ( 2000 ) ;
} catch ( Exception ignored ) {}
}
}
至此关于 log4j的大体概况就讲述到这种水平,相信大家都已经对他有所了解了,如果你还想更深的了解log4j,请经常访问下面提及的相关链接:
Log4j项目主页…………………………………………………. www.log4j.org
Log4j FAQ………………………………………………………. www.log4j.org/log4j/faq.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值