I wouldn't say it was a bad code base, but it was done by a single geeky programmer who never cared about the readability because I guess he never thought anyone else would ever try to read it. Anyway, I could see all these meaningful log messages coming out from it but I didn't know from where. I think he never heard of log4j or anything like that but luckily he used a class like this:
and used it like this:
public class LogHelper{
public static void log(String log){
System.out.println(log);
}
}
1 public class XSo he called this static log method from all over the code base to do the logging.
2 {
3 public void doA()
4 {
5 Logger.log("doing A");
6
7 //..
8 //..
9 Logger.log("done doing A");
10 }
11
12 public void doB()
13 {
14 Logger.log("doing B");
15
16 //..
17 //..
18 Logger.log("done doing B");
19 }
20 }
And the log looked like this:
doing A
doing B
done doing B
done doing A
I desperately wanted to know which class/method/line was calling this method like I am used to in log4j.
Then I thought the calling Thread has this information. The question is how can I get it! After playing a bit with stack information, I came up with this:
public static String getCallingMethodInfo() {So finally the log method looked like this:
StackTraceElement[] stackTrace ;
try{
throw new Exception();
}
catch (Exception e) {
stackTrace = e.getStackTrace();
}
if(stackTrace != null && stackTrace.length >= 2) {
StackTraceElement s = stackTrace[2];
if(s != null) {
return s.getClassName() + ".(" + s.getMethodName() +"):["+ s.getLineNumber() + "] -:";
}
}
return null;
}
public class LogHelper {
public static void log(String log){
String caller = getCallingMethodInfo();
System.out.println(caller + ": " + log);
}
}
So, finally the logs looked like this:
In jdk 1.5 you can actually get the stack information like this:
X.(doA):[5]-: doing A
X.(doB):[14]-: doing B
X.(doA):[9]-: done doing A
X.(doB):[18]-: done doing B
Thread.currentThread().getStackTrace()but unfortunately I was working with a 1.4 codebase. But Throwing an exception and catching it back did the trick :)
Having said all that, It will be an insane idea to put this code to production. But can be very helpful when you are trying to understand the code.
1 comment:
You don't need to throw and catch your exception. This works just as well:
final Throwable fakeException = new Throwable();
final StackTraceElement[] elements = fakeException.getStackTrace();
Post a Comment