I have a series of micro services that hav controllers each controller has a method
@SneakyThrows
@PostMapping(value = "/getData", produces = { "application/json" })
public GetDataResponse getData(@RequestBody GetDataRequest data) {
}
I can add logging to each controller to get the same data as each controller is called.
@SneakyThrows
@PostMapping(value = "application/<controllerApplicationName>/getData", produces = { "application/json" })
public GetDataResponse getData(@RequestBody GetDataRequest data) {
log.info("From client " data.getClientId()
}
Is there a way to get springboot to handle this logging, so I dont need to add logging to each controller and new controller
CodePudding user response:
Yes there a way to do that, you can add Spring AOP to your project, AOP is a proxy mechanism which will intercept calls to methods in your spring managed classes. But it works on public methods only.
With this you don't need to write logging code in every method, for your whole application, a single class can work.
Here's a sample code to kickstart. (And do refer online for its tutorials)
package com.demo.survey.aop;
import javax.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
@Pointcut("execution(* com.demo.controllers.*.*(..))")
private void forControllerPackage() {}
@Pointcut("execution(* com.demo.serviceImpl.*.*(..))")
private void forServiceImplPackage() {}
@Pointcut("forControllerPackage() || forServiceImplPackage()")
private void applyPointCut() {}
// Will get called before your method gets executed
@Before("execution(* com.demo.controllers.demoController.addData(..)))")
public void beforeAddQuestion(JoinPoint jt) {
MethodSignature methodSig = (MethodSignature) jt.getSignature();
System.out.println("methodSig = " methodSig);
Object[] args = jt.getArgs();
for(Object tempArgs : args) {
System.out.println("tempArgs = " tempArgs);
}
}
// @Around:- This will get called before and after your method runs.
@Around("applyPointCut()")
public Object logExceptions(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object result = null;
//display Method Signature
MethodSignature methodSig = (MethodSignature) proceedingJoinPoint.getSignature();
try {
// execute the method
// do something before proceeding
System.out.println("methodSig = " methodSig);
Object[] args = proceedingJoinPoint.getArgs();
for(Object tempArgs : args) {
// Arguments which are being passed to method
System.out.println("tempArgs = " tempArgs);
}
result = proceedingJoinPoint.proceed();
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
}
// Here are the 2 dependencies that you will need
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
</dependency>
