国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

關(guān)于log4j

2019-11-11 01:33:30
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

Log4j 是如何獲取 類名、函數(shù)名、行數(shù)的

見(jiàn) org.apache.log4j.spi.LocationInfo.LocationInfo(Throwable t, String fqnOfCallingClass)

源碼分析

Object[] noArgs = null; // 獲取函數(shù)調(diào)用棧 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); // 判斷當(dāng)前調(diào)用的類是否為 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; }

函數(shù)調(diào)用棧

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)

從函數(shù)調(diào)用棧從下往上開(kāi)始查找 Category ,若當(dāng)前調(diào)用類為 Category, 則上層就是 Main 方法的調(diào)用信息。

如何手動(dòng)獲取 函數(shù)調(diào)用信息(類名、函數(shù)名、行號(hào))

// 指定 fqnOfCategoryClass 為 LoggingEvent.class.getName()LoggingEvent event = new LoggingEvent(LoggingEvent.class.getName(), logger, Level.DEBUG, "i am message", null);// 然后手動(dòng)獲取 LocationInfo,這時(shí)函數(shù)調(diào)用棧的倒數(shù)第二層就是// org.apache.log4j.spi.LoggingEvent.getLocationInformation(:line)// 此時(shí)的 line 就是下面這行代碼的 行號(hào)LocationInfo info = event.getLocationInformation();

上面獲取的行號(hào)只是 event.getLocationInformation() 的行數(shù),所以要想獲得自己想要的行號(hào),必須對(duì)以上操作進(jìn)行包裝。

獻(xiàn)上一個(gè)包裝的 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); }}
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 双流县| 扶绥县| 佛学| 嘉荫县| 石阡县| 什邡市| 资溪县| 北辰区| 荣成市| 榆社县| 新野县| 沽源县| 清流县| 九寨沟县| 济宁市| 绥棱县| 泉州市| 崇文区| 阳曲县| 金坛市| 齐河县| 中卫市| 平远县| 新建县| 苏尼特左旗| 土默特左旗| 商都县| 萨迦县| 沐川县| 绥化市| 高安市| 万宁市| 德州市| 萝北县| 桓台县| 奎屯市| 珠海市| 张北县| 大邑县| 通江县| 乌鲁木齐县|