关于log4j
来源:互联网 发布:apache ant 1.9.6 编辑:程序博客网 时间:2024/04/29 18:00
Log4j 是如何获取 类名、函数名、行数的
见 org.apache.log4j.spi.LocationInfo.LocationInfo(Throwable t, String fqnOfCallingClass)
源码分析
Object[] noArgs = null; // 获取函数调用栈 Object[] elements = (Object[]) getStackTraceMethod.invoke(t, noArgs); String prevClass = NA; for(int i = elements.length - 1; i >= 0; i--) { String thisClass = (String) getClassNameMethod.invoke(elements[i], noArgs); // 判断当前调用的类是否为 Category if(fqnOfCallingClass.equals(thisClass)) { int caller = i + 1; if (caller < elements.length) { className = prevClass; methodName = (String) getMethodNameMethod.invoke(elements[caller], noArgs); fileName = (String) getFileNameMethod.invoke(elements[caller], noArgs); if (fileName == null) { fileName = NA; } int line = ((Integer) getLineNumberMethod.invoke(elements[caller], noArgs)).intValue(); if (line < 0) { lineNumber = NA; } else { lineNumber = String.valueOf(line); } StringBuffer buf = new StringBuffer(); buf.append(className); buf.append("."); buf.append(methodName); buf.append("("); buf.append(fileName); buf.append(":"); buf.append(lineNumber); buf.append(")"); this.fullInfo = buf.toString(); } return; } prevClass = thisClass; }
函数调用栈
org.apache.log4j.spi.LoggingEvent.getLocationInformation(LoggingEvent.java:253)↓org.apache.log4j.helpers.PatternParser$LocationPatternConverter.convert(PatternParser.java:500)↓org.apache.log4j.helpers.PatternConverter.format(PatternConverter.java:65)↓org.apache.log4j.PatternLayout.format(PatternLayout.java:506)↓org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:310)↓org.apache.log4j.WriterAppender.append(WriterAppender.java:162)↓org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)↓org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:66)↓org.apache.log4j.Category.callAppenders(Category.java:206)↓xxx.xxx.Main(args:line)
从函数调用栈从下往上开始查找 Category ,若当前调用类为 Category, 则上层就是 调用者(这里即Main 方法)的调用信息。
如何手动获取 函数调用信息
(类名、函数名、行号)
// 指定 fqnOfCategoryClass 为 LoggingEvent.class.getName()LoggingEvent event = new LoggingEvent(LoggingEvent.class.getName(), logger, Level.DEBUG, "i am message", null);// 然后手动获取 LocationInfo,这时函数调用栈的倒数第二层就是// org.apache.log4j.spi.LoggingEvent.getLocationInformation(:line)// 此时的 line 就是下面这行代码的 行号LocationInfo info = event.getLocationInformation();
上面获取的行号只是 event.getLocationInformation() 的行数,所以要想获得自己想要的行号,必须对以上操作进行包装。
献上一个包装的 Logger
maven
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version></dependency>
wrapper Logger
注意观察 FQCN 的使用
import org.apache.log4j.Level;import org.apache.log4j.spi.LoggingEvent;/** * wrapper org.apache.log4j.Logger * * @author Jinpeng Cui * */public class Logger { public static final boolean enable = true; private static final String FQCN = Logger.class.getName(); private static org.apache.log4j.Logger proxy; public Logger(final String clazzName) { proxy = org.apache.log4j.Logger.getLogger(clazzName); } public static Logger getLogger(final Class<?> clazz) { return new Logger(clazz.getName()); } public void error(String message) { if (isErrorEnable()) { forceLog(Level.ERROR, message); } } public void info(String message) { if (isInfoEnabled()) { forceLog(Level.INFO, message); } } public void debug(String message) { if (isDebugEnabled()) { forceLog(Level.DEBUG, message); } } private void forceLog(Level level, String message) { proxy.callAppenders(new LoggingEvent(FQCN, proxy, level, message, null)); } public boolean isErrorEnable() { return enable && proxy.isEnabledFor(Level.ERROR); } public boolean isInfoEnabled() { return enable && proxy.isEnabledFor(Level.INFO); } public boolean isDebugEnabled() { return enable && proxy.isEnabledFor(Level.DEBUG); }}
0 0
- 关于Log4j
- 关于log4j
- 关于Log4j
- 关于log4j
- 关于log4j
- 关于Log4j
- 关于log4J
- 关于log4j
- 关于Log4j
- 关于log4j
- 关于log4j
- 关于Log4j
- 关于log4j
- 关于log4j的应用
- 【zz】关于Log4j
- 关于log4j异常问题
- 关于log4j的使用
- 关于log4j的问题
- 人工智能在围棋程序中的应用
- h5适配ios 屏幕
- 计算机基础概述--计算机技术的最基础最核心的技术(计算机网络、计算机组成原理、操作系统、数据结构)
- Binary Tree Paths
- Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能
- 关于log4j
- centos本身的防火墙firewall小结
- Image-Loader简单使用
- 一般函数指针和类的成员函数指针
- 代理服务器 Squid
- UVA514:Rails(铁轨)
- 九度 oj 题目1090:路径打印
- LVS集群中的IP负载均衡技术
- poj1026