Skip to content

Instantly share code, notes, and snippets.

@MdGolam-Kibria
Created October 6, 2024 08:20
Show Gist options
  • Save MdGolam-Kibria/d3a7023084f9fcaa0297ded37852c508 to your computer and use it in GitHub Desktop.
Save MdGolam-Kibria/d3a7023084f9fcaa0297ded37852c508 to your computer and use it in GitHub Desktop.
Request Response Details log globally using AOP including request served time calculation.
package com.bbl.corpnet.api.aspect;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
@Aspect
@Component
public class ReqResLoggingAspect {
private final Logger LOGGER = LoggerFactory.getLogger(this.getClass().getName());
private final HttpServletRequest httpServletRequest;
public ReqResLoggingAspect(HttpServletRequest httpServletRequest) {
this.httpServletRequest = httpServletRequest;
}
@Pointcut("within(com.bbl.corpnet.api..*) && (" +
"@annotation(org.springframework.web.bind.annotation.PostMapping) ||" +
"@annotation(org.springframework.web.bind.annotation.GetMapping) ||" +
"@annotation(org.springframework.web.bind.annotation.PutMapping) ||" +
"@annotation(org.springframework.web.bind.annotation.DeleteMapping) ||" +
"@annotation(org.springframework.web.bind.annotation.PatchMapping))")
public void httpMethods() {
}
@Pointcut("within(com.bbl.corpnet.api..*) && @annotation(org.springframework.web.bind.annotation.RequestMapping)")
public void requestMappingMethods() {
}
@Pointcut("!within(com.bbl.corpnet.api.common.HealthCheckController)")
public void excludeControllers() {
}
@AfterReturning(value = "(httpMethods() || requestMappingMethods()) && excludeControllers()", argNames = "p,returnValue", returning = "returnValue")
public void beforeHttpMethodExecution(JoinPoint p, Object returnValue) {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
try {
if (p.getArgs().length != 0) {
LOGGER.info("\n\n\n\n-------------------------------------------------------------------------REQUEST DETAILS START-------------------------------------------------------------------------\n\n\n");
LOGGER.info("\nRequest URL : {}\n" +
"Controller Location : {}\n",
httpServletRequest.getRequestURI(), p.getSignature());
for (int i = 0; i < p.getArgs().length; i++) {
MethodSignature methodSignature = (MethodSignature) p.getSignature();
String[] parameterNames = methodSignature.getParameterNames();
Object arg = p.getArgs()[i];
if (arg instanceof MultipartFile) {
MultipartFile file = (MultipartFile) arg;
loggingRequestedInfo(i, parameterNames, file.getOriginalFilename());
} else {
try {
loggingRequestedInfo(i, parameterNames, mapper.writeValueAsString(arg));
} catch (Exception jsonEx) {
LOGGER.info("\nParameter [{}] - Request Object parsing time error : {}\n",
i + 1,
jsonEx.getMessage());
}
}
}
LOGGER.info("\nResponse Object: {}\n", mapper.writeValueAsString(returnValue));
LOGGER.info("-------------------------------------------------------------------------REQUEST DETAILS END-------------------------------------------------------------------------\n\n\n\n");
}
} catch (Exception e) {
LOGGER.error("Error processing request/response objects: {}", e.getMessage(), e);
}
}
@Around("@annotation(com.bbl.corpnet.api.annotation.LogExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed();
long executionTime = System.currentTimeMillis() - start;
LOGGER.info("{} executed in {} ms", joinPoint.getSignature(), executionTime);
return proceed;
}
private void loggingRequestedInfo(int i, String[] parameterNames, String file) {
LOGGER.info("\n" +
"Request parameter : [{}]\n" +
"Param Name : [{}]\n" +
"Param Value : {}\n",
i + 1,
parameterNames.length > 0 ? parameterNames[i] : "",
file);
}
}
@MdGolam-Kibria
Copy link
Author

Suggestions for improvement are appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment