We are running are a series JAX-WS webservices and I'm currently trying to improve the applications logging.
I am currently failing to find a way to capture Runtime exceptions so they can be logged with stacktrace etc. With the hope that we don't have to have to wrap each of our functions in a try/catch to facilitate the logging.
It appeared that the web service handlers are too late.
It feels like this should be well tread ground but my googling is not feeding me the results I need.
Has anyone got any ideas about how best to achieve this, feeling stuck.
Thanks,
Jon
You can try AOP here .
Create a #annotation and make that particular annotation as an pointcut in AOP. And write around function so that you can log whatever you want around the execution.
The only thing you have to do is to provide annotation to the function.
You can check this : https://www.baeldung.com/spring-aop-annotation
Related
I use KafkaBolt in Storm to publish messages to various Kafka topics. I want to put logging and metrics around the publishing logic so I can create alerts around any exceptions that might be thrown when there's a publishing failure. Exposing those exceptions is done through a Callback function that's passed into KafkaProducer.send(), which is executed after publishing succeeds or fails.
The problem is that KafkaBolt completely encapsulates its KafkaProducer so there's no way to inject a custom Callback, so if I want to see any errors I have to look in the Storm UI. I've worked around this by creating a wrapper for KafkaBolt. This wrapper will, in turn, wrap the OutputCollector passed into KafkaBolt.prepare() in a custom OutputCollector that overrides the behavior of OutputCollector.reportError(). I can then add my own logging and metrics reporting code there and then have it call the original method.
This solution seems perfectly adequate for what I need, but it seems odd that KafkaBolt makes it so difficult to programmatically access those exceptions. I was wondering if maybe I was missing something obvious and if there was a better way to do this.
I don't think you're missing anything, you're likely just the first person with this need. Someone has to hit this issue and decide to fix it :)
If you'd like to make changes to the bolt to support custom error handling (e.g. by allowing the user to provide a callback as you suggest), you can raise an issue at https://issues.apache.org/jira/projects/STORM/issues and make a PR against https://github.com/apache/storm/pulls. You're of course also welcome to only raise the issue, someone else might see it and decide to fix it, but contributing the fix yourself would likely be faster.
edit: You can find the bolt code at https://github.com/apache/storm/blob/master/external/storm-kafka-client/src/main/java/org/apache/storm/kafka/bolt/KafkaBolt.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.
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
Say you have an application with a series of actions. How would you write it such that actions are logged when they are triggered?
Use a Template pattern.
Use AOP.
Use a Listener and Events.
Use a combination of the above.
Something else (explain).
I'd vote for AOP for the sake of eliminating redundancy, but only if there's room for AOP in your project.
You can have custom logging using a logging library from your methods elsewhere in your project, but in a particular component where you hold many similar classes and want to log similar things for all of them, it can be painful to copy/paste and make sure everyone knows how to log.
EDIT: regarding the other enumerated approaches, I think the advantage of AOP would be that it doesn't require you to design your code (template methods or events) specifically for this topic. You usually don't lose any of the code flexibility when spotting cross-cutting concerns and treating them as such, as opposed to redesigning a whole class hierarchy just to make use of consistent logging.
I think the best answer is using log4j (or sli4j, if that's the latest) inside an aspect.
Logging is the "hello world" of AOP. If you aren't using AOP, you're doing it wrong.
It really would depend on your specific context. Specifically on what was being tracked and how the application currently worked. If the actions are classes that all have a common base class and all you care about is the name of the action, then a simple addition to log in this class would be a great choice. If you have actions spread across several layers of code, then an AOP or Listener/Event type solution might work better. If that application was a web app vs desktop or if you ultimately need the logs feed to a database, webservice, or just want text files all make a difference.
if you simply want to log particular actions it's probably simplest to use a logging api such as commons-logging or log4j etc add a log statement in the code you wish to track.
I'm working on modifying an existing application implemented as a 2.1 stateless EJB. I'd like to put in some kind of generic, detailed, logging of all calls made to the EJB.
Stuff I'd like to log:
Name of method being called
Serialized copy of all passed parameters
Serialized copy of return value
I implemented something like that for an asp.net REST web service before by simply putting in a hook before the request is processed and one right before the response is sent back. It produces a lot of data, but it's well worth it for debugging a long running system.
I'm not sure how the same can be done for an EJB. I'd like to avoid AOP since the application doesn't currently use AOP. Interceptors won't work because it's not EJB 3.0.
Does anyone know of a way to hook into the EJB processing pipeline to look at request as they come in? Is there another approach to doing this?
Thanks
I think there are only two ways two ways to know when a method of an EJB (or any other class) is called:
Bad solution: using the Java Debug Interface (JDI) you can know which line is executed, as you know it when you are debugging Java with your IDE. It's complicated and there are some problems when you are debugging an application in the same JVM where JDI runs.
Good solution: as Thomas Owens says, AOP is the recommended solution. If you are not using it in your project now, this is a good reason for using it.