最近在封装一个Java报警的SDK,期望应用程序在调用SDK报警API方法时能调用类和调用方法名并通过邮件和短信的方式通知给开发者。
大致有两种方式,总结一下。
1. 通过Throwable.getStackTrace()
StackTraceElement[] arr = (new Throwable()).getStackTrace();
for(int i=0; i<arr.length; i++) {
StackTraceElement el = arr[i];
System.out.println(i+"\t"+el.getClassName()+"\t" +el.getMethodName()+"\t"+el.getLineNumber());
}
简单模拟一下日志框架(log4j、lobback)的功能,如下:
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* ${DESCRIPTION}
*
* @author Ricky Fung
*/
public class StackTraceTest {
public static void main(String[] args) {
Log log = new Log();
log.info("hello");
}
}
class Log {
public void info(String msg) {
System.out.println(String.format("%s | %s", getCaller(), msg));
}
public String getCaller() {
StackTraceElement[] arr = (new Throwable()).getStackTrace();
//打印格式: date | thread | class | msg
StringBuilder sb = new StringBuilder(100);
sb.append(getDate()).append(" | ").append(Thread.currentThread().getName()).append(" | ")
.append(arr[2].getClassName()).append('(').append(arr[2].getMethodName()).append(':').append(arr[2].getLineNumber()).append(')');
return sb.toString();
}
public String getDate() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
}
打印结果:
2017-08-17 14:35:27 | main | com.yirendai.titan.alert.StackTraceTest(main:16) | hello
2. 通过Thread的方法getStackTrace()
JDK1.5在Thread类里面引入了getStackTrace()和getAllStackTraces()两个方法。这下子,我们不用 (new Throwable()).getStackTrace ();可以调用
Thread.getCurrentThread().getStackTrace()来获得当前线程的运行栈信息。不仅如此,只要权限允许,还可以获得其它线程的运行栈信息。
StackTraceElement[] arr = Thread.currentThread().getStackTrace();
模拟日志框架,如下:
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* ${DESCRIPTION}
*
* @author Ricky Fung
*/
public class StackTraceTest {
public static void main(String[] args) {
Log log = new Log();
log.info("hello");
}
}
class Log {
public void info(String msg) {
StackTraceElement[] arr = Thread.currentThread().getStackTrace();
System.out.println(String.format("%s | %s", inferCaller(arr), msg));
}
public String inferCaller(StackTraceElement[] arr) {
//打印格式: date | thread | class | msg
StringBuilder sb = new StringBuilder(100);
sb.append(getDate()).append(" | ").append(Thread.currentThread().getName()).append(" | ")
.append(arr[2].getClassName()).append('(').append(arr[2].getMethodName()).append(':').append(arr[2].getLineNumber()).append(')');
return sb.toString();
}
public String getDate() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
}