利用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,同时输出到控制台和文件,并分别控制输出级别。本文不做讨论,请自行搜索。




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