public Scope activateInScope() { // already in scope if (tracer.getActive() == this) { return Scope.NoopScope.INSTANCE; } activate(); return new Scope() { @Override public void close() { deactivate(); } }; }
public T captureException(@Nullable Throwable t) { if (t != null) { captureException(getTraceContext().getClock().getEpochMicros(), t); } return (T) this; }
@Override public void close() { deactivate(); } };
@Test void testEnableDropSpans() { when(tracerImpl.getConfig(CoreConfiguration.class).getTransactionMaxSpans()).thenReturn(1); Transaction transaction = tracerImpl.startTransaction(); try (Scope scope = transaction.activateInScope()) { Span span = tracerImpl.getActive().createSpan(); try (Scope spanScope = span.activateInScope()) { assertThat(span.isSampled()).isTrue(); span.end(); } Span span2 = tracerImpl.getActive().createSpan(); try (Scope spanScope = span2.activateInScope()) { assertThat(span2.isSampled()).isFalse(); span2.end(); } transaction.end(); } assertThat(reporter.getFirstTransaction().isSampled()).isTrue(); assertThat(reporter.getFirstTransaction().getSpanCount().getDropped().get()).isEqualTo(1); assertThat(reporter.getFirstTransaction().getSpanCount().getStarted().get()).isEqualTo(1); assertThat(reporter.getSpans()).hasSize(1); }
public void activate(TraceContextHolder<?> holder) { if (logger.isDebugEnabled()) { logger.debug("Activating {} on thread {}", holder.getTraceContext(), Thread.currentThread().getId()); } activeStack.get().push(holder); }
@Test void testDisable() { when(config.getConfig(CoreConfiguration.class).isActive()).thenReturn(false); Transaction transaction = tracerImpl.startTransaction(); try (Scope scope = transaction.activateInScope()) { assertThat(tracerImpl.currentTransaction()).isSameAs(transaction); assertThat(transaction.isSampled()).isFalse(); Span span = tracerImpl.getActive().createSpan(); try (Scope spanScope = span.activateInScope()) { assertThat(tracerImpl.getActive()).isSameAs(span); assertThat(tracerImpl.getActive()).isNotNull(); } assertThat(tracerImpl.getActive()).isSameAs(transaction); transaction.end(); } assertThat(tracerImpl.currentTransaction()).isNull(); assertThat(reporter.getTransactions()).isEmpty(); assertThat(reporter.getSpans()).isEmpty(); }
/** * Wraps the provided {@link Runnable} and makes this {@link TraceContext} active in the {@link Runnable#run()} method. * * <p> * Note: does not activate the {@link AbstractSpan} but only the {@link TraceContext}. * This is useful if this span is closed in a different thread than the provided {@link Runnable} is executed in. * </p> */ public Runnable withActiveContext(Runnable runnable) { return tracer.wrapRunnable(runnable, getTraceContext()); }
@Advice.OnMethodEnter(suppress = Throwable.class) public static void onMethodEnter(@SimpleMethodSignatureOffsetMappingFactory.SimpleMethodSignature String signature, @Advice.Local("span") AbstractSpan<?> span) { if (tracer != null) { final TraceContextHolder<?> parent = tracer.getActive(); if (parent == null) { span = tracer.startTransaction() .withName(signature) .activate(); } else { span = parent.createSpan() .withName(signature) .activate(); } } }
/** * Wraps the provided {@link Callable} and makes this {@link TraceContext} active in the {@link Callable#call()} method. * * <p> * Note: does not activate the {@link AbstractSpan} but only the {@link TraceContext}. * This is useful if this span is closed in a different thread than the provided {@link java.util.concurrent.Callable} is executed in. * </p> */ public <V> Callable<V> withActiveContext(Callable<V> runnable) { return tracer.wrapCallable(runnable, getTraceContext()); }
@Test void testNestedSpan() { Transaction transaction = tracerImpl.startTransaction(); try (Scope scope = transaction.activateInScope()) { assertThat(tracerImpl.currentTransaction()).isSameAs(transaction); Span span = tracerImpl.getActive().createSpan(); try (Scope spanScope = span.activateInScope()) { assertThat(tracerImpl.getActive()).isSameAs(span); assertThat(span.isChildOf(transaction)).isTrue(); Span nestedSpan = tracerImpl.getActive().createSpan(); try (Scope nestedSpanScope = nestedSpan.activateInScope()) { assertThat(tracerImpl.getActive()).isSameAs(nestedSpan); assertThat(nestedSpan.isChildOf(span)).isTrue(); nestedSpan.end(); } span.end(); } assertThat(tracerImpl.getActive()).isEqualTo(transaction); transaction.end(); } assertThat(tracerImpl.currentTransaction()).isNull(); assertThat(reporter.getSpans()).hasSize(2); }
public void deactivate(TraceContextHolder<?> holder) { if (logger.isDebugEnabled()) { logger.debug("Deactivating {} on thread {}", holder.getTraceContext(), Thread.currentThread().getId()); } final Deque<TraceContextHolder<?>> stack = activeStack.get(); assertIsActive(holder, stack.poll()); if (holder == stack.peekLast()) { // if this is the bottom of the stack // clear to avoid potential leaks in case of wrong api usage // makes all leaked spans eligible for GC stack.clear(); } }
@Test void testDisableMidTransaction() { Transaction transaction = tracerImpl.startTransaction(); try (Scope scope = transaction.activateInScope()) { assertThat(tracerImpl.currentTransaction()).isSameAs(transaction); Span span = tracerImpl.getActive().createSpan(); try (Scope spanScope = span.activateInScope()) { when(config.getConfig(CoreConfiguration.class).isActive()).thenReturn(false); span.withName("test"); assertThat(span.getName().toString()).isEqualTo("test"); assertThat(tracerImpl.getActive()).isSameAs(span); assertThat(span.isChildOf(transaction)).isTrue(); span.end(); } Span span2 = tracerImpl.getActive().createSpan(); try (Scope spanScope = span2.activateInScope()) { when(config.getConfig(CoreConfiguration.class).isActive()).thenReturn(false); span2.withName("test2"); assertThat(span2.getName().toString()).isEqualTo("test2"); assertThat(tracerImpl.getActive()).isSameAs(span2); assertThat(span2.isChildOf(transaction)).isTrue(); span2.end(); } assertThat(tracerImpl.getActive()).isEqualTo(transaction); transaction.end(); } assertThat(tracerImpl.currentTransaction()).isNull(); assertThat(reporter.getSpans()).hasSize(2); assertThat(reporter.getFirstTransaction()).isSameAs(transaction); }
public boolean isSampled() { return getTraceContext().isSampled(); }
@Test void testEnableStacktraces() throws InterruptedException { when(tracerImpl.getConfig(StacktraceConfiguration.class).getSpanFramesMinDurationMs()).thenReturn(-1L); Transaction transaction = tracerImpl.startTransaction(); try (Scope scope = transaction.activateInScope()) { Span span = tracerImpl.getActive().createSpan(); try (Scope spanScope = span.activateInScope()) { Thread.sleep(10); span.end(); } transaction.end(); } assertThat(reporter.getFirstSpan().getStacktrace()).isNotNull(); }
@Override public boolean isChildOf(TraceContextHolder parent) { return parent.getTraceContext().getTraceId().equals(traceId) && parent.getTraceContext().getId().equals(parentId); }
@Test void testThreadLocalStorage() { Transaction transaction = tracerImpl.startTransaction(); try (Scope scope = transaction.activateInScope()) { assertThat(tracerImpl.currentTransaction()).isSameAs(transaction); Span span = tracerImpl.getActive().createSpan(); try (Scope spanScope = span.activateInScope()) { assertThat(tracerImpl.currentTransaction()).isSameAs(transaction); assertThat(tracerImpl.getActive()).isSameAs(span); assertThat(span.isChildOf(transaction)).isTrue(); span.end(); } assertThat(tracerImpl.getActive()).isEqualTo(transaction); transaction.end(); } assertThat(tracerImpl.currentTransaction()).isNull(); }
public void captureException(long epochMicros, @Nullable Throwable e, @Nullable TraceContextHolder<?> active) { if (e != null) { ErrorCapture error = errorPool.createInstance(); error.withTimestamp(epochMicros); error.setException(e); Transaction currentTransaction = currentTransaction(); if (currentTransaction != null) { error.setTransactionType(currentTransaction.getType()); error.setTransactionSampled(currentTransaction.isSampled()); } if (active != null) { if (active instanceof Transaction) { Transaction transaction = (Transaction) active; // The error might have occurred in a different thread than the one the transaction was recorded // That's why we have to ensure the visibility of the transaction properties error.getContext().copyFrom(transaction.getContextEnsureVisibility()); } else if (active instanceof Span) { Span span = (Span) active; error.getContext().getTags().putAll(span.getContext().getTags()); } error.asChildOf(active.getTraceContext()); } else { error.getTraceContext().getId().setToRandomValue(); } reporter.report(error); } }
@Test void testEnableStacktracesForSlowSpans() throws InterruptedException { when(tracerImpl.getConfig(StacktraceConfiguration.class).getSpanFramesMinDurationMs()).thenReturn(1L); Transaction transaction = tracerImpl.startTransaction(); try (Scope scope = transaction.activateInScope()) { Span span = tracerImpl.getActive().createSpan(); try (Scope spanScope = span.activateInScope()) { Thread.sleep(10); span.end(); } transaction.end(); } assertThat(reporter.getFirstSpan().getStacktrace()).isNotNull(); }
@Test void testDisableStacktraces() { when(tracerImpl.getConfig(StacktraceConfiguration.class).getSpanFramesMinDurationMs()).thenReturn(0L); Transaction transaction = tracerImpl.startTransaction(); try (Scope scope = transaction.activateInScope()) { Span span = tracerImpl.getActive().createSpan(); try (Scope spanScope = span.activateInScope()) { span.end(); } transaction.end(); } assertThat(reporter.getFirstSpan().getStacktrace()).isNull(); }
@Test void testDisableStacktracesForFastSpans() { when(tracerImpl.getConfig(StacktraceConfiguration.class).getSpanFramesMinDurationMs()).thenReturn(100L); Transaction transaction = tracerImpl.startTransaction(); try (Scope scope = transaction.activateInScope()) { Span span = tracerImpl.getActive().createSpan(); try (Scope spanScope = span.activateInScope()) { span.end(); } transaction.end(); } assertThat(reporter.getFirstSpan().getStacktrace()).isNull(); }