package com.pollex.pam.aop.logging;
|
|
import java.util.Arrays;
|
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.annotation.AfterThrowing;
|
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Pointcut;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Profiles;
|
import tech.jhipster.config.JHipsterConstants;
|
|
/**
|
* Aspect for logging execution of service and repository Spring components.
|
*
|
* By default, it only runs with the "dev" profile.
|
*/
|
@Aspect
|
public class LoggingAspect {
|
|
private final Environment env;
|
|
public LoggingAspect(Environment env) {
|
this.env = env;
|
}
|
|
/**
|
* Pointcut that matches all repositories, services and Web REST endpoints.
|
*/
|
@Pointcut(
|
"within(@org.springframework.stereotype.Repository *)" +
|
" || within(@org.springframework.stereotype.Service *)" +
|
" || within(@org.springframework.web.bind.annotation.RestController *)"
|
)
|
public void springBeanPointcut() {
|
// Method is empty as this is just a Pointcut, the implementations are in the advices.
|
}
|
|
/**
|
* Pointcut that matches all Spring beans in the application's main packages.
|
*/
|
@Pointcut("within(com.pollex.pam.business.repository..*)" + " || within(com.pollex.pam.business.service..*)" + " || within(com.pollex.pam.web.rest..*)")
|
public void applicationPackagePointcut() {
|
// Method is empty as this is just a Pointcut, the implementations are in the advices.
|
}
|
|
/**
|
* Retrieves the {@link Logger} associated to the given {@link JoinPoint}.
|
*
|
* @param joinPoint join point we want the logger for.
|
* @return {@link Logger} associated to the given {@link JoinPoint}.
|
*/
|
private Logger logger(JoinPoint joinPoint) {
|
return LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringTypeName());
|
}
|
|
/**
|
* Advice that logs methods throwing exceptions.
|
*
|
* @param joinPoint join point for advice.
|
* @param e exception.
|
*/
|
@AfterThrowing(pointcut = "applicationPackagePointcut() && springBeanPointcut()", throwing = "e")
|
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
|
if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT))) {
|
logger(joinPoint)
|
.error(
|
"Exception in {}() with cause = '{}' and exception = '{}'",
|
joinPoint.getSignature().getName(),
|
e.getCause() != null ? e.getCause() : "NULL",
|
e.getMessage(),
|
e
|
);
|
} else {
|
logger(joinPoint)
|
.error(
|
"Exception in {}() with cause = {}",
|
joinPoint.getSignature().getName(),
|
e.getCause() != null ? e.getCause() : "NULL"
|
);
|
}
|
}
|
|
/**
|
* Advice that logs when a method is entered and exited.
|
*
|
* @param joinPoint join point for advice.
|
* @return result.
|
* @throws Throwable throws {@link IllegalArgumentException}.
|
*/
|
@Around("applicationPackagePointcut() && springBeanPointcut()")
|
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
Logger log = logger(joinPoint);
|
if (log.isDebugEnabled()) {
|
log.debug("Enter: {}() with argument[s] = {}", joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));
|
}
|
try {
|
Object result = joinPoint.proceed();
|
if (log.isDebugEnabled()) {
|
if(!(result instanceof byte[])){
|
log.debug("Exit: {}() with result = {}", joinPoint.getSignature().getName(), result);
|
}
|
}
|
return result;
|
} catch (IllegalArgumentException e) {
|
log.error("Illegal argument: {} in {}()", Arrays.toString(joinPoint.getArgs()), joinPoint.getSignature().getName());
|
throw e;
|
}
|
}
|
}
|