How to trace Java servlet execution? - java

I've hit one of those bugs that only seem to show up in production. Whenever I try to reproduce the error on my development machine, even with the same input data, I draw a blank.
So, I want to be able to trace the entire execution flow of this Java servlet which is running through Tomcat 7, from its invocation to the final exception that gets thrown. Ideally, it'd give me a lengthy list of method calls, parameters and return values. Something like the *nix strace, except for Java classes.
I did find Execution trace/flow in java 6 and higher where in the comments BTrace is linked to. I've had a look at it, but don't really see how it might help me. Also, it looks to be centered around running through a separate Java program. I'm OK with adding a bit of code, but really don't want to have to go into every method to add a trace call.
The absolute best would be if whatever approach used to do this can be coaxed into logging through slf4j (since I already use that for logging), but any logging is better than none.
How to obtain such a trace of a servlet?

I am not aware of an automatic tool for this but it is fairly easy to do by hand.
Just pick a few relevant places (for example inside the servlet) when it is actually called and do something like:
logger.info("Called X with Params "+y, new Exception());
That will give you the method, the parameters and the stack trace.
Scatter a few more log lines like that in relevant places and you should be able to track down the problem.

Maybe the Mapped Diagnostic Context can help you in this situation. Since you're using slf4j, it should be no problem to switch to logback as logging framework.
With it, you can provide additional informations, such as URI, session etc. + you can extend your logging pattern to include method and class to drill down your stack.

Related

Eclipse - Method Call Feed?

In Eclipse is there a way to view all methods that are called while a program is debugging in a list-style view? I'm not looking to step through the code and I'm aware of the call hierarchy, I'd just like to see every method that is involved while running a process on an application - something like a feed of all activity. Anything like this exist?
Nothing as such out of the box eclipse provides except Call Hierarchy which you already know. For following options you have to code a bit:
Use logging framework (log4j, slf4j etc.) to put trace in each method and it will log all methods in sequence at runtime
If you are using spring you can achieve above result with the help of aspects as well
You can use byte code modifier like javaassist to insert these logging statements at runtime as well.
All these options only work with a good logging. Hope this helps.

Java - Line by line 'debug report'

The program I'm building seems to freeze at some points on the user's system. When I test the very same steps, I see no problem. Even though Java is supposed to be a platform-independent VM, my guess is it has to do with the systems we're using (I'm on linux, the user on Mac), maybe something with file access.
I cannot access the user's system, and the user has no idea what debugging means. In order to test where the problem is, I was thinking of writing the program's progress to a file, and having him send me the file when there's a problem. Therefore my question:
Is there some kind of library which allows writing the line by line execution of a program to a file? Ideally, the values of certain variables would also be included.
edit: I'm familiar with Logger, but (like one answer says), that would require writing a lot of log statements. Is there some way to do this automatic? Maybe line by line is overkill, but something like log each method entry/exit would definitely work.
Thanks a lot!
This might be a good use case for aspect-oriented programming. Specifically, the AspectJ library for Java might suit your needs (there are others, but this is the one I'm most familiar with). You could define a logging aspect that would automatically insert method entry/exit log messages into the methods you wish to trace, without having to modify the code for those methods. The aspect can be included or excluded as you wish whenever you build the application (eg, include it just for this user until you resolve the issue).
Something like the following might be a good start:
aspect LogAllMethods {
Log log = new Log(); // pseudocode -- replace with whatever logging mechanism you like
before(): call(public * com.mycompany.*.*(..)) {
log.log("Entered method: " + thisJoinPoint);
}
after(): call(public * com.mycomapny.*.*(..)) {
log.log("Leaving method: " + thisJoinPoint);
}
}
This basically says that, before and after any public method call in the package com.mycompany, log the entry/exit and the name of the method (thisJoinPoint is a special variable in AspectJ that refers to the point in the program's execution that the aspect is being applied to). The AspectJ documentation has some nice tutorials and examples of defining aspects and how they can be used, as well as instructions on how to introduce aspects into your application.
This might be overkill for your situation and underutilization of AspectJ, but it should allow you to do some fine-grained debugging without having to add logging calls to every method in your code.
Typically the debug information you want would be included in a log file. Logging frameworks like Java's built in Logging API allow you to configure what severity of messages to produce when the program is run. In other words, you could have it normally report severe errors only, but enable debug output selectively when you need more information.
However, logging frameworks normally require you, the programmer, to explicitly tell it what to log. It doesn't simply log everything (that would be a lot of data too!).
It sounds like what you want is logging in your application. See the Wikipedia article for Java Logging Frameworks for details.
Some of the more common logging frameworks, all mentioned in the aforementioned article, are:
Log4J
Java Logging API
Apache Commons Logging
SLF4J

Debugging: to System.out.println() or to not System.out.println()

That is my question. More specifically, I'm trying to get used to Eclipse's debugger and I'd like to know if printing to console is still done in some cases or if it's considered a bad practise that should be entirely avoided. Also, what can be considered as good approach(es) to debugging overall?
Use System.err.println() instead.
Why?
System.out.println() is often redirected to a file or another output, while this is pretty much always printed on the console. It's easier for debugging and also the right way to do it.
Edit (warning: subjective):
Since you asked about whether System.out.println should be entirely avoided: I don't believe in anything that you must always avoid, be it using goto's, crashing your computer with a BSOD, or whatever. Sometimes you just need a quick-and-dirty way to get small things done fast, and it just plain isn't worth the 1 hour you'll spend on it to try to do things the "right" way, instead of a 5-minute fix, no matter how good the "good" way is. Use your judgment when deciding if something should be used or not, but never set rules for yourself like "I'll never use goto!". :)
Edit 2 (example):
Let's say you're debugging a crashing driver and you suspect that an if statement that shouldn't be execute is being executed. Instead of spending three hours finding out how to use ZwRaiseHardError to display a message box, just call KeBugCheck inside the if and crash the darned system. Sure, you'll reboot, but unless your reboot takes hours, you just saved yourself that much time.
The best choice would be a logging library (of course, this adds an extra dependency to your project). Check out commons-logging, for instance.
The main advantage is that you can write your debug messages in the DEBUG level and when you deploy your code, you'll just configure the logger to skip those messages (instead of searching for all occurrences of System.out.println in your code).
One other great advantage is that loggers usually can be configured to write anywhere (even send email messages or SMS) also without touching your code.
Minor point: if your program actually outputs something useful to the console via System.out, you may want to instead print the debugging info to System.err
You should generally strive to have as much debugging as possible (ideally using some standard logger like log4j). This both eases debugging when you're actually developing the program AND allows for much easier debugging of already-released code in production. The benefit is that your code remains unchanged and you don't need to ADD debugf prints, yet by default the logging config can turn off the logging until it's actually needed (or at least turn down the level of logs)
As far as general simple "throw printlns at the wall" debugging, it can sometimes be one of the fastest ways to debug, though it should by no means be the only/main one.
Why can it be useful? Among other reasons, because running a Java program in a debugger may be much slower than outside of it; or because your bug manifests in an environment/situation that can't be easily replicated in your Eclipse debugger.
If the debugging print lines are not going to stay in the code after you've fixed your bug, then do whatever is easiest for you. Lambert's advice of using System.err.println() is a good idea since you can differentiate it from other output that your program may produce. If the debugging print lines are going to stay in your code, then I would advise on using a logging framework like log4j. This way you can dial up or down the level of output based on whether you're trying to debug something or just running in production. Be sure to output things at the right level when using log4j. Don't just log everything at INFO.
I use System.out.println for my debugging in case i have a problem or to inform me that methods have started to make sure everything has worked properly but when I publish the program I always remove it because it slows down the program.

java runtime tracing library to replace system.out.println

Have you heard of any library which would allow me to set up tracing for specific methods at runtime?
Instead of adding (and removing) lots of System.out.println in my code (and having to re-compile and re-deploy) I would like to have a magic thing which would print out a line for each call of selected method without any change in the code. This would work without re-compiling, so some kind of JVM agent (or some non-standard JVM would be needed?). Sounds like a job for aspect programming?
A typical scenario would be to start an application, configure the traced methods dynamically (in a separate file or similar) and then everytime a selected method is called a line with its name (and arguments) is printed out to System.out (or some log file).
Naturally one could think of tens of additional features, but this basic set would be a great tool. BTW, I use Eclipse interactive debugger too, not only the System.out tracing technique, but both have some advantages and sometimes Eclipse is not enough.
Yes what you are referring to is known as Aspect oriented programming. A typical library providing this for Java is AspectJ. You define what are called pointcuts, essentially regular expressions for classes and method names, including wildcards, and the code to execute at each pointcut, known as an advice. This is useful for logging and also security checks and similar cross cutting concerns.
You can turn pointcut advices on and off through configuration. You can have an advice execute before a method call, after it returns or even after it throws an exception. Arguments are also available.
An aspectj java agent is needed for this to work.
In my experience, that kind of very detailed tracing (much more detailed than one would normally use for logging) as a debugging technique is indicative of insufficient unit testing and integration testing.
You can do this using a tool called InTrace.
NOTE: InTrace is a free and open source tool which I have written.
Log4J useful for disabling logging depending on "log-level" (DEBUG, INFO, WARN, FATAL).
You specify in configuration file what the least level you want to appear in logs, e.g., don't log anything below INFO level, and voila!
Looks like there's yet another solution - called Byteman. In their own words:
Byteman is a tool which simplifies tracing and testing of Java
programs. Byteman allows you to insert extra Java code into your
application, either as it is loaded during JVM startup or even after
it has already started running. The injected code is allowed to access
any of your data and call any application methods, including where
they are private. You can inject code almost anywhere you want and
there is no need to prepare the original source code in advance nor do
you have to recompile, repackage or redeploy your application. In fact
you can remove injected code and reinstall different code while the
application continues to execute.
Jackplay is the tool you are looking for.
It allows you to enable logging on method entry and exit points without any coding or redeployment.
It also allows redefining a method body. It gives you web based UI as control panel to enable or undo tracing on your class.methods.

General debugging log practices

Due to recent events, i am trying to figure out how much debugging logs i should use for code in general.
What i have been doing is using debugging logs pretty sparingly, and just in cases where i wanted some extra information or what have you. This made sense to me, as it seems like you shouldn't log every little thing your code does, as that could make flood you with so much information that it would be easier to miss something that was actually important (or go crazy from digging through and verifying logs).
On the other hand, i present an example: I just started using logback/slf4j for my java project, and to test that i had the .xlm file set up correctly i added a debugging log statement to the end of a method that initializes gui components. Normally i would have never put a log statement there, because it is pretty obvious if your gui components don't initialize correctly when you run the program. However this time i ran the program, and low and behold the logs showed that the gui components were being initialized twice, even though only one set of them were being displayed. A decent sized bug, but something i likely wouldn't have caught without without those debugging statements.
So my question: Is there any "best practices" out there when it comes to debugging logs? I have seen many best practice questions when it comes to info logs, exceptions, errors, etc, but haven't found much out there in regards to debugging logs.
Thanks :)
Some thoughts:
Don't just log what's happening, but take care to log the available parameters/method arguments etc. It's easy to overlook this.
It's easy to disable debug logging via configuration rather than logging in after the fact.
Don't worry about logging overhead until it really becomes an issue.
You can automate some logging (entry/exit of methods) by using an AOP framework (Spring / AspectJ etc.)
I don't think there are any "best practices" in deciding what / how much to log. It is one of those catch-22 situations. If you need to look at the logs, there is "never" enough information there, but if you don't then "all" logging is just code clutter and an unnecessary runtime overhead. You need to make a separate judgement about where to draw the line for each application.
One point to bear in mind though. If you and your customers are able to hack the code to add temporary debugging statements, then you don't need as much permanent logging code in place. But if you don't have the option of hacking on the (almost) production code to debug things, then you need a certain level of logging code in place, just in case ...

Categories

Resources