log4j概述

来源:互联网 发布:青岛和上海知乎 编辑:程序博客网 时间:2024/05/21 15:36

log4j----概述:
log4j有三种主要的组件:记录器,存放器,布局
Log4j有三个主要的组件:Loggers,Appenders和Layouts,这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出。
综合使用这三个组件可以轻松的记录信息的类型和级别,并可以在运行时控制日志输出的样式和位置。

记录器loggers:
log4j允许程序员定义多个记录器,每个记录器有自己的名字,记录器之间通过名字来表明隶属关系(或家族关系)。

有一个记录器叫根记录器,它永远存在,且不能通过名字检索或引用,可以通过Logger.getRootLogger()方法取得它,
而一般记录器通过Logger.getLogger(String name)方法。下面是Logger类的基本方法。

package org.apache.log4j;

public class Logger {

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

public static Logger getLogger(String name);

 

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


Java程序举例来说:

//建立Logger的一个实例,命名为“com.foo”

Logger  logger = Logger.getLogger("com.foo");

//设置logger的级别。通常不在程序中设置logger的级别。一般在配置文件中设置。

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.");

//命名为“com.foo.bar”的实例barlogger会继承实例“com.foo”的级别。因此,下面这个请求可用,因为INFO >= INFO

barlogger.info("Located nearest gas station.");

//下面这个请求不可用,因为DEBUG < INFO

barlogger.debug("Exiting gas station search");


有几个有趣的情况,一是当一个记录器实例化后,再一次用相同的名字调用getLogger()会返回对它的引用,
这非常有利于用同一个记录器在不同代码或类中记录log信息,另一个是与自然界中祖先先于后代出现不同,
一个记录器的祖先可以比后代记录出现的晚,但会自动根据名字之间的关系建立这种家族关系。


存放器: Appenders:
在log4j中,log信息通过存放器输出到目的地。支持的存放器有console, files, GUI components,
remote socket servers, JMS, NT Event Loggers, remote UNIX Syslog daemons。通过file存放器,
log信息可以被输出到不同的文件中(即不同的目的地)。log信息可被异步存放。

一个记录器可以有多个存放器,可以通过方法addAppender来增加存放器。一条blog信息如果可被这个记录器处理,
则记录器会把这条信息送往每个它所拥有的存放器。

配置根Logger,其语法为:
log4j.rootLogger = [ level ] , appenderName, appenderName, ...
level 是日志记录的优先级
appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。

配置日志信息输出目的地Appender,其语法为
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(将日志信息以流格式发送到任意指定的地方)

配置日志信息的格式(布局),其语法为:
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(包含日志产生的时间、线程、类别等等信息)

 

log4j的初始化:
log4j可以使用3中配置器来初始化:BasicConfigurator,DOMConfigurator,PropertyConfigurator 其语法为:
BasicConfigurator.configure (): 自动快速地使用缺省Log4j环境。
PropertyConfigurator.configure ( String configFilename) :读取使用Java的特性文件编写的配置文件。
DOMConfigurator.configure ( String filename ) :读取XML形式的配置文件。

properties文件的读取:见下边例子
//dbconfig.properties在classes根目录下
Properties prop = new Properties();
InputStream is = BaseBean.class.getClassLoader().getResourceAsStream("dbconfig.properties");
prop.load(is);
String url = prop.getProperty(prefix+".url");

//jdbc.properties在classes根目录下
Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("/jdbc.properties")); 
url = properties.getProperty("local.jdbc.url");

任何WEB工程,只要lib目录下有log4j的jar包,classes目录下边有log4j.properties,
则log4j.properties会自动加载,不用写任何代码,log4j就会初试化。

注意一点:PropertyConfigurator.configure ( String configFilename),这个语句只需要在系统启动的时候执行一次。
那么到底放到那里进行这条语句的初始化呢?(自己放到了servletlistener里边)

log4j实例的获得:
在需要使用log4j的类中,添加一个静态的属性:(不必是静态的把?)
public static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () ) ;
protected final Log logger = LogFactory.getLog(getClass());

log4j的命名:
Log4j使得通过软件组件命名logger很容易。我们可以通过Logger的静态的初始化方法在每一个类里定义一个logger,
令logger的名字等于类名的全局名,而实现logger的命名。这是一个实效的简单的定义一个logger的方法。
因为日志输出带有产生日志的类的名字,这个命名策略使得我们更容易定位到一个日志信息的来源。虽然普通,
但却是命名logger的常用策略之一。 Log4j没有限制定义logger的可能。开发员可以自由的按照它们的意愿定义logger的名称。 然而,
以类的所在位置来命名Logger好象是目前已知的最好方法。


log4j中配置日志文件相对路径方法:
在servletlistener中写:
PropertyConfigurator.configure ( String configFilename) ;//实例化log4j.properties
System.setProperty ("WORKDIR", WORKDIR);//设置个系统变量
log4j.properties中写:
log4j.appender.logfile.File=${WORKDIR}/logs/app.log
注意:
是log4j.appender.logfile.File=${WORKDIR}/logs/app.log   不是 log4j.appender.logfile.File=${WORKDIR}/logs/app.log .
System.setProperty ("WORKDIR", WORKDIR);//设置个系统变量 这句要先写,然后在写下边这一句。
PropertyConfigurator.configure ( String configFilename) ;//实例化log4j.properties 。
如:log4j.appender.logfile.File=${WORKDIR}/logs/app.log
其中“${WORKDIR}/”是个变量,会被System Property中的“WORKDIR”的值代替。这样,我们就可以在log4j加载配置文件之前,
先用System.setProperty ("WORKDIR", WORKDIR);设置好根路径,此操作可通过一初始的servlet进行。


log4j的日志输出:
log.debug("xx");
log.debug("xx",Exception e); //可以输出堆栈信息。log4j和commons-logging同样都行。


其他注意事项:
log4j不能创建目录,但是会自动创建log文件。
能不能不用logger.debug("xx");去输出日志呢? 可以
protected final Log logger = LogFactory.getLog(getClass());  这个是谁的方法?是commons-logging 的。

虽然不用logger.error("xxxx"); 在有错误的地方log4j也会输出日志,但是指明的错误地方不对()
WARN 2008-06-23 22:15:09,781 [org.apache.struts.action.RequestProcessor]
[org.apache.struts.action.RequestProcessor.processException(RequestProcessor.java:538)] -
<Unhandled Exception thrown: class java.lang.ArithmeticException>


如何将栈中的异常信息写入log4j.Logger配置的输出流中?
public static String errorException(Exception e) {
  StackTraceElement[] ste = e.getStackTrace();
  StringBuffer sb = new StringBuffer();
  sb.append(e.getMessage() + "/n");
  for (int i = 0; i < ste.length; i++) {
   sb.append(ste[i].toString() + "/n");
  }
  return sb.toString();
 }

我使用了如下方法获得异常所在的文件,行号和方法:  
  StackTraceElement   stackTraceElement=   ex.getStackTrace()[0];//   得到异常棧的首个元素  
  System.out.println("File="+stackTraceElement.getFileName());//   打印文件名  
  System.out.println("Line="+stackTraceElement.getLineNumber());//   打印出错行号  
  System.out.println("Method="+stackTraceElement.getMethodName());//   打印出错方法  


---------------------------------------------------------------------------------------------
log4j一般的使用步骤 :


1、建一个log4j.properties的配置文件,放到有main的入口类的相同路径下。

og4j.rootLogger=debug, stdout, R

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=%d %5p [%t] (%F:%L) - %m%n

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

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

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n


 

2、在入口类的静态区初始化log4j

 static {
  PropertyConfigurator.configure(
   YesFTPClientFrame.class.getResource("log4j.properties"));
 }

 

3、在每一个需要log的地方都初始化一个私有静态的变量

 private static Logger logger = Logger.getLogger(xx.class);

 

4、使用log4j提供的方法

logger.info(”hello”);

5、用log4j输出异常的堆栈信息

logger.error("oops, got an exception: ", e);

原创粉丝点击