连接点调用如何唯一存储?

时间:2018-03-09 03:26:32

标签: java spring aop aspectj

我有一个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()

1 个答案:

答案 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();

我知道这并不是你提出的要求,但希望你能找到一些有用的东西来满足你的需求。