0

I'm looking for a way to automate an arduous mechanical procedure that I perform too often: implementing trace logging on a method.

Consider the following fictitious methods.

private void createBaz(String key, String databaseConfigKey, String query) {
    this.queries.put(key, query);
    this.databases.put(key, Database.forKey(databaseConfigKey));
}

private void createFrob(String key, String hostname) {
    this.frobs.put(key, query);
}

Now, I'll add some useful logging.

private void createBaz(String key, String databaseConfigKey, String query) {
    this.log.trace("createBaz(" + key + ", " + databaseConfigKey + ", " + query + ")");
    this.queries.put(key, query);
    this.databases.put(key, Database.forKey(databaseConfigKey));
}

private void createFrob(String key, String hostname) {
    this.log.trace("createFrob(" + key + ", " + hostname + ")");
    this.frobs.put(key, query);
}

Note the similarities of the two log.trace calls.

I've typed out a lot of log lines like that, and I'm tired of it. I'm looking for something like this:

private void createBaz(String key, String databaseConfigKey, String query) {
    doLogTrace();
    this.queries.put(key, query);
    this.databases.put(key, Database.forKey(databaseConfigKey));
}

private void createFrob(String key, String hostname) {
    doLogTrace();
    this.frobs.put(key, query);
}

I might need help refining my question!

It doesn't matter to me if doLogTrace(); happens to be a longer string like doLogTrace(this,System.foo(),#$^#$&^$#);. It could even be multiple lines, so long as it's the SAME string wherever I use it. Then I could just put that string in a keyboard macro.

Things I've considered

  • AspectJ Not for this project.
  • IDE magic. I could probably write a macro for emacs that could jump to the top of the method, copy the name and parameter list, drop one line down, paste it and automagically edit it into log.trace("<methodName>(" + <method1> + ["," + <methodN>] +")");... But, normally my .java files are only open in Eclipse... :/
daveloyall
  • 2,140
  • 21
  • 23
  • You could investigate code injection. We use it for some things. I don't pretend to understand it yet. – keshlam Mar 13 '14 at 15:21
  • Can you elaborate on why AspectJ is not appropriate? Is it the aspect-oriented approach, or AspectJ in particular that is problematic? – Gus Mar 13 '14 at 15:49
  • @Gus, I don't know anything about AspectJ. For this project, I'm expected to leave the code in a form that can be built, modified, and debugged easily by a co-worker (or temp worker) who probably only has a stock, off the shelf copy of Eclipse. Moreover, it's old code. – daveloyall Mar 13 '14 at 17:42
  • @keshlam, I'm familiar with Dependency Injection. What is code injection? (I'm familiar with that term in the context of web application security, but I think you must be talking about something else.) – daveloyall Mar 13 '14 at 17:43
  • There are moderately standardized systems which run on top of tools like BCEL or ASM, which search for code patterns and modify them in standard ways. I've seen a system that automatically adds entry/exit messages to methods for problem analysis and logging to exception handlers, for debugging purposes. I don't know whether the one we used is widely available, but "if it happens, it must be possible." – keshlam Mar 13 '14 at 19:36
  • I believe that my question should have been "Does the Java Language provide a facility to do this?" and the answer is "No.". Thoughts? – daveloyall Mar 18 '14 at 17:47
  • Now that Java 8 has been released, perhaps there is a solution that isn't outside the java language. See string "Method parameter reflection" in http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html ? – daveloyall Mar 18 '14 at 20:38

3 Answers3

0

It sounds like you want Aspect-Oriented Programming

Here's a good overview of doing AOP with Guice

Mike B
  • 5,390
  • 2
  • 23
  • 45
  • I've added new comments to the question that are related to this; see above. Presently this project can be checked out, built, altered, and redeployed by anyone on my floor with no modifications to their development environment. Would using Guice change that? – daveloyall Mar 13 '14 at 17:47
  • No, Guice is more like a library that you use. I'm sure there probably is a way of using Guice that would preclude easy workspace setup, but if you just follow the documentation there should be no change at all to your development flow. – Mike B Mar 13 '14 at 18:03
0

From this post you can see how you can get the name of the currently executing method. Getting the name of the current executing method

Having that, you also got your each method parameters, so create a new method that will take the rest of parameters ( int... will allow you to enter any number of ints, you could use Object)

For example:

private void logTrace(Object ... args) {
    String methodName = stacktrace.methodName;
    String logmsg = methodName + "(";
    foreach(arg : args){
        logmsg+= arg + ", ";
    }
    logmsg+= ")";
    log(logmsg);
}
Community
  • 1
  • 1
Giannis
  • 5,286
  • 15
  • 58
  • 113
  • How do you invoke this? Can you get the varargs without typing them all in? – daveloyall Mar 13 '14 at 22:22
  • You could look it up. you can call logTrace("one","two","three"), then args inside logTrace will be an Object[3]. Its called Variable-length argument lists I believe. If you are looking for something more automated than this you probably want to look into java reflection – Giannis Mar 14 '14 at 10:13
0

You could use Java's Proxy class to add some before / after code for each method. The benefit is you can avoid modifying your original code.

If you're looking for more of a quick and dirty solution, you could use Thread.currentThread().getStackTrace() and just display the one relevant frame (it won't get the parameter values though)

Graham Griffiths
  • 2,196
  • 1
  • 12
  • 15
  • I'm not familiar with `java.lang.reflect.Proxy`. I get that you're suggesting I "wrap" my existing class in a proxy so that I can do logging there. Offhand, I suspect that doing this is complex enough that I'd introduce new bugs in the process... So, maybe I am indeed looking for a 'quick n' dirty' solution. :) – daveloyall Mar 13 '14 at 17:57