Log4j从异常堆栈中获取类、方法、行数演示

好奇Log4j格式化日志时,上述信息获取方式。 跟踪代码,发现了其利用异常实现的,下面是简单例子:

  1. package com.billstudy.test;
  2. import java.lang.reflect.Method;
  3. /**
  4. * Test exception stack infomation analysis
  5. * @author LiBiao - Bill
  6. * @since V1.0 2016年4月15日 - 下午5:48:35
  7. */
  8. @SuppressWarnings({ "unchecked", "rawtypes" })
  9. public class StackDemo {
  10. private static Method getStackTraceMethod;
  11. private static Method getClassNameMethod;
  12. private static Method getMethodNameMethod;
  13. private static Method getFileNameMethod;
  14. private static Method getLineNumberMethod;
  15. static {
  16. Class[] noArgs = null;
  17. try {
  18. getStackTraceMethod = Throwable.class.getMethod("getStackTrace", noArgs);
  19. Class stackTraceElementClass = Class.forName("java.lang.StackTraceElement");
  20. getClassNameMethod = stackTraceElementClass.getMethod("getClassName", noArgs);
  21. getMethodNameMethod = stackTraceElementClass.getMethod("getMethodName", noArgs);
  22. getFileNameMethod = stackTraceElementClass.getMethod("getFileName", noArgs);
  23. getLineNumberMethod = stackTraceElementClass.getMethod("getLineNumber", noArgs);
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. /**
  29. * Obtain relevant information from the exception stack
  30. * @author LiBiao - Bill
  31. * @since V1.0 2016年4月15日 - 下午6:14:33
  32. * @param e
  33. * @param className
  34. */
  35. private static void analysisException(Exception e, String className) {
  36. Object[] noArgs = null;
  37. try {
  38. Object[] elements = (Object[]) getStackTraceMethod.invoke(e,noArgs);
  39. for (int i = 0; i < elements.length; i++) {
  40. Object element = elements[i];
  41. String clazz = (String) getClassNameMethod.invoke(element, noArgs);
  42. // find
  43. if (className.equals(clazz)) {
  44. String method = (String) getMethodNameMethod.invoke(element, noArgs);
  45. int line = (Integer) getLineNumberMethod.invoke(element, noArgs);
  46. String fileName = (String) getFileNameMethod.invoke(element, noArgs);
  47. String result = String.format(
  48. "class:%s \r\n "
  49. + "method:%s \r\n "
  50. + "line:%s \r\n "
  51. + "fileName:%s \r\n errorMsg:%s", clazz,method,line,fileName,e.getMessage());
  52. System.out.println(result);
  53. break;
  54. }
  55. }
  56. } catch (Exception ex) {
  57. ex.printStackTrace();
  58. }
  59. }
  60. public static void main(String[] args) {
  61. String findClassName = "com.billstudy.test.StackDemo$B";
  62. try {
  63. A a = new A();
  64. a.test();
  65. } catch (Exception e) {
  66. //e.printStackTrace();
  67. analysisException(e, findClassName);
  68. }
  69. // a.nullException();
  70. }
  71. public static class A {
  72. private B b = new B();
  73. public void test() {
  74. b.test();
  75. }
  76. public void nullException() {
  77. String target = null;
  78. target.intern();
  79. }
  80. }
  81. public static class B {
  82. private C c = new C();
  83. public void test() {
  84. c.test();
  85. }
  86. }
  87. public static class C {
  88. public void test() {
  89. throw new RuntimeException("别问我为啥,就是想抛个异常 ~");
  90. }
  91. }
  92. }

(更多…)