How do you track the entry and exit of all functions in a Spring based web application?

In the Spring web-based web application project, I am now, the developers have written two registration statements in each function. One registers a record in a function, and the other registers an output. The idea is to trace the path of execution - at least the level of the function.

Is there a way to do this without clogging the entire code base with these duplicate statements?

To be clear, we want to register all the functions, not just the publicly available Spring beans methods.

+4
source share
2 answers

You can do this with Spring AOP .

Spring AOP will allow you to “intercept” method calls and execute arbitrary code before and / or after a method call. You can also view the parameters and return the values ​​of these methods.

In order to get the journal you are talking about, you would do something similar, probably using around the tip :

  • Intercept all method calls (or, preferably, only those that interest you).
  • Log before the method.
  • Call the method.
  • Post-method logging.

All Spring's information on how to do this can be found in the attached documentation.

+3
source

Same idea as Nicholas. You can use Spring AOP for this.

I like working with annotations, so the logic is in the source code, not in the aspect advice.

Define Annotation

package aop; @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Traceable {} 

Define 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 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 the 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 associated with advice, all the “final” methods are no longer called. It’s important not to use the “final”

So, if TRACE log mode is enabled, every call to the find method will be traced

Please note that this does not work if

0
source

Source: https://habr.com/ru/post/1368993/


All Articles