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

貢獻者指南