Search in sources :

Example 51 with Span

use of com.nike.wingtips.Span in project riposte by Nike-Inc.

the class DTraceStartHandler method doChannelRead.

@Override
public PipelineContinuationBehavior doChannelRead(ChannelHandlerContext ctx, Object msg) {
    // We only do the processing for HttpRequest which is the first message in a request chain.
    if (shouldHandleDoChannelReadMessage(msg)) {
        try {
            startTrace((HttpRequest) msg, ctx);
        } catch (Throwable t) {
            logger.error("An unexpected error occurred while starting the distributed tracing overall request span. This " + "exception will be swallowed to avoid breaking the Netty pipeline, but it should be " + "investigated as it shouldn't ever happen.", t);
        }
    }
    if (msg instanceof LastHttpContent) {
        HttpProcessingState httpProcessingState = ChannelAttributes.getHttpProcessingStateForChannel(ctx).get();
        // Add the "we received the last bytes of the request on the wire" annotation to the span if possible
        // and desired.
        Span requestSpan = handlerUtils.getOverallRequestSpan(httpProcessingState);
        if (requestSpan != null && spanNamingAndTaggingStrategy.shouldAddWireReceiveFinishAnnotation()) {
            requestSpan.addTimestampedAnnotationForCurrentTime(spanNamingAndTaggingStrategy.wireReceiveFinishAnnotationName());
        }
    }
    return PipelineContinuationBehavior.CONTINUE;
}
Also used : HttpProcessingState(com.nike.riposte.server.http.HttpProcessingState) LastHttpContent(io.netty.handler.codec.http.LastHttpContent) Span(com.nike.wingtips.Span)

Example 52 with Span

use of com.nike.wingtips.Span in project riposte by Nike-Inc.

the class DTraceStartHandler method startTrace.

protected void startTrace(HttpRequest nettyRequest, ChannelHandlerContext ctx) {
    Tracer tracer = Tracer.getInstance();
    // Start the distributed trace.
    RequestWithHeaders requestWrapper = new RequestWithHeadersNettyAdapter(nettyRequest);
    final Span parentSpan = HttpRequestTracingUtils.fromRequestWithHeaders(requestWrapper, userIdHeaderKeys);
    HttpProcessingState httpProcessingState = ChannelAttributes.getHttpProcessingStateForChannel(ctx).get();
    // Create the new trace or child span, depending on what info came through via the Netty HttpRequest.
    // We'll use the fallback span name to start with, because it's possible to throw an exception when
    // creating the Riposte RequestInfo from the HttpRequest (which can happen when we call
    // handlerUtils.createRequestInfoFromNettyHttpRequestAndHandleStateSetupIfNecessary(...) for certain
    // bad requests), and we want the log message for *that* to include trace ID.
    Span newSpan;
    if (parentSpan != null) {
        newSpan = tracer.startRequestWithChildSpan(parentSpan, handlerUtils.determineFallbackOverallRequestSpanName(nettyRequest));
        logger.debug("Found Parent Span {}", parentSpan);
    } else {
        newSpan = tracer.startRequestWithRootSpan(handlerUtils.determineFallbackOverallRequestSpanName(nettyRequest), HttpRequestTracingUtils.getUserIdFromRequestWithHeaders(requestWrapper, userIdHeaderKeys));
        logger.debug("Parent Span not found, starting a new trace with root span {}", newSpan);
    }
    // Add the "we received the first bytes of the request on the wire" annotation to the span if desired.
    if (spanNamingAndTaggingStrategy.shouldAddWireReceiveStartAnnotation()) {
        newSpan.addTimestampedAnnotationForCurrentTime(spanNamingAndTaggingStrategy.wireReceiveStartAnnotationName());
    }
    // Get the RequestInfo (generating it from the given Netty HttpRequest if necessary), so that
    // getSpanName() can use it to come up with a better initial span name.
    RequestInfo<?> riposteRequestInfo = (httpProcessingState == null) ? null : handlerUtils.createRequestInfoFromNettyHttpRequestAndHandleStateSetupIfNecessary(nettyRequest, httpProcessingState);
    if (riposteRequestInfo != null) {
        // Change the span name based on what the tag strategy wants now that we have a Riposte RequestInfo.
        spanNamingAndTaggingStrategy.changeSpanName(newSpan, handlerUtils.determineOverallRequestSpanName(nettyRequest, riposteRequestInfo, spanNamingAndTaggingStrategy));
        // Add request tagging.
        spanNamingAndTaggingStrategy.handleRequestTagging(newSpan, riposteRequestInfo);
    }
}
Also used : Tracer(com.nike.wingtips.Tracer) HttpProcessingState(com.nike.riposte.server.http.HttpProcessingState) RequestWithHeaders(com.nike.wingtips.http.RequestWithHeaders) RequestWithHeadersNettyAdapter(com.nike.trace.netty.RequestWithHeadersNettyAdapter) Span(com.nike.wingtips.Span)

Example 53 with Span

use of com.nike.wingtips.Span in project riposte by Nike-Inc.

the class AsyncHttpClientHelperTest method executeAsyncHttpRequest_with_ctx_extracts_mdc_and_tracing_info_from_ctx_and_delegates_to_kitchen_sink_execute_method.

@Test
public void executeAsyncHttpRequest_with_ctx_extracts_mdc_and_tracing_info_from_ctx_and_delegates_to_kitchen_sink_execute_method() {
    // given
    RequestBuilderWrapper rbwMock = mock(RequestBuilderWrapper.class);
    AsyncResponseHandler responseHandlerMock = mock(AsyncResponseHandler.class);
    CompletableFuture cfMock = mock(CompletableFuture.class);
    doReturn(cfMock).when(helperSpy).executeAsyncHttpRequest(any(RequestBuilderWrapper.class), any(AsyncResponseHandler.class), any(Deque.class), any(Map.class));
    Map<String, String> mdcMock = mock(Map.class);
    Deque<Span> spanStackMock = mock(Deque.class);
    state.setLoggerMdcContextMap(mdcMock);
    state.setDistributedTraceStack(spanStackMock);
    // when
    CompletableFuture result = helperSpy.executeAsyncHttpRequest(rbwMock, responseHandlerMock, ctxMock);
    // then
    verify(helperSpy).executeAsyncHttpRequest(rbwMock, responseHandlerMock, spanStackMock, mdcMock);
    assertThat(result).isSameAs(cfMock);
    verify(rbwMock).setCtx(ctxMock);
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Deque(java.util.Deque) Map(java.util.Map) Span(com.nike.wingtips.Span) Test(org.junit.Test)

Example 54 with Span

use of com.nike.wingtips.Span in project riposte by Nike-Inc.

the class AsyncHttpClientHelperTest method executeAsyncHttpRequest_sets_up_and_executes_call_as_expected.

@DataProvider(value = { "true   |   true", "true   |   false", "false  |   true", "false  |   false" }, splitBy = "\\|")
@Test
public void executeAsyncHttpRequest_sets_up_and_executes_call_as_expected(boolean performSubspan, boolean currentTracingInfoNull) {
    // given
    Whitebox.setInternalState(helperSpy, "performSubSpanAroundDownstreamCalls", performSubspan);
    CircuitBreaker<Response> circuitBreakerMock = mock(CircuitBreaker.class);
    doReturn(Optional.of(circuitBreakerMock)).when(helperSpy).getCircuitBreaker(any(RequestBuilderWrapper.class));
    ManualModeTask<Response> cbManualTaskMock = mock(ManualModeTask.class);
    doReturn(cbManualTaskMock).when(circuitBreakerMock).newManualModeTask();
    String url = "http://localhost/some/path";
    String method = "GET";
    AsyncHttpClient.BoundRequestBuilder reqMock = mock(AsyncHttpClient.BoundRequestBuilder.class);
    RequestBuilderWrapper rbw = new RequestBuilderWrapper(url, method, reqMock, Optional.empty(), false);
    AsyncResponseHandler responseHandlerMock = mock(AsyncResponseHandler.class);
    Span initialSpan = (currentTracingInfoNull) ? null : Tracer.getInstance().startRequestWithRootSpan("foo");
    Deque<Span> initialSpanStack = (currentTracingInfoNull) ? null : Tracer.getInstance().getCurrentSpanStackCopy();
    Map<String, String> initialMdc = (currentTracingInfoNull) ? null : MDC.getCopyOfContextMap();
    resetTracingAndMdc();
    // when
    CompletableFuture resultFuture = helperSpy.executeAsyncHttpRequest(rbw, responseHandlerMock, initialSpanStack, initialMdc);
    // then
    // Verify that the circuit breaker came from the getCircuitBreaker helper method and that its
    // throwExceptionIfCircuitBreakerIsOpen() method was called.
    verify(helperSpy).getCircuitBreaker(rbw);
    verify(cbManualTaskMock).throwExceptionIfCircuitBreakerIsOpen();
    // Verify that the inner request's execute method was called with a
    // AsyncCompletionHandlerWithTracingAndMdcSupport for the handler.
    ArgumentCaptor<AsyncHandler> executedHandlerCaptor = ArgumentCaptor.forClass(AsyncHandler.class);
    verify(reqMock).execute(executedHandlerCaptor.capture());
    AsyncHandler executedHandler = executedHandlerCaptor.getValue();
    assertThat(executedHandler).isInstanceOf(AsyncCompletionHandlerWithTracingAndMdcSupport.class);
    // Verify that the AsyncCompletionHandlerWithTracingAndMdcSupport was created with the expected args
    AsyncCompletionHandlerWithTracingAndMdcSupport achwtams = (AsyncCompletionHandlerWithTracingAndMdcSupport) executedHandler;
    assertThat(achwtams.completableFutureResponse).isSameAs(resultFuture);
    assertThat(achwtams.responseHandlerFunction).isSameAs(responseHandlerMock);
    assertThat(achwtams.performSubSpanAroundDownstreamCalls).isEqualTo(performSubspan);
    assertThat(achwtams.circuitBreakerManualTask).isEqualTo(Optional.of(cbManualTaskMock));
    if (performSubspan) {
        int initialSpanStackSize = (initialSpanStack == null) ? 0 : initialSpanStack.size();
        assertThat(achwtams.distributedTraceStackToUse).hasSize(initialSpanStackSize + 1);
        Span subspan = (Span) achwtams.distributedTraceStackToUse.peek();
        assertThat(subspan.getSpanName()).isEqualTo(initialSpanNameFromStrategy.get());
        if (initialSpan != null) {
            assertThat(subspan.getTraceId()).isEqualTo(initialSpan.getTraceId());
            assertThat(subspan.getParentSpanId()).isEqualTo(initialSpan.getSpanId());
        }
        assertThat(achwtams.mdcContextToUse.get(SpanFieldForLoggerMdc.TRACE_ID.mdcKey)).isEqualTo(subspan.getTraceId());
    } else {
        assertThat(achwtams.distributedTraceStackToUse).isSameAs(initialSpanStack);
        assertThat(achwtams.mdcContextToUse).isSameAs(initialMdc);
    }
    // Verify that the trace headers were added (or not depending on state).
    Span spanForDownstreamCall = achwtams.getSpanForCall();
    if (initialSpan == null && !performSubspan) {
        assertThat(spanForDownstreamCall).isNull();
        verifyNoMoreInteractions(reqMock);
    } else {
        assertThat(spanForDownstreamCall).isNotNull();
        verify(reqMock).setHeader(TraceHeaders.TRACE_SAMPLED, convertSampleableBooleanToExpectedB3Value(spanForDownstreamCall.isSampleable()));
        verify(reqMock).setHeader(TraceHeaders.TRACE_ID, spanForDownstreamCall.getTraceId());
        verify(reqMock).setHeader(TraceHeaders.SPAN_ID, spanForDownstreamCall.getSpanId());
        if (spanForDownstreamCall.getParentSpanId() == null) {
            verify(reqMock, never()).setHeader(eq(TraceHeaders.PARENT_SPAN_ID), anyString());
        } else {
            verify(reqMock).setHeader(TraceHeaders.PARENT_SPAN_ID, spanForDownstreamCall.getParentSpanId());
        }
        verify(reqMock, never()).setHeader(eq(TraceHeaders.SPAN_NAME), anyString());
    }
    // Verify that any subspan had request tagging performed.
    if (performSubspan) {
        strategyRequestTaggingArgs.get().verifyArgs(spanForDownstreamCall, rbw, wingtipsTagAndNamingAdapterMock);
    }
}
Also used : AsyncHandler(com.ning.http.client.AsyncHandler) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Span(com.nike.wingtips.Span) Response(com.ning.http.client.Response) CompletableFuture(java.util.concurrent.CompletableFuture) AsyncHttpClient(com.ning.http.client.AsyncHttpClient) DataProvider(com.tngtech.java.junit.dataprovider.DataProvider) Test(org.junit.Test)

Example 55 with Span

use of com.nike.wingtips.Span in project riposte by Nike-Inc.

the class AsyncHttpClientHelperTest method basic_executeAsyncHttpRequest_extracts_mdc_and_tracing_info_from_current_thread_and_delegates_to_kitchen_sink_execute_method.

@Test
public void basic_executeAsyncHttpRequest_extracts_mdc_and_tracing_info_from_current_thread_and_delegates_to_kitchen_sink_execute_method() {
    // given
    RequestBuilderWrapper rbw = mock(RequestBuilderWrapper.class);
    AsyncResponseHandler responseHandler = mock(AsyncResponseHandler.class);
    CompletableFuture cfMock = mock(CompletableFuture.class);
    doReturn(cfMock).when(helperSpy).executeAsyncHttpRequest(any(RequestBuilderWrapper.class), any(AsyncResponseHandler.class), any(Deque.class), any(Map.class));
    Tracer.getInstance().startRequestWithRootSpan("foo");
    Deque<Span> expectedSpanStack = Tracer.getInstance().getCurrentSpanStackCopy();
    Map<String, String> expectedMdc = MDC.getCopyOfContextMap();
    // when
    CompletableFuture result = helperSpy.executeAsyncHttpRequest(rbw, responseHandler);
    // then
    verify(helperSpy).executeAsyncHttpRequest(rbw, responseHandler, expectedSpanStack, expectedMdc);
    assertThat(result).isSameAs(cfMock);
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Deque(java.util.Deque) Map(java.util.Map) Span(com.nike.wingtips.Span) Test(org.junit.Test)

Aggregations

Span (com.nike.wingtips.Span)103 Test (org.junit.Test)73 DataProvider (com.tngtech.java.junit.dataprovider.DataProvider)41 Map (java.util.Map)26 Deque (java.util.Deque)24 Assertions.catchThrowable (org.assertj.core.api.Assertions.catchThrowable)20 CompletableFuture (java.util.concurrent.CompletableFuture)18 HttpProcessingState (com.nike.riposte.server.http.HttpProcessingState)13 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)12 HashMap (java.util.HashMap)10 HttpRequest (io.netty.handler.codec.http.HttpRequest)9 Before (org.junit.Before)9 RequestInfo (com.nike.riposte.server.http.RequestInfo)8 Tracer (com.nike.wingtips.Tracer)8 HttpTagAndSpanNamingAdapter (com.nike.wingtips.tags.HttpTagAndSpanNamingAdapter)7 ChannelFuture (io.netty.channel.ChannelFuture)7 ChannelHandler (io.netty.channel.ChannelHandler)7 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)7 HttpResponse (io.netty.handler.codec.http.HttpResponse)7 LastHttpContent (io.netty.handler.codec.http.LastHttpContent)7