無設定檔使用log4j
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檔案中產生
出處:http://hi.baidu.com/cliff/item/16bae5a8ab3e7af715329b13