Java API 自带的日志管理,可配置文件路径,并自动创建不存在的目录

来源:互联网 发布:12306数据库 编辑:程序博客网 时间:2024/05/01 05:37

原文转自:http://blog.csdn.net/naruto1021/article/details/7968664,只做收藏用。

由于项目需要根据日志来跟踪了解系统信息,方便查看传输数据以及异常信息,所以打算用log4j来完成这个日志管理的功能。

可惜的是,在使用中发现log4j在打印异常信息时,并不能像控制台那样详细打印出跟踪栈StackTrace内的信息到配置文件指定的日志文件中去。

可能是我能力有限,网上查了很多资料,尝试了很多办法都不行。

后来发现Java API 自带的日志管理java.util.logging.Logger好像可以满足要求,于是尝试了一下,结果如愿以偿,深感欣慰啊。

关于怎么使用Java自带的日志管理,相信网上有很多例子,我就不重复说了。

在这里我只想说一下,在加载配置文件路径时,如果路径不存在,日志管理类LogManager不会主动创建不存在的目录,而是报异常如下:

[plain] view plaincopy
  1. Can't load log handler "java.util.logging.FileHandler"  
  2. java.io.IOException: Couldn't get lock for C:/iMessengerLogs/log%g.log  
  3. java.io.IOException: Couldn't get lock for C:/iMessengerLogs/log%g.log  
  4.     at java.util.logging.FileHandler.openFiles(Unknown Source)  
  5.     at java.util.logging.FileHandler.<init>(Unknown Source)  
  6.     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)  
  7.     at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)  
  8.     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)  
  9.     at java.lang.reflect.Constructor.newInstance(Unknown Source)  
  10.     at java.lang.Class.newInstance0(Unknown Source)  
  11.     at java.lang.Class.newInstance(Unknown Source)  
  12.     at java.util.logging.LogManager$3.run(Unknown Source)  
  13.     at java.security.AccessController.doPrivileged(Native Method)  
  14.     at java.util.logging.LogManager.loadLoggerHandlers(Unknown Source)  
  15.     at java.util.logging.LogManager.initializeGlobalHandlers(Unknown Source)  
  16.     at java.util.logging.LogManager.access$1100(Unknown Source)  
  17.     at java.util.logging.LogManager$RootLogger.getHandlers(Unknown Source)  
  18.     at java.util.logging.Logger.log(Unknown Source)  
  19.     at java.util.logging.Logger.doLog(Unknown Source)  
  20.     at java.util.logging.Logger.log(Unknown Source)  
  21.     at java.util.logging.Logger.info(Unknown Source)  
  22.     at com.log.LoggerTest.main(LoggerTest.java:13)  

所以,在加载配置之前必须先读取配置文件中日志文件的目录,判断目录是否存在,如果不存在,则创建目录。

源码如下:

1.MyLogManager.java 日志管理(读取配置文件,创建目录,加载配置文件,获取日志对象)

[java] view plaincopy
  1. package com.log;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.util.Properties;  
  8. import java.util.logging.LogManager;  
  9. import java.util.logging.Logger;  
  10.   
  11. /** 
  12.  * 日志管理 
  13.  *  
  14.  * @author 
  15.  *  
  16.  */  
  17. public class MyLogManager {  
  18.   
  19.     private static Logger logger;  
  20.   
  21.     static {  
  22.         InputStream is1 = null;  
  23.         InputStream is2 = null;  
  24.         try {  
  25.             // 读取配置文件,创建相应的文件目录  
  26.             String logFilePath = "";  
  27.             is1 = new FileInputStream(  
  28.                     "D:\\workspace\\log\\src\\com\\log\\log.properties");  
  29.             Properties properties = new Properties();  
  30.             properties.load(is1);  
  31.             String pattern = properties  
  32.                     .getProperty("java.util.logging.FileHandler.pattern");  
  33.             logFilePath = pattern.substring(0, pattern.lastIndexOf("/"));  
  34.             File file = new File(logFilePath);  
  35.             if (!file.exists()) {  
  36.                 file.mkdirs();  
  37.             }  
  38.             // 重新初始化日志属性并重新读取日志配置  
  39.             is2 = new FileInputStream(  
  40.                     "D:\\workspace\\log\\src\\com\\log\\log.properties");  
  41.             LogManager logManager = LogManager.getLogManager();  
  42.             logManager.readConfiguration(is2);  
  43.   
  44.         } catch (SecurityException e) {  
  45.             e.printStackTrace();  
  46.         } catch (IOException e) {  
  47.             e.printStackTrace();  
  48.         } finally {  
  49.             try {  
  50.                 is1.close();  
  51.                 is2.close();  
  52.             } catch (IOException e) {  
  53.                 e.printStackTrace();  
  54.             }  
  55.         }  
  56.     }  
  57.   
  58.     /** 
  59.      * 获取日志对象 
  60.      *  
  61.      * @param clazz 
  62.      * @return 
  63.      */  
  64.     public static Logger getLogger(Class<?> clazz) {  
  65.         logger = Logger.getLogger(clazz.getName());  
  66.         return logger;  
  67.     }  
  68. }  

2.log.properties配置文件(带详细注释)
[plain] view plaincopy
  1. #Level的五个等级SEVERE(最高值) 、WARNING 、INFO 、CONFIG 、FINE 、FINER 、FINEST(最低值)  
  2.   
  3. #为 Handler 指定默认的级别(默认为 Level.INFO)。   
  4. java.util.logging.ConsoleHandler.level=INFO  
  5. # 指定要使用的 Formatter 类的名称(默认为 java.util.logging.SimpleFormatter)。   
  6. java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter  
  7.   
  8. # 为 Handler 指定默认的级别(默认为 Level.ALL)  
  9. java.util.logging.FileHandler.level=INFO  
  10. # 指定要使用的 Formatter 类的名称(默认为 java.util.logging.XMLFormatter)  
  11. java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter  
  12. # 指定要写入到任意文件的近似最大量(以字节为单位),如果该数为0,则没有限制(默认为无限制)  
  13. java.util.logging.FileHandler.limit=20480  
  14. # 指定有多少输出文件参与循环(默认为 1)。   
  15. java.util.logging.FileHandler.count=10  
  16. # 为生成的输出文件名称指定一个模式。有关细节请参见以下内容(默认为 "%h/java%u.log")  
  17. # "/" 本地路径名分隔符  
  18. # "%t" 系统临时目录   
  19. # "%h" "user.home"系统属性的值   
  20. # "%g" 区分循环日志的生成号   
  21. # "%u" 解决冲突的惟一号码   
  22. # "%%" 转换为单个百分数符号"%"  
  23. # 如果未指定 "%g"字段,并且文件计数大于 1,那么生成号将被添加到所生成文件名末尾的小数点后面   
  24. java.util.logging.FileHandler.pattern=C:/testLogs/log%g.log  
  25. # 指定是否应该将 FileHandler 追加到任何现有文件上(默认为 false)  
  26. java.util.logging.FileHandler.append=true  
  27.   
  28. # 指定handler  
  29. handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler  

3.LoggerTest.java日志测试类
[java] view plaincopy
  1. package com.log;  
  2.   
  3. import java.io.FileInputStream;  
  4. import java.util.logging.Level;  
  5. import java.util.logging.Logger;  
  6.   
  7. public class LoggerTest {  
  8.   
  9.     private static Logger logger = MyLogManager.getLogger(LoggerTest.class);  
  10.   
  11.     public static void main(String[] args) {  
  12.         try {  
  13.             logger.info("打印信息");  
  14.             //不存在的路径  
  15.             String filePath = "C:\\workspace\\log\\src\\com\\log\\log.properties";  
  16.             /** 
  17.              * 会抛出异常: 
  18.              * java.io.FileNotFoundException: C:\workspace\log\src\com\log\log.properties (系统找不到指定的路径。) 
  19.              */  
  20.             new FileInputStream(filePath);  
  21.         } catch (Exception e) {  
  22.             logger.log(Level.SEVERE, e.getMessage(), e);  
  23.         }  
  24.     }  
  25.   
  26. }  

4.日志文件中的异常打印信息