log4j是apache的开源java程序,功能非常强大,可应用到不同的领域,支持多种方式如console,file,email,db等多种形式的日志。但是相对来说,log4j的配置也必须复杂,需要一个log4j.properties的文件,每次配置一个日志还需要修改,而且配置文件配置复杂,那么如何简单的使用log4j,打造一个简单而通用的log系统呢?
下面是我写的一个通用的基于log4j的class,很多功能都得到了削减,但又最大程度满足了日志的需求,程序如下,读者可以自行修改:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package logproject;
import org.apache.log4j.Logger;
import org.apache.log4j.RollingFileAppender;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.Level;
import java.io.File;
import java.util.HashMap;
/**
*
* @author pgaof
*/
public class Logging {
private Logger logger = null;
private String posFlag = "";
private static HashMap instances = new HashMap();
private Logging(String logName,String logPath){
logger = Logger.getLogger(logName);
RollingFileAppender appender = new RollingFileAppender();
if(logPath==null || logPath.trim().equals("")) //如果没有指定logPath,那么设置为默认的logpath
logPath = getDefaultLogPath();
File file = new File(logPath);
if(!file.exists()){ //确保logPath是否存在,如果不存在,那么创建一个
file.mkdir();
}
appender.setFile(logPath+"/"+logName+".log");
appender.setAppend(true);
appender.setMaxFileSize("10240KB"); //设置log文件最大大小为10M
appender.setMaxBackupIndex(2); //设置log文件生成的,如果超过10M,那么就是log.1,log.2等
appender.setLayout(new PatternLayout("[%d] %r %-5p -- %m%n")); //设置log生成格式
appender.activateOptions(); //激活选项
logger.addAppender(appender);
}
/**
* 如果没有指定log name,那么默认为"default",生成的log就是default.log
* @return
*/
public static Logging getLog(){
return getLog(null);
}
public static Logging getLog(String logName){
return getLog(logName,null);
}
/**
* 获取Logging的实例.
* @param logName log文件的名字,相同的log名称的话,那么写入同一个log文件中
* @param logPath log存储路径
* @return
*/
public synchronized static Logging getLog(String logName,String logPath){
if(logName==null || logName.trim().equals("")) logName="default";
if(!instances.containsKey(logName)){
Logging logging = new Logging(logName,logPath);
instances.put(logName,logging);
}
return (Logging)instances.get(logName);
}
public void info(Object msg){
getCaller();
msg=msg+"--"+posFlag;
logger.info(msg);
}
public void info(Object msg,Throwable t){
getCaller();
msg=msg+"--"+posFlag;
logger.info(msg,t);
}
public void debug(Object msg){
getCaller();
msg=msg+"--"+posFlag; /*msg加上调用class的调用信息。这样做的原因是因为log4j本身的配置中虽然包含了此信息,但是由于是通用class,调用的情况不太相同,如果不人工加上,那么显示的class信息就是本类的class,无法正确的显示信息项*/
logger.debug(msg);
}
public void debug(Object msg,Throwable t){
getCaller();
msg=msg+"--"+posFlag;
logger.debug(msg,t);
}
public void error(Object msg){
getCaller();
msg=msg+"--"+posFlag;
logger.error(msg);
}
public void error(Object msg,Throwable t){
getCaller();
msg=msg+"--"+posFlag;
logger.error(msg,t);
}
public void fatal(Object msg){
getCaller();
msg=msg+"--"+posFlag;
logger.fatal(msg);
}
public void fatal(Object msg,Throwable t){
getCaller();
msg=msg+"--"+posFlag;
logger.fatal(msg,t);
}
/**
* 获取此类被调用的root类。就是最开始是那个类调用了该类
* @return
*/
private void getCaller(){
StackTraceElement stack[] = (new Throwable()).getStackTrace();
for(int i=0;i<stack.length-1;i++){
// System.out.println(stack[i].getClassName()+","+stack[i].getFileName()
// +","+stack[i].getMethodName()+","+stack[i].getLineNumber()+"|"+this.getClass().getName());
if(stack[i].getClassName().equals(this.getClass().getName()) && !stack[i+1].getClassName().equals(this.getClass().getName())){
posFlag = "["+stack[i+1].getClassName()+"."+stack[i+1].getMethodName()+"("+stack[i+1].getFileName()+":"+stack[i+1].getLineNumber()+")]";
break;
}
}
}
private String getDefaultLogPath(){
String logPath = "c:/logfiles";
if(File.pathSeparatorChar==':'){
logPath="/logfiles";
}
return logPath;
}
}
使用此class很简单,方法如下:
Logging logging = Logging.getLog(); //在默认位置window下是c:/logfiles,Unix下是:/logfiles 生成一个default.log文件
Logging logging = Logging.getLog("test"); //在默认位置生成test.log文件
Logging logging = Logging.getLog("test","d:/"); //在d:/下生成test.log文件
logging.info("hello world");
注明:"test"等是log文件名,如果设置成相同,那么就会在同一个log文件中生成