log4j 使用详解:对每个类文件记录日志,每个包用同一个日志文件,不同的包对应不同的日志文件

需要学习基础的概念和知识的朋友请访问下面的链接,,写的挺详细,挺好的.

http://heavyz.sourceforge.net/homepage/homepage_zh/comp/notes/log4j.html

http://blog.csdn.net/joolu/archive/2009/04/08/4057458.aspx

http://blog.163.com/yangjianit/blog/static/117722471200962210424117/

下面具体了解下实现每个包共享一个日志文件的思路和实现..

首先简单总结下几个类,

Logger :这个是你要具体操作的类,,只要操作这个类就可以输出到日志文件里了,(也是实现该功能的重要部分),

Level,Priority:日志的级别,,总共用7个默认的级别,all<debug<info<warn<error<fatal<off(看英文就很明显了)

Appender:有以下几种,ConsoleAppender,FileAppender,RollingFileAppender,DailyRollingFileAppender,WriterAppender,,

其中FileAppender,RollingFileAppender,DailyRollingFileAppender这三个是WriterAppender的子类.

除了consoleAppender以外都是往输出流输出..顺便说下,LOG4J还可以往数据库里写。上三篇中有说明

还有Layout,LayoutPattern等等,,就不一一说了,查下官方的API就获得更详细的信息.

下面开始正题,我的思路是用log4j提供的 PropertyConfigurator.configure(Properties property);来实现的

不提供配置文件,,配置文件的内容都是通过这个properties的对象来提供的,设置好每个变量的值后调用上面的方法就可以得到用上面的内容为基础的logger对象,,然后用 logger的5中方法来调用就可以了,(logger.debug(),info(),error(),warn(),fatal())等等,但不是直接调用logger的方法,是你自己的类提供该方法的实现,,要做到每个包共享同一个日志文件,我是要做到每个类的日志都要对应到该类的目录结构下,,

比如说,com.jongsuny.util.loggerUtil 这个类的日志信息,,假定我要保存日志的跟目录为d:logs,,

该类的日志信息要保存在,d:logscomjongsunyutilmessage.log ,,其他类也一样,根据他的包生成路径..

用两个类来实现,,Log4jLogger,Log4jProperty,,两个类,第一个是日志记录器,也就相当于org.apache.log4j.Logger,,第二个是用来设置个变量的…下面具体看代码

package com.webs.log4j.custom;

import java.io.File;
import java.util.Enumeration;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

public class Log4jLogger {
private Logger logger = null;
private Log4jProperties property = new Log4jProperties();
//用类名构造出Logger
public Log4jLogger(String name) {
this.init(name);//设置Property的各个值
PropertyConfigurator.configure(this.property.getProperties());
//查看设置情况
Enumeration enums=this.property.getProperties().propertyNames();
while(enums.hasMoreElements()){
String temp=(String)enums.nextElement();
System.out.println(temp+” = “+this.property.getProperties().getProperty(temp));
}
//用Logger的getLogger(String)方法来创建logger
this.logger = Logger.getLogger(name);
}

public Log4jLogger(Class clazz) {
this.init(clazz.getName());
PropertyConfigurator.configure(this.property.getProperties());
this.logger = Logger.getLogger(clazz);
}
//返回Logger对象
public Logger getLogger(String name) {
System.out.println(name);
System.out.println(“afer:”+getPath(name));
return Logger.getLogger(name);
}
//设置各个变量的值
public void init(String path) {
property.setAppend(“true”);
property.setFile(this.getPath(path)+”error.log”);
//   property.setFileSize(“1MB”);
//   property.setMaxBackUp(“5″);
property.setLayout(“org.apache.log4j.PatternLayout”);
property.setLayoutPattern(“[%d{yyyy-MM-dd HH:mm:ss} | %c{3}:%L | %p:%m]%n”);
//   property.setLogType(“org.apache.log4j.RollingFileAppender”);
property.setLogType(“org.apache.log4j.DailyRollingFileAppender”);
property.setThreShold(“debug”);
}
//把类名解析成实际路径
public String getPath(String path){
String temp=path.replace(“.”, “/”).substring(0,path.replace(“.”, “/”).lastIndexOf(“/”)+1);
this.ceateDir(temp);//首先创建目录
return temp;
}
public void ceateDir(String path){
String base=this.property.getBasePath();
try{
String paths[]=path.split(“/”);
File file=new File(base+path);
if(!file.exists()){
file.mkdirs();
}
}catch(Exception e){
}
}
//下面是各个级别的记录方法,没什么可说的
public void fatal(Object o) {
logger.fatal(o);
}
public void error(Object o) {
logger.error(o);
}

public void warn(Object o) {
logger.warn(o);
}

public void info(Object o) {
logger.info(o);
}

public void debug(Object o) {
logger.debug(o);
}
}
////////////////////////////////////////////////////下面是Log4jProperty类的具体代码

package com.webs.log4j.custom;

import java.util.Properties;

public class Log4jProperties {
private final String LOG = “log4j.appender.logs”;
private final String LOG_FILE = “log4j.appender.logs.File”;
private final String LOG_LAYOUT = “log4j.appender.logs.layout”;
private final String LOG_LAYOUT_PATTERN = “log4j.appender.logs.layout.ConversionPattern”;
private final String LOG_THRESHOLD = “log4j.appender.logs.Threshold”;
private final String LOG_IMMEDIATEFLUSH = “log4j.appender.logs.ImmediateFlush”;
private final String LOG_DATEPATTERN = “log4j.appender.logs.DatePattern”;
private final String LOG_MAXFILESIZE = “log4j.appender.logs.MaxFileSize”;
private final String LOG_MAXBACKUPINDEX = “log4j.appender.logs.MaxBackupIndex”;
private final String LOG_APPEND = “log4j.appender.logs.Append”;
private Properties props = null;
private String basePath = “d:/logs/”;

public Log4jProperties() {
props = new Properties();
props.put(“log4j.rootLogger”,”debug,logs”);
}

public void setLogType(String value) {
props.put(this.LOG, value);
}

public void setFile(String value) {
props.put(this.LOG_FILE, basePath + value);
}

public void setAppend(String value) {
props.put(this.LOG_APPEND, value);
}

public void setFileSize(String value) {
props.put(this.LOG_MAXFILESIZE, value);
}

public void setMaxBackUp(String value) {
props.put(this.LOG_MAXBACKUPINDEX, value);
}

public void setImmediateFlush(String value) {
props.put(this.LOG_IMMEDIATEFLUSH, value);
}

public void setLayout(String value) {
props.put(this.LOG_LAYOUT, value);
}

public void setLayoutPattern(String value) {
props.put(this.LOG_LAYOUT_PATTERN, value);
}

public void setDatePattern(String value) {
props.put(this.LOG_DATEPATTERN, value);
}

public void setThreShold(String value) {
props.put(this.LOG_THRESHOLD, value);
}

public Properties getProperties() {
return props;
}

public String getBasePath() {
return basePath;
}

public void setBaseRoot(String basePath) {
this.basePath = basePath;
}

public void setProps(Properties props) {
this.props = props;
}
}
///下面是测试类

package com.webs.log4j.custom;

import org.apache.log4j.Logger;

public class LoggerTest {

/**
* @param args
*/
public static void main(String[] args) {
//   Logger log=new Log4jLogger(LoggerTest.class.getName()).getLogger(LoggerTest.class.getName());
Log4jLogger log=new Log4jLogger(LoggerTest.class.getName());
log.debug(“my test logs!”);
log.error(“this is error message”);
}

}
//这样就初步的得到了想要的效果了,,但是还有一些问题的存在,,我发现日志里的类的路径不全,,,

待改善的地方,,构造函数里加个Integer Type,,表示用哪中Appender,,然后就根据type来提供不同的properties,,这样就解决了日志的分类了,,比如说error都记录到每个包里的error.log里,如果是fatal级别的错误就直接输出到控制台,,还有把这个级别的错误同一写到一个文件里,,

暂时就是这样了,,,我的周末呀,,10点起来看个电影12点,吃个饭回来一直研究到下午5点才完事…本来就休息这么一天也被这个LOG4J吞了…但是有收获,,,值得,,如果有更好的办法,,请联系我或留言,,谢谢

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>