Spring 引导@Aspect 日志记录
Spring Boot @Aspect Logging
我尝试使用@Aspect 来记录所有请求和响应。如果我的端点有@RequestBody,我的代码可以正常工作,但我的获取端点没有@RequestBody,我看不到日志。对这种情况有什么解释吗?
我的class就是这样;
@Aspect
@Component
@Slf4j
@RequiredArgsConstructor(onConstructor = @__({@Autowired, @NotNull}))
public class AspectLogging {
private final ObjectMapper objectMapper;
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping)")
public void annotationPointCutDefinition() {
}
@Pointcut("execution(* *(com.dux.secondwallet.api.v3.pay.merchant.*))")
public void atExecution() {
}
@Before("annotationPointCutDefinition() && atExecution()")
public void endpointBefore(JoinPoint p) {
Object[] signatureArgs = p.getArgs();
if (Objects.nonNull(signatureArgs) && signatureArgs.length > 0) {
log.info("Request object: " + signatureArgs[0]);
}
}
@AfterReturning(pointcut = "annotationPointCutDefinition() && atExecution()", returning = "returnValue")
public void endpointAfterReturning(Object returnValue) {
try {
log.info("Response object:" + objectMapper.writeValueAsString(returnValue));
} catch (JsonProcessingException e) {
log.error(e.getMessage(), e);
}
}
@AfterThrowing(pointcut = "annotationPointCutDefinition() && atExecution()", throwing = "e")
public void endpointAfterThrowing(JoinPoint p, Exception e) throws Exception {
e.printStackTrace();
log.error(p.getTarget().getClass().getSimpleName() + " " + p.getSignature().getName() + " " + e.getMessage());
}
}
示例控制器; getRequest 方法不记录,postRequest 记录。
@Slf4j
@RestController
@RequestMapping("/v3/")
public class MyController {
@GetMapping("/balances")//not before and after logging
public List<java.lang.String> getRequest() {
return Collections.singletonList("TEST");
}
@PostMapping("/limits")//its logging
public TransactionLimitResponse postRequest(@Valid @RequestBody TransactionLimitRequest transactionLimitRequest) {
return TransactionLimitResponse.builder()
.currency("EUR")
.type("TYPE")
.min(100)
.max(1000)
.build();
}
}
您的切入点定义不正确。使用 @Pointcut("execution(* com.dux.secondwallet.api.v3.pay.merchant.*.*(..))")
切入点将匹配定义包下 classes 中的所有方法。
提示
除此之外,您应该使用 @Configuration
作为 Aspect-Configuration class 而不是 @Component
。此外,通过在实例字段上使用 @NonNull
,您可以跳过 @RequiredArgsConstructor
配置。
首先我想问一下你要记录什么?
您的方面代码的目的是记录方法参数,并且您在@GetMapping 方法上没有任何参数。
所以你的方面方法也为@GetMapping 成功触发。但只需检查条件并通过它。看不到日志很正常
应用下面的更改将起作用:
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
//@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping))")
public void getMapping() {
}
@Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
//@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping))")
public void postMapping() {
}
@Pointcut("execution(* *(..)) && within(com.dux.secondwallet.api.v3.pay.merchant.*))")
public void atExecution() {
}
@Before("(getMapping() || postMapping()) && atExecution()")
public void endpointBefore(JoinPoint p) {
log.info("ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss");
Object[] signatureArgs = p.getArgs();
if (Objects.nonNull(signatureArgs) && signatureArgs.length > 0) {
log.info("Request object: " + signatureArgs[0]);
}else{
log.info("log for get");
}
}
execution(* *(..))
: 这是你的方法签名。
within(com.dux.secondwallet.api.v3.pay.merchant.*)
这是包裹限制。
我尝试使用@Aspect 来记录所有请求和响应。如果我的端点有@RequestBody,我的代码可以正常工作,但我的获取端点没有@RequestBody,我看不到日志。对这种情况有什么解释吗?
我的class就是这样;
@Aspect
@Component
@Slf4j
@RequiredArgsConstructor(onConstructor = @__({@Autowired, @NotNull}))
public class AspectLogging {
private final ObjectMapper objectMapper;
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping)")
public void annotationPointCutDefinition() {
}
@Pointcut("execution(* *(com.dux.secondwallet.api.v3.pay.merchant.*))")
public void atExecution() {
}
@Before("annotationPointCutDefinition() && atExecution()")
public void endpointBefore(JoinPoint p) {
Object[] signatureArgs = p.getArgs();
if (Objects.nonNull(signatureArgs) && signatureArgs.length > 0) {
log.info("Request object: " + signatureArgs[0]);
}
}
@AfterReturning(pointcut = "annotationPointCutDefinition() && atExecution()", returning = "returnValue")
public void endpointAfterReturning(Object returnValue) {
try {
log.info("Response object:" + objectMapper.writeValueAsString(returnValue));
} catch (JsonProcessingException e) {
log.error(e.getMessage(), e);
}
}
@AfterThrowing(pointcut = "annotationPointCutDefinition() && atExecution()", throwing = "e")
public void endpointAfterThrowing(JoinPoint p, Exception e) throws Exception {
e.printStackTrace();
log.error(p.getTarget().getClass().getSimpleName() + " " + p.getSignature().getName() + " " + e.getMessage());
}
}
示例控制器; getRequest 方法不记录,postRequest 记录。
@Slf4j
@RestController
@RequestMapping("/v3/")
public class MyController {
@GetMapping("/balances")//not before and after logging
public List<java.lang.String> getRequest() {
return Collections.singletonList("TEST");
}
@PostMapping("/limits")//its logging
public TransactionLimitResponse postRequest(@Valid @RequestBody TransactionLimitRequest transactionLimitRequest) {
return TransactionLimitResponse.builder()
.currency("EUR")
.type("TYPE")
.min(100)
.max(1000)
.build();
}
}
您的切入点定义不正确。使用 @Pointcut("execution(* com.dux.secondwallet.api.v3.pay.merchant.*.*(..))")
切入点将匹配定义包下 classes 中的所有方法。
提示
除此之外,您应该使用 @Configuration
作为 Aspect-Configuration class 而不是 @Component
。此外,通过在实例字段上使用 @NonNull
,您可以跳过 @RequiredArgsConstructor
配置。
首先我想问一下你要记录什么?
您的方面代码的目的是记录方法参数,并且您在@GetMapping 方法上没有任何参数。
所以你的方面方法也为@GetMapping 成功触发。但只需检查条件并通过它。看不到日志很正常
应用下面的更改将起作用:
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
//@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping))")
public void getMapping() {
}
@Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
//@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping))")
public void postMapping() {
}
@Pointcut("execution(* *(..)) && within(com.dux.secondwallet.api.v3.pay.merchant.*))")
public void atExecution() {
}
@Before("(getMapping() || postMapping()) && atExecution()")
public void endpointBefore(JoinPoint p) {
log.info("ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss");
Object[] signatureArgs = p.getArgs();
if (Objects.nonNull(signatureArgs) && signatureArgs.length > 0) {
log.info("Request object: " + signatureArgs[0]);
}else{
log.info("log for get");
}
}
execution(* *(..))
: 这是你的方法签名。
within(com.dux.secondwallet.api.v3.pay.merchant.*)
这是包裹限制。