模拟log4j获取日志对象调用所在的类名、方法名及行号

转载 2013年12月05日 21:52:39

    当我们在记录日志时,每个类中会定义一个日志对象,然后利用这个对象去写日志,那么我们在处理日志时,如何能才能记录日志对象所在的类、方法和行号呢?log4j中已经实现了该功能,那么它是怎么实现的呢?

    其实我们可以这样,在要写日志的代码时获得当前的线程信息,这样我们就可以获得上个线程的信息了(即对象写日志所在类的信息)。

    先看以下列子。

新建Location类和Test类:

      Location:

public class Location {
  public void getInfo(){
    String location="";
    StackTraceElement[] stacks = Thread.currentThread().getStackTrace(); 
    location = "类名:"+stacks[2].getClassName() + "\n函数名:" + stacks[2].getMethodName()
    + "\n文件名:" + stacks[2].getFileName() + "\n行号:"
    + stacks[2].getLineNumber() + "";
    System.out.println(location);
  }
}

Test:

public class Test {

  public static void main(String[] args) {
    Location l = new Location();
    l.getInfo();
  }

}

执行Test中的main函数,得到以下结果:

类名:thread.Test
函数名:main
文件名:Test.java
行号:10

是不是输出了Test类中调用的信息呢?那么有很多人就问了,为什么location类中调用的是stacts[2]而不是stacts[0]或其他的呢?

针对这个问题,我们可以将stacts数组里面的东西遍历输出一下就知道了:

StackTraceElement[] stacks = Thread.currentThread().getStackTrace(); 
    for(int i=0;i<stacks.length;i++){
      location = i+"  at "+stacks[i].getClassName() + "." + stacks[i].getMethodName()
      + "(" + stacks[i].getFileName() + ":"
      + stacks[i].getLineNumber() + ")";
      System.out.println(location);
    }

再次执行,输出结果如下:

0  at java.lang.Thread.getStackTrace(Thread.java:1436)
1  at thread.Location.getInfo(Location.java:6)
2  at thread.Test.main(Test.java:7)
那么这就好理解了,线程是以栈形式存放的,

分析一下StackTraceElement[] stacks = Thread.currentThread().getStackTrace();

此代码中会创建2个线程,调用Thread.currentThread().getStackTrace()时底层会创建一个线程,我们调用它也会创建一个线程,然后test调用getInfo函数时会创建一个线程,这样总共就三个线程了,程序执行顺序是先test类中调用getInfo方法,然后getInfo方法中调用StackTraceElement[] stacks = Thread.currentThread().getStackTrace();调用StackTraceElement[] stacks = Thread.currentThread().getStackTrace();时底层还会创建一个线程,根据栈的原理先进后出规则,他们的排队顺序就是上面输出的结果了。

在某个函数在被调用时用反射记录日志

/// /// 方法反射 /// /// /// private static string MethodRef...
  • Joyhen
  • Joyhen
  • 2014年08月12日 17:18
  • 959

log4j日志封装说明—slf4j对于log4j的日志封装-正确获取调用堆栈

日志是项目中必用的东西,日志产品里最普及应该就是log4j了。(logback这里暂不讨论。) 先看一下常用的log4j的用法,一般来说log4j都会配合slf4j或者common-logging使用...
  • u014437455
  • u014437455
  • 2014年04月19日 22:53
  • 1774

AOP日志,记录调用类、方法、方法参数名称、方法参数值(包括对象和基本类型)

AOP日志,记录调用类、方法、方法参数名称、方法参数值(包括对象和基本类型)...
  • paincupid
  • paincupid
  • 2016年04月17日 22:34
  • 15014

Log4j是输出日志时是如何获知当前方法、行号的

记得最早在项目中用Log4j的时候,也是觉得在每一个要记载日志的类中或者某个上层类中要声明一个Logger属性挺麻烦的protected static Log log = LogFactory.get...
  • relative660
  • relative660
  • 2009年06月12日 15:18
  • 4420

Log信息获取调用类和调用方法名的实现原理

恰好看到关于log的讨论。想起以前调查的一个问题。整理出来,希望对大家能有所帮助。  Sun JDK 源代码下载 http://wwws.sun.com/software/communityso...
  • zhangdaiscott
  • zhangdaiscott
  • 2012年02月19日 12:00
  • 2289

模拟log4j获取日志对象调用所在的类名、方法名及行号

http://www.cnblogs.com/pangblog/p/3397899.html 当我们在记录日志时,每个类中会定义一个日志对象,然后利用这个对象去写日志,那么我们在处理日志...
  • z69183787
  • z69183787
  • 2017年08月29日 16:57
  • 498

Log4j日志输出详细

日志论      在应用程序中输出日志有有三个目的: (1)监视代码中变量的变化情况,把数据周期性地记录到文件中供其他应用进行统计分析工作。 (2)跟踪代码运行进轨迹,作为日后审计的依据。 ...
  • zjml2412
  • zjml2412
  • 2015年11月21日 13:31
  • 9363

获取日志数据的方法和系统

摘要 本发明公开了一种获取日志数据的方法和系统,所述方法包括:第一Flume从应用服务器获取日志数据;所述第一Flume将获取的日志数据传送到Kafka,所述Kafka将收到的日志数据转换为Ka...
  • baidu_24932821
  • baidu_24932821
  • 2016年04月16日 11:12
  • 2081

日志组件slf4j介绍及配置详解

基本介绍每一个Java程序员都知道日志对于任何一个Java应用程序,尤其是服务端程序是至关重要的,而很多程序员也已经熟悉各种不同的日志库如java.util.logging、Apache log4j、...
  • u011331383
  • u011331383
  • 2016年05月12日 17:24
  • 47452

log4j(slf4j)使用资源集合

1、log4j和slf4j的介绍和区别slf4j及优势:是一个用户日志系统的facade,它允许用户在部署最终应用时方便的变更其日志系统,真正使用的还是比如log4j或commons-logging等...
  • javaloveiphone
  • javaloveiphone
  • 2016年07月11日 17:21
  • 407
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:模拟log4j获取日志对象调用所在的类名、方法名及行号
举报原因:
原因补充:

(最多只允许输入30个字)