利用java.util.logging.Logger輸出日誌



log4j提供了非常靈活而又強大的日誌功能,java運行庫中的日誌功能反而被忽略了。其實也是挺好用的,最重要的是,用這個的話就不再需要log4j的jar文件。

由於java.util.logging.Logger不會自動加載配置文件,如果想用配置文件控制輸出級別,需要稍微做點工作:

  • 使用一個日誌管理類
package logger;


import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
  
public class LoggerManager {  
  
	private static Map<Class<?>,Logger> loggerCache = new HashMap<Class<?>,Logger>();
    // 初始化LogManager  
    static {  
        // 讀取配置文件  
        ClassLoader cl = LoggerManager.class.getClassLoader();  
        InputStream inputStream = null;  
        if (cl != null) {  
            inputStream = cl.getResourceAsStream("log.properties");  
        } else {  
            inputStream = ClassLoader  
                    .getSystemResourceAsStream("log.properties");  
        }  
        java.util.logging.LogManager logManager = java.util.logging.LogManager  
                .getLogManager();  
        if (inputStream == null){
        	System.err.println("LoggerManager: Log configuration NOT found!");
    
        }else try {  
            // 重新初始化日誌屬性並重新讀取日誌配置。  
            logManager.readConfiguration(inputStream);  
            System.out.println("LoggerManager: Log configuration loaded.");
            
                   } catch (Exception e) {  
            System.err.println(e);  
        }  finally{
        	try {inputStream.close();}
        	catch(Exception ex){
        		ex.printStackTrace();
        	}
        }
    }  
  
    /** 
     * 獲取日誌對象 
     * @param clazz 
     * @return 
     */  
    public static Logger getLogger(Class<?> clazz) {  
    	
        Logger logger = loggerCache.get(clazz);
        if (logger==null){
        	logger = Logger.getLogger(clazz.getCanonicalName());
        	loggerCache.put(clazz, logger); 
        }
        return logger;  
    }  
    /**
     * 獲取指定Logger的有效Level
     * @param logger
     * @return
     */
    public static Level getEffectiveLevel(Logger logger)
    {
    	Level level = null;
    	Logger parent = logger;
    	while (level==null){
    		if (parent==null)
    			break;
    		level = parent.getLevel();
    		parent = parent.getParent();
    	}
    	return level;
    }
  
}  


  • 然後,這樣使用日誌:

//啓動類,或者最先加載的類用此方法,可以先讀取配置文件,再生成Logger實例
 private static Logger logger = LoggerManager.getLogger(DocFillerDemo.class);


//一般的類可以這樣
  // private static Logger logger =Logger.getLogger(DocFillerDemo.class.getCanonicalName());


用法舉例:

logger.severe("錯誤信息");

logger.warn("警告信息");

logger.info("一般性信息,例如登錄情況,業務邏輯信息輸出等");

logger.fine("調試信息");

logger.finer("更細的調試信息");

ogger.finest("最細的調試信息");

  • 另外需要注意的問題是配置文件

log.properties:

#Levels: SEVERE, WARNING ,INFO,CONFIG,FINE ,FINER,FINEST
#Global level
#LOGGER.level=FINEST
.level=INFO

# Example to customize the SimpleFormatter output format 
# to print one-line log message like this:
#     <level>: <log message> [<date/time>]
#
#java.util.logging.SimpleFormatter.format="%4$s: %3$s %5$s [%1$tc] %n"

# handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler 
handlers= java.util.logging.ConsoleHandler
  
#set default level for ConsoleHandler
java.util.logging.ConsoleHandler.level=ALL
# set formatter 
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
  
java.util.logging.FileHandler.level=INFO
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
# lof file size limit   
java.util.logging.FileHandler.limit=1024000
# log file roll over count 
java.util.logging.FileHandler.count=3
# log file name pattern,default: "%h/java%u.log"
java.util.logging.FileHandler.pattern=C:/SSLog%u.log
# 
java.util.logging.FileHandler.append=true  


############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################
#set level of com.ordinov. 
#mandatory if logger got by: logger = Logger.getLogger(DocDataBySqlDAO.class.getCanonicalName());
com.ordinov.level=ALL

這個文件可以放在當前目錄,classpath目錄(LoggerManager能讀到)。

尤其注意其中幾個leve的設置:

.level=INFO

這是全局默認設置,所有的logger實例的默認值;

com.xxx.level=FINE

設置某一級別的默認值。這個設置覆蓋全局設置,並且可以被更細的級別繼承。也就是說,如果沒有別的設置,com.xxx.aaa 的有效level就是 com.xxx.level的值了;

如果設置了 com.xxx.bbb=FINER,那麼這個設置會影響com.xxx.bbb包以及子包的level。

另外不可忽略的是handler設置:

handlers= java.util.logging.ConsoleHandler

這一行確保所有級別的日誌可以在控制檯輸出

java.util.logging.ConsoleHandler.level=ALL

這一行確保控制檯會輸出所有級別。如果ConsoleHandler.level設置爲INFO,那麼即使com.xxx.level=FINE,屬於這個包的logger的fine級別信息也不會被輸出到控制檯。


當然,還可以加入FileHandler,同時輸出到控制檯和文件,並分別控制輸出級別。本文不做討論,請自行搜索。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章