Same idea than Nicholas. You can use Spring AOP to do that.
I like working with annotation, so that the logic is specified in the source code, not in the aspect's advice.
Define an annotation
package aop;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Traceable {}
Define the aspect
package aop;
@Aspect
public class TraceableAspect {
private final static AtomicLong Count = new AtomicLong(0);
@Around("execution(* *(..)) && @annotation(aop.Traceable)")
public Object aroundTraceableMethod(ProceedingJoinPoint pjp) throws Throwable {
Logger logger = LoggerFactory.getLogger(pjp.getTarget().getClass());
if (logger.isTraceEnabled()) {
return executeWithTrace(pjp, logger, Count.incrementAndGet());
}
return pjp.proceed();
}
private Object executeWithTrace(ProceedingJoinPoint pjp, Logger logger, long id) throws Throwable {
long start = System.currentTimeMillis();
try {
logger.trace(String.format("#### - #%d - Starting execution of method '%s'", id, pjp.toShortString()));
return pjp.proceed();
} catch (Throwable throwable) {
logger.error(String.format("#### - #%d - Error while executing method '%s' : %s", id, pjp.toShortString(), throwable.toString()));
throw throwable;
} finally {
if (logger.isTraceEnabled()) {
logger.trace(String.format("#### - #%d - End of method '%s' (duration %s ms)", id, pjp.toShortString(), (System.currentTimeMillis() - start)));
}
}
}
}
Use the aspect in Spring Boot project
package project;
@Profile("with-trace-aop")
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class SecToolWebApplicationTraceableAspect extends aop.TraceableAspect {
@PostConstruct
public void init(){
Logger logger = LoggerFactory.getLogger(this.getClass());
logger.warn("###-AOP-### TraceableAspect initialized for this application");
}
}
**Trace method in a controller
package project;
@RestController
public class ModelController {
@Traceable
@RequestMapping(method = RequestMethod.GET, value = "/{date}")
@ResponseBody
public <Collection<TE> find(@PathVariable @DateTimeFormat(pattern = DateUtils.DATE_FORMAT) Date date) {
...
}
}
IMPORTANT when a class is linked to an advice, all "final" methods are no more called. It is important to not use "final"
So, assuming the TRACE mode log is enabled, each call of the method "find" would be traced
Pay attention to this does not work if the