避免每个类中都初始化日志类
2016-06-22 16:07
260 查看
写代码的时候,很多类里需要打日志,一般写法都是:
Logger log = LoggerFactory.getLogger(XXX.class); // 或者参数给的是类名字符串
每个类里面都要写,好烦,能否封装一下,自动获取使用日志的类名,这样就不用每个类里都写了:
一个百试不爽的实现方式(通过异常栈获取):
其实,文首给出的实现也是jdk里的实现方式:
后面给出的代码是JDK1.4的源代码,和Log4J的源代码。说明其实现原理。
获得调用类,和方法名,就是需要获得当前运行栈的结构。
new Throwable().getStackTrace() 会返回当前运行栈的结构层次。
利用这种原理,可以获得整个运行栈的调用关系。
JDK1.4的java.util.logging包, 通过Throwable.getStackTrace()方法实现的。
// Get the stack trace.
StackTraceElement stack[] = (new Throwable()).getStackTrace();
log4j的实现也是异曲同工:
org.apache.log4j.spi.LocationInfo类。
先用Throwable.printStackTrace()方法把Exception信息打印到一个字符串里。
然后按行分析这个字符串。抽出调用类和方法。
JDK1.5在Thread类里面引入了getStackTrace()和getAllStackTraces()两个方法。这下子,我们不用 (new Throwable()).getStackTrace ();可以调用
Thread.getCurrentThread().getStackTrace()来获得当前线程的运行栈信息。不仅如此,只要权限允许,还可以获得其它线程的运行栈信息。不幸的是,虽然可以拿到栈信息,但是日志打印的时候依然显示的是Thread.getCurrentThread().getStackTrace()该语句所在的类的信息。
Logger log = LoggerFactory.getLogger(XXX.class); // 或者参数给的是类名字符串
每个类里面都要写,好烦,能否封装一下,自动获取使用日志的类名,这样就不用每个类里都写了:
一个百试不爽的实现方式(通过异常栈获取):
public static Logger getLogger() { Logger logger = Logger.getLogger(getInvokingClassName()); PropertyConfigurator.configure(getConfigFileName()); return logger; } public static String getInvokingClassName() { return new Throwable().getStackTrace()[2].getClassName(); }有人说这样的方式性能会有问题,网上有人给出了如下几种方式取得类名:
// 1、通过SecurityManager的保护方法getClassContext() String clazzName = new SecurityManager() { public String getClassName() { return getClassContext()[1].getName(); } }.getClassName(); System.out.println(clazzName); ****以上这个总觉得哪里有限制***** 2、通过分析匿名类名称() String clazzName3 = new Object() { public String getClassName() { String clazzName = this.getClass().getName(); return clazzName.substring(0, clazzName.lastIndexOf('$')); } }.getClassName(); System.out.println(clazzName3); 3、通过Thread的方法getStackTrace() String clazzName4 = Thread.currentThread().getStackTrace()[2].getClassName(); System.out.println(clazzName4); 注意:虽然以上3中方式都可以拿到类名,但是,写日志的时候,我们是要从日志里看出 日志是出自那个类,而以上3中都只能显示其自身所在的类信息,却得不到正在写日志的 类的信息。
其实,文首给出的实现也是jdk里的实现方式:
后面给出的代码是JDK1.4的源代码,和Log4J的源代码。说明其实现原理。
获得调用类,和方法名,就是需要获得当前运行栈的结构。
new Throwable().getStackTrace() 会返回当前运行栈的结构层次。
利用这种原理,可以获得整个运行栈的调用关系。
JDK1.4的java.util.logging包, 通过Throwable.getStackTrace()方法实现的。
// Get the stack trace.
StackTraceElement stack[] = (new Throwable()).getStackTrace();
log4j的实现也是异曲同工:
org.apache.log4j.spi.LocationInfo类。
先用Throwable.printStackTrace()方法把Exception信息打印到一个字符串里。
然后按行分析这个字符串。抽出调用类和方法。
JDK1.5在Thread类里面引入了getStackTrace()和getAllStackTraces()两个方法。这下子,我们不用 (new Throwable()).getStackTrace ();可以调用
Thread.getCurrentThread().getStackTrace()来获得当前线程的运行栈信息。不仅如此,只要权限允许,还可以获得其它线程的运行栈信息。不幸的是,虽然可以拿到栈信息,但是日志打印的时候依然显示的是Thread.getCurrentThread().getStackTrace()该语句所在的类的信息。
相关文章推荐
- Apache Log4j 2.0-rc1 发布
- Awstats处理多apache日志
- 典型入侵日志分析
- MS SQL Server数据库清理错误日志的方法
- 对MySQL日志操作的一些基本命令总结
- 简介操作MySQL日志的一些方法
- MySQL的日志基础知识及基本操作学习教程
- MSSQL 2005/2008 日志压缩清理方法小结
- SQL Server误区30日谈 第19天 Truncate表的操作不会被记录到日志
- C#3.0使用EventLog类写Windows事件日志的方法
- Sqlserver2005日志文件太大如何减小
- ORA-00392ORA-00312日志正在清除故障
- MySQL中查询日志与慢查询日志的基本学习教程
- mysql binlog二进制日志详解
- C#实现线程安全的简易日志记录方法
- C#实现将程序运行信息写入日志的方法
- ORACLE DATAGUARD中手工处理日志v$archive_GAP的方法
- 某个aspx页面突然死了连日志也没有的解决方法
- 如何查看数据库alert日志文件
- 解析php如何将日志写进syslog