elastic/apm-agent-java

Improve docs and add error log related to illegal activation of transaction

开放

#850 创建于 2019年9月18日

 (3 条评论) (1 个反应) (0 位负责人)Java (332 个派生)auto 404
docsgood first issue

仓库指标

星标
 (592 个星标)
PR 合并指标
 (PR 指标待抓取)

描述

Using multiple nested transactions, ElasticApm.currentTransaction() returns oldest transaction instead of newest created.

Activating a transaction transaction.activate() pushes the transaction to the head of the active stack: ElasticApmTracer.java:

    public void activate(TraceContextHolder<?> holder) {
        if (logger.isDebugEnabled()) {
            logger.debug("Activating {} on thread {}", holder, Thread.currentThread().getId());
        }

        ((Deque)this.activeStack.get()).push(holder);
    }

But when retrieving it, the last element of the stack is checked: ElasticApmTracer.java:

  public Transaction currentTransaction() {
        TraceContextHolder<?> bottomOfStack = (TraceContextHolder)((Deque)this.activeStack.get()).peekLast();
        if (bottomOfStack instanceof Transaction) {
            return (Transaction)bottomOfStack;
       ....................

In the above method, peekLast() returns the oldest transaction instead of newly pushed one.

As multiple methods use Deque::peek(first element) to get active transaction, the logic inside currentTransaction() method should be change to iterate from first to last element:

     @Nullable
     public Transaction currentTransaction() {
-        TraceContextHolder<?> bottomOfStack = (TraceContextHolder)((Deque)this.activeStack.get()).peekLast();
+        TraceContextHolder<?> bottomOfStack = (TraceContextHolder)((Deque)this.activeStack.get()).peek();
         if (bottomOfStack instanceof Transaction) {
             return (Transaction)bottomOfStack;
         } else {
-            Iterator it = ((Deque)this.activeStack.get()).descendingIterator();
+            Iterator it = ((Deque)this.activeStack.get()).iterator();

             TraceContextHolder context;
             do {

elastic-apm-agent-1.9.0

贡献者指南