简体   繁体   中英

Aspectj (with spring) - logging throw of an exception only once on the throwing method without the propagated methods

We just implemented a logging aspect for all of our services methods. We Implemented exception throwing logging as well.

Problem is if we have the following scenario:

ClassA.method1 calls ClassB.method2 calls ClassC.method3 and method3 throws an exception.

What happens now is - we got a logging of the exception throwing in method3 AND method2 AND method1. (the excpetion is propagated and therefore rethrown from each)

How can we achieve that my aspect will handle only the last method throwing the exception (method3)?

Thanks!

Similar solution was described in AspectJ in Action. There's lots of things that might be implemented like logging of method name, arguments etc, but for simplicity sake :

public aspect ExceptionAspect {
    private Log log = Logger.getLogger("error_log");
    private Exception exception;

    pointcut exceptionPointcut() : execution(* my.package..*(..));

    after() throwing(Exception ex) : exceptionPointcut() {
        if (exception != ex) {
            exception = ex;
            log.error("ERROR: {}", ex);
        }
    }
}

A solution could be to store a reference of the throwable object in the handler class in which intercept methods to log. A good data structure for holding these references can be WeakSet , something like below:

Set<Throwable> throwableRecord = Collections.newSetFromMap(new WeakHashMap<>());

In the case of an occurring exception, at first, the handler checks whether the exception exists in the set or not. If not, the throwable object is added to the set and is also logged. If it exists, simply ignore the exception since it is a propagated exception, and we are sure that we logged it before.

if (throwableRecord.contains(throwable)) {
    //dont't log
    //the exception is logged before
}
throwableRecord.add(throwable);
//log the exception

The benefit of using WeakSet is that, whenever the throwable object is garbaged by gc, its related entry is automatically removed from the set.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM