/** * Pushes the given span onto the {@link #currentSpanStackThreadLocal} stack. If the stack is null it will create a new one. Also pushes the span info into the logging * {@link org.slf4j.MDC} so it is available there. */ protected void pushSpanOntoCurrentSpanStack(Span pushMe) { Deque<Span> currentStack = currentSpanStackThreadLocal.get(); if (currentStack == null) { currentStack = new LinkedList<>(); currentSpanStackThreadLocal.set(currentStack); } currentStack.push(pushMe); configureMDC(pushMe); classLogger.debug("** starting sample for span {}", serializeSpanToDesiredStringRepresentation(pushMe)); }
/** * Completes the current child sub-span by calling {@link #completeAndLogSpan(Span, boolean)} on it and then {@link #configureMDC(Span)} on the sub-span's parent * (which becomes the new current span). * <p/> * <b>WARNING:</b> This only works if there are at least 2 spans in the {@link #currentSpanStackThreadLocal} stack - one for the child sub-span and one for the parent span. * If you're trying to complete the overall request's span you should be calling {@link #completeRequestSpan()} instead. If there are 0 or 1 spans on the stack then * this method will log an error and do nothing. */ public void completeSubSpan() { Deque<Span> currentSpanStack = currentSpanStackThreadLocal.get(); if (currentSpanStack == null || currentSpanStack.size() < 2) { int stackSize = (currentSpanStack == null) ? 0 : currentSpanStack.size(); classLogger.error( "WINGTIPS USAGE ERROR - Expected to find a child sub-span on the stack to complete, but the span stack was size {} instead (there should be at least 2 for " + "this method to be able to find a child sub-span). wingtips_usage_error=true, bad_span_stack=true", stackSize, new Exception("Stack trace for debugging purposes") ); // Nothing to do return; } // We have at least two spans. Pop off the child sub-span and complete/log it. Span subSpan = currentSpanStack.pop(); completeAndLogSpan(subSpan, false); // Now configure the MDC with the new current span. configureMDC(currentSpanStack.peek()); }
unconfigureMDC(); else configureMDC(newStackLatestSpan);
@Test public void configureMDC_should_set_span_values_on_MDC() throws Exception { // given Span span = Span.newBuilder("test-span", SpanPurpose.LOCAL_ONLY).withParentSpanId("3").build(); String expected = span.toJSON(); // when Tracer.configureMDC(span); // then assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isEqualTo(expected); }
@Test public void unconfigureMDC_should_unset_span_values_on_MDC() throws Exception { // given Span span = Span.newBuilder("test-span", SpanPurpose.LOCAL_ONLY).withParentSpanId("3").build(); Tracer.configureMDC(span); // when Tracer.unconfigureMDC(); // then assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isNull(); }