我有一个dataframe
Aspect,可以记录并调用方法。例如,
AspectJ
这会记录
之类的消息@Aspect
public class MyRetryAspect{
@Around("@annotation(path.to.an.annotation)")
public Object logAndRetryServiceCall(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("Calling method", joinPoint.getCallSignature.toShortString())
return joinPoint.proceed();
}
当流量繁忙时,有几项服务可以拨打INFO c.b.n.e.core.aop.SpringRetryAspect - Calling SomeClass.someMethod(..)
,我想区分和存储它们。通过这种方式,SomeClass.someMethod()
可以记录有关呼叫的更详细信息。例如,如果两个线程来回调用方面,则日志应表示这些是单独的调用方。类似的东西:
@Aspect
这是设计的,但说明了日志可以区分具有不同参数的调用的想法。在实践中,我记录了重试尝试,因此如果两个线程正在重试相同的服务调用,我们希望在日志中区分和跟踪它们,例如
INFO c.b.n.e.core.aop.SpringRetryAspect - Calling SomeClass.someMethod(Object@3233)
INFO c.b.n.e.core.aop.SpringRetryAspect - Calling SomeClass.someMethod(Object@3813)
最后,我的问题是,有没有办法将一个调用与另一个调用连接点区别开来?我最接近的是尝试将参数拉到 INFO c.b.n.e.core.aop.SpringRetryAspect - Calling SomeClass.someMethod(Object@3233) attempt (1 of 5)
INFO c.b.n.e.core.aop.SpringRetryAspect - Calling SomeClass.someMethod(Object@3813) attempt (3 of 5)
INFO c.b.n.e.core.aop.SpringRetryAspect - Calling SomeClass.someMethod(Object@3813) attempt (4 of 5)
INFO c.b.n.e.core.aop.SpringRetryAspect - Calling SomeClass.someMethod(Object@3233) attempt (2 of 5)
并拿出第一个参数并将它变成字符串...它真的很难看。 是否可以从joinPoint中提取任何可以区分一个来电者的独特信息?
someMethod()
答案 0 :(得分:0)
如果您在项目中使用log4j-api
,则可以使用课程ThreadContext
。
然后,您可以存储每个线程所需的任何信息。
例如,在开始调用方法之前:
ThreadContext.put("thread_id", new AlternativeJdkIdGenerator().generateId().toString());
ThreadContext.put("count_thread_executions", "0");
然后在Aspect
:
@Aspect
public class MyRetryAspect{
@Around("@annotation(path.to.an.annotation)")
public Object logAndRetryServiceCall(ProceedingJoinPoint joinPoint) throws Throwable {
ThreadContext.put("count_thread_executions", ((Integer) (Integer.parseInt(ThreadContext.get("count_thread_executions")) + 1)).toString());
String count_thread_executions = ThreadContext.get("count_thread_executions");
// Use count_thread_executions as needed
log.info("Calling method", joinPoint.getCallSignature.toShortString());
return joinPoint.proceed();
}
}
最后不要忘记在所有方法执行后清除ThreadContext
。
ThreadContext.clearAll();
我知道这并不是你提出的要求,但希望你能找到一些有用的东西来满足你的需求。