是否可以通过 aspect 在日志中 "impersonate" a class?
Is it possible to "impersonate" a class in logging via aspect?
我开发了一个方面,当我使用标准格式进入和退出 class 时,它会记录下来 class,所以类似于:
2020-03-20 20:05:30.280 INFO 3336 --- [nio-8080-exec-2] c.a.common.aop.LoggingAspect : Entering method
请注意日志 class 似乎是 "LoggingAspect"。相反,是否可以记录代理的 class 名称?
目前我得到:
2020-03-20 20:05:30.280 INFO 3336 --- [nio-8080-exec-2] c.a.common.aop.LoggingAspect : Entering method
2020-03-20 20:06:30.280 INFO 3336 --- [nio-8080-exec-2] c.a.my.proxied.Class : Doing stuff
2020-03-20 20:05:30.280 INFO 3336 --- [nio-8080-exec-2] c.a.common.aop.LoggingAspect : Exiting method
我希望每一行总是 c.a.my.proxied.Class
。
这是我的方面:
@Aspect
@Order(1)
@Component
@Slf4j
public class LoggingAspect {
@Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
private void controllerInvocation() {}
@Around("controllerInvocation()")
public Object logEntering(ProceedingJoinPoint joinPoint) throws Throwable{
log.info("Entering method");
Object res = joinPoint.proceed();
log.info("Exiting method");
return res;
}
}
来自注释文档 @Slf4j
@Slf4j
public class LogExample {}
将生成:
public class LogExample {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
}
这意味着通过使用 log
引用,在代码共享中它总是用于 LoggingAspect
。
解决方法如下
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
// ...
@Around("controllerInvocation()")
public Object logEntering(ProceedingJoinPoint joinPoint) throws Throwable {
// Get the logger for the class of intercepted method
Logger logz = getLogger(joinPoint.getTarget().getClass());
logz.info("Entering method");
Object res = joinPoint.proceed();
logz.info("Exiting method");
return res;
}
希望对您有所帮助
编辑:OP 要求@kriegaex 提供他建议的示例。我冒昧地说明他的建议。
请参阅文档中的 aop 示例 section 以获取更多详细信息
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
// ...
@Around("controllerInvocation() && target(myTarget)")
public Object logEntering(ProceedingJoinPoint joinPoint,Object myTarget) throws Throwable {
// Get the logger for the class of intercepted method
Logger logz = getLogger(myTarget.getClass());
logz.info("Entering method");
try{
Object res = joinPoint.proceed();
}finally{
logz.info("Exiting method");
}
return res;
}
我开发了一个方面,当我使用标准格式进入和退出 class 时,它会记录下来 class,所以类似于:
2020-03-20 20:05:30.280 INFO 3336 --- [nio-8080-exec-2] c.a.common.aop.LoggingAspect : Entering method
请注意日志 class 似乎是 "LoggingAspect"。相反,是否可以记录代理的 class 名称? 目前我得到:
2020-03-20 20:05:30.280 INFO 3336 --- [nio-8080-exec-2] c.a.common.aop.LoggingAspect : Entering method
2020-03-20 20:06:30.280 INFO 3336 --- [nio-8080-exec-2] c.a.my.proxied.Class : Doing stuff
2020-03-20 20:05:30.280 INFO 3336 --- [nio-8080-exec-2] c.a.common.aop.LoggingAspect : Exiting method
我希望每一行总是 c.a.my.proxied.Class
。
这是我的方面:
@Aspect
@Order(1)
@Component
@Slf4j
public class LoggingAspect {
@Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
private void controllerInvocation() {}
@Around("controllerInvocation()")
public Object logEntering(ProceedingJoinPoint joinPoint) throws Throwable{
log.info("Entering method");
Object res = joinPoint.proceed();
log.info("Exiting method");
return res;
}
}
来自注释文档 @Slf4j
@Slf4j
public class LogExample {}
将生成:
public class LogExample {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
}
这意味着通过使用 log
引用,在代码共享中它总是用于 LoggingAspect
。
解决方法如下
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
// ...
@Around("controllerInvocation()")
public Object logEntering(ProceedingJoinPoint joinPoint) throws Throwable {
// Get the logger for the class of intercepted method
Logger logz = getLogger(joinPoint.getTarget().getClass());
logz.info("Entering method");
Object res = joinPoint.proceed();
logz.info("Exiting method");
return res;
}
希望对您有所帮助
编辑:OP 要求@kriegaex 提供他建议的示例。我冒昧地说明他的建议。
请参阅文档中的 aop 示例 section 以获取更多详细信息
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
// ...
@Around("controllerInvocation() && target(myTarget)")
public Object logEntering(ProceedingJoinPoint joinPoint,Object myTarget) throws Throwable {
// Get the logger for the class of intercepted method
Logger logz = getLogger(myTarget.getClass());
logz.info("Entering method");
try{
Object res = joinPoint.proceed();
}finally{
logz.info("Exiting method");
}
return res;
}