public async Task Invoke_Trace() { var accessor = new HttpContextAccessor { HttpContext = new DefaultHttpContext() }; var context = CreateHttpContext(); var tracerMock = CreateIManagedTracerMock(context); var delegateMock = new Mock <RequestDelegate>(); delegateMock.Setup(d => d(context)).Returns(Task.CompletedTask); Func <TraceHeaderContext, IManagedTracer> fakeFactory = f => tracerMock.Object; Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer(accessor)); var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory, accessor); await middleware.Invoke(context, _traceHeaderContext); Assert.Equal(tracerMock.Object, ContextTracerManager.GetCurrentTracer(accessor)); Assert.True(context.Response.Headers.ContainsKey(TraceHeaderContext.TraceHeader)); Assert.Equal(_traceHeaderContext.ToString(), context.Response.Headers[TraceHeaderContext.TraceHeader]); delegateMock.VerifyAll(); tracerMock.VerifyAll(); }
internal void BeginRequest(object sender, EventArgs e) { var request = HttpContext.Current.Request; string header = request.Headers.Get(TraceHeaderContext.TraceHeader); var headerContext = TraceHeaderContext.FromHeader( header, () => _traceFallbackPredicate?.ShouldTrace(request)); var tracer = _tracerFactory(headerContext); if (tracer.GetCurrentTraceId() == null) { return; } ContextTracerManager.SetCurrentTracer(tracer); if (headerContext.TraceId != null) { // Set the updated trace header on the response. var updatedHeaderContext = TraceHeaderContext.Create( tracer.GetCurrentTraceId(), tracer.GetCurrentSpanId() ?? 0, true); HttpContext.Current.Response.Headers.Set( TraceHeaderContext.TraceHeader, updatedHeaderContext.ToString()); } // Start the span and annotate it with information from the current request. var span = tracer.StartSpan(HttpContext.Current.Request.Path); ContextInstanceManager.Set(span); tracer.AnnotateSpan(Labels.FromHttpRequest(HttpContext.Current.Request)); tracer.AnnotateSpan(Labels.AgentLabel); }
public async Task TraceSingleAsync(Func <IHostBuilder> createHostBuilder) { IHost host = null; try { host = createHostBuilder().Build(); await host.StartAsync(); ITraceContext traceContext = new SimpleTraceContext(null, null, true); var tracerFactory = host.Services.GetRequiredService <Func <ITraceContext, IManagedTracer> >(); IManagedTracer tracer = tracerFactory(traceContext); ContextTracerManager.SetCurrentTracer(tracer); using (tracer.StartSpan(_testId)) { IManagedTracer currentTracer = host.Services.GetRequiredService <IManagedTracer>(); currentTracer.RunInSpan( () => Console.WriteLine("Using Cloud Trace from a non ASP.NET Core app"), "testing_tracing"); } var trace = TraceEntryPolling.Default.GetTrace(_testId, _startTime); TraceEntryVerifiers.AssertParentChildSpan(trace, _testId, "testing_tracing"); } finally { if (host is object) { await host.StopAsync(); } } }
public async Task Invoke_Trace() { var accessor = new HttpContextAccessor { HttpContext = new DefaultHttpContext() }; var context = CreateHttpContext(); var tracerMock = CreateIManagedTracerMock(context); var delegateMock = new Mock <RequestDelegate>(); delegateMock.Setup(d => d(context)).Returns(Task.CompletedTask); var tracerFactoryMock = new Mock <IManagedTracerFactory>(); tracerFactoryMock.Setup(f => f.CreateTracer(_traceHeaderContext)).Returns(tracerMock.Object); Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer(accessor)); var middleware = new CloudTraceMiddleware(delegateMock.Object, tracerFactoryMock.Object, accessor); await middleware.Invoke(context, _traceHeaderContext); Assert.Equal(tracerMock.Object, ContextTracerManager.GetCurrentTracer(accessor)); delegateMock.VerifyAll(); tracerMock.VerifyAll(); }
public async Task Invoke_Trace() { var context = CreateHttpContext(); var tracerMock = CreateIManagedTracerMock(context); var delegateMock = new Mock <RequestDelegate>(); delegateMock.Setup(d => d(context)).Returns(Task.CompletedTask); Func <TraceHeaderContext, IManagedTracer> fakeFactory = f => tracerMock.Object; Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer()); var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory, new DefaultCloudTraceNameProvider()); await middleware.Invoke(context, _traceHeaderContext); // Since the current tracer is AsyncLocal<>, it will be back to the default after awaiting the middleware invoke Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer()); Assert.True(context.Response.Headers.ContainsKey(TraceHeaderContext.TraceHeader)); Assert.Equal(_traceHeaderContext.ToString(), context.Response.Headers[TraceHeaderContext.TraceHeader]); delegateMock.VerifyAll(); tracerMock.VerifyAll(); }
public async Task SetAndGetInDifferentAsyncContexts() { var mockedManagedTracer = new Mock <IManagedTracer>(MockBehavior.Strict).Object; async Task setTracer() { ContextTracerManager.SetCurrentTracer(mockedManagedTracer); await Task.Yield(); } async Task <IManagedTracer> getTracer() { var tracer = ContextTracerManager.GetCurrentTracer(); await Task.Yield(); return(tracer); } await setTracer(); var actualManagedTracer = await getTracer(); // The "intuitive" thing would be to // Assert.Equal(mockedManagedTracer, actualManagedTracer); // but, we have implemented the ContextTraceManager using AsyncLocal // and since in this test we have set the mocked tracer in an independent // async context from the one we are then obtaining the tracer, the tracer set // on the first async context is not propagated to the second async context where // we are trying to obtain it. Assert.Equal(NullManagedTracer.Instance, actualManagedTracer); }
public void FromGoogleTrace() { var oldTracer = ContextTracerManager.GetCurrentTracer(); try { string traceId = "dummy_trace_id"; ulong spanId = 0x12D687; // The spanId set on the log entry should confirm to x16 // format so that the backend can really associate the log entry // to the span. string expectedSpanId = "000000000012d687"; ContextTracerManager.SetCurrentTracer(MockTracer(traceId, spanId)); var traceContext = TraceContextForLogEntry.FromGoogleTrace(); Assert.Equal(traceId, traceContext.TraceId); Assert.Equal(expectedSpanId, traceContext.SpanId); } finally { ContextTracerManager.SetCurrentTracer(oldTracer); } }
public void Set() { var mockedManagedTracer = new Mock <IManagedTracer>(MockBehavior.Strict).Object; ContextTracerManager.SetCurrentTracer(mockedManagedTracer); Assert.Equal(mockedManagedTracer, ContextTracerManager.GetCurrentTracer()); }
public ErrorReportingContextExceptionLoggerTest() { var tracerMock = new Mock <IManagedTracer>(MockBehavior.Strict); tracerMock.Setup(t => t.GetCurrentTraceId()).Returns(_traceId); tracerMock.Setup(t => t.GetCurrentSpanId()).Returns(_spanId); ContextTracerManager.SetCurrentTracer(tracerMock.Object); }
/// <summary> /// Invokes the next <see cref="RequestDelegate"/> and traces the time /// taken for the next delegate to run, reporting the results to the /// Google Cloud Trace API. /// </summary> /// <param name="httpContext">The current HTTP context.</param> /// <param name="traceContext">Trace information from the current request. Must not be null.</param> /// <param name="fallback">Predicate to be used if the trace context has no information about whether /// the request should be traced or not.</param> /// <param name="traceContextPropagator">Trace context propagator to be used to set the trace context /// on the <see cref="HttpResponse"/>. Must not be null.</param> public async Task Invoke( HttpContext httpContext, ITraceContext traceContext, TraceDecisionPredicate fallback, Action <HttpResponse, ITraceContext> traceContextPropagator) { GaxPreconditions.CheckNotNull(traceContext, nameof(traceContext)); GaxPreconditions.CheckNotNull(traceContextPropagator, nameof(traceContextPropagator)); // Applies the trace decision fallback, if needed. traceContext = WithShouldTraceFallback(traceContext, fallback.ShouldTrace(httpContext.Request)); // Create a tracer for the given request and set it on the context manager so // the tracer can be used in other places. var tracer = _tracerFactory(traceContext); ContextTracerManager.SetCurrentTracer(tracer); if (tracer.GetCurrentTraceId() == null) { await _next(httpContext).ConfigureAwait(false); } else { if (traceContext.TraceId != null) { // Set the current trace context on the response. var currentTraceContext = ContextTracerManager.GetCurrentTraceContext(); traceContextPropagator.Invoke(httpContext.Response, currentTraceContext); } // Trace the delegate and annotate it with information from the current // HTTP context. var traceName = await _nameProvider.GetTraceNameAsync(httpContext).ConfigureAwait(false); var span = tracer.StartSpan(traceName); try { await _next(httpContext).ConfigureAwait(false); } catch (Exception exception) { try { StackTrace stackTrace = new StackTrace(exception, true); tracer.SetStackTrace(stackTrace); } catch (Exception innerException) { throw new AggregateException(innerException, exception); } throw; } finally { tracer.AnnotateSpan(Labels.AgentLabel); tracer.AnnotateSpan(Labels.FromHttpContext(httpContext)); span.Dispose(); } } }
public void Set_NullTraceId_NullTraceContext() { var managedTracerMock = new Mock <IManagedTracer>(MockBehavior.Strict); managedTracerMock.Setup(t => t.GetCurrentTraceId()).Returns <IManagedTracer, string>(null); ContextTracerManager.SetCurrentTracer(managedTracerMock.Object); Assert.Null(ContextTracerManager.GetCurrentTraceContext()); }
/// <summary> /// Invokes the next <see cref="RequestDelegate"/> and traces the time /// taken for the next delegate to run, reporting the results to the /// Stackdriver Trace API. /// </summary> /// <param name="httpContext">The current HTTP context.</param> /// <param name="traceHeaderContext">Information from the current request header. Must not be null.</param> public async Task Invoke(HttpContext httpContext, TraceHeaderContext traceHeaderContext) { GaxPreconditions.CheckNotNull(traceHeaderContext, nameof(traceHeaderContext)); // Create a tracer for the given request and set it on the context manager so // the tracer can be used in other places. var tracer = _tracerFactory(traceHeaderContext); ContextTracerManager.SetCurrentTracer(tracer); if (tracer.GetCurrentTraceId() == null) { await _next(httpContext).ConfigureAwait(false); } else { if (traceHeaderContext.TraceId != null) { // Set the trace updated trace header on the response. var updatedHeaderContext = TraceHeaderContext.Create( tracer.GetCurrentTraceId(), tracer.GetCurrentSpanId() ?? 0, true); httpContext.Response.Headers.Add( TraceHeaderContext.TraceHeader, updatedHeaderContext.ToString()); } // Trace the delegate and annotate it with information from the current // HTTP context. var traceName = await _nameProvider.GetTraceNameAsync(httpContext).ConfigureAwait(false); var span = tracer.StartSpan(traceName); try { await _next(httpContext).ConfigureAwait(false); } catch (Exception exception) { try { StackTrace stackTrace = new StackTrace(exception, true); tracer.SetStackTrace(stackTrace); } catch (Exception innerException) { throw new AggregateException(innerException, exception); } throw; } finally { tracer.AnnotateSpan(Labels.AgentLabel); tracer.AnnotateSpan(Labels.FromHttpContext(httpContext)); span.Dispose(); } } }
public void CreateManagedTracer() { var mockProvider = new Mock <IServiceProvider>(); var mockTracer = new Mock <IManagedTracer>(); string traceId = Guid.NewGuid().ToString("N"); mockTracer.Setup(p => p.GetCurrentTraceId()).Returns(traceId); ContextTracerManager.SetCurrentTracer(mockTracer.Object); var tracer = ManagedTracer.CreateDelegatingTracer(() => ContextTracerManager.GetCurrentTracer()); Assert.IsType <DelegatingTracer>(tracer); Assert.Equal(traceId, tracer.GetCurrentTraceId()); mockTracer.Verify(); }
public void FromGoogleTrace_NoTrace() { var oldTracer = ContextTracerManager.GetCurrentTracer(); try { ContextTracerManager.SetCurrentTracer(MockTracer()); Assert.Null(TraceContextForLogEntry.FromGoogleTrace()); } finally { ContextTracerManager.SetCurrentTracer(oldTracer); } }
public void Set_TraceContext() { var managedTracerMock = new Mock <IManagedTracer>(MockBehavior.Strict); managedTracerMock.Setup(t => t.GetCurrentTraceId()).Returns("dummyTraceId"); managedTracerMock.Setup(t => t.GetCurrentSpanId()).Returns(123456789u); ContextTracerManager.SetCurrentTracer(managedTracerMock.Object); var traceContext = ContextTracerManager.GetCurrentTraceContext(); Assert.NotNull(traceContext); Assert.Equal("dummyTraceId", traceContext.TraceId); Assert.Equal(123456789u, traceContext.SpanId); Assert.True(traceContext.ShouldTrace); }
public async Task TraceIncomingAsync() { IHost host = null; // Hides that we use different classes so that we can have multiple CreateHostBuilder methods. Func <IHostBuilder> CreateHostBuilder = DefaultHostBuilder.CreateHostBuilder; try { // Sample: Start host = CreateHostBuilder().Build(); await host.StartAsync(); // End sample object request = null; // Sample: IncomingContext ITraceContext traceContext = GetTraceContextFromIncomingRequest(request); var tracerFactory = host.Services.GetRequiredService <Func <ITraceContext, IManagedTracer> >(); IManagedTracer tracer = tracerFactory(traceContext); ContextTracerManager.SetCurrentTracer(tracer); // End sample // Let's just start a span with the test ID so we can find it faster. // But we don't show this in sample code. using (tracer.StartSpan(_testId)) { // Sample: Trace IManagedTracer currentTracer = host.Services.GetRequiredService <IManagedTracer>(); using (currentTracer.StartSpan("testing_tracing")) { Console.WriteLine("Using Cloud Trace from a non ASP.NET Core app"); } // End sample } var trace = TraceEntryPolling.Default.GetTrace(_testId, _startTime); TraceEntryVerifiers.AssertParentChildSpan(trace, _testId, "testing_tracing"); Assert.Equal(traceContext.TraceId, trace.TraceId); } finally { if (host is object) { await host.StopAsync(); } } }
public async Task TraceAsync() { // Naming it like an instance variable so that it looks like that on sample code. IHost _host = null; try { // Sample: Start _host = CreateHostBuilder().Build(); await _host.StartAsync(); // End sample // Sample: IncomingContext ITraceContext traceContext = GetTraceContextFromIncomingRequest(); var tracerFactory = _host.Services.GetRequiredService <Func <ITraceContext, IManagedTracer> >(); IManagedTracer tracer = tracerFactory(traceContext); ContextTracerManager.SetCurrentTracer(tracer); // End sample // Let's just start a span with the test ID so we can find it faster. // But we don't show this in sample code. using (tracer.StartSpan(_testId)) { // Sample: Trace IManagedTracer currentTracer = _host.Services.GetRequiredService <IManagedTracer>(); using (currentTracer.StartSpan("standalone_tracing")) { Console.WriteLine("Using Cloud Trace from a non ASP.NET Core app"); } // End sample } var trace = s_polling.GetTrace(_testId, _startTime); TraceEntryVerifiers.AssertParentChildSpan(trace, _testId, "standalone_tracing"); Assert.Equal(traceContext.TraceId, trace.TraceId); } finally { if (_host != null) { await _host.StopAsync(); } } }
public async Task Invoke_NoTrace() { var context = new DefaultHttpContext(); var delegateMock = new Mock <RequestDelegate>(); var tracerMock = new Mock <IManagedTracer>(); Func <ITraceContext, IManagedTracer> fakeFactory = f => tracerMock.Object; var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory, new DefaultCloudTraceNameProvider()); await middleware.Invoke(context, _traceContext, TraceDecisionPredicate.Default, CustomTraceContextPropagator); // Since the current tracer is AsyncLocal<>, it will be back to the default after awaiting the middleware invoke Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer()); AssertNoTraceContext(context.Response); delegateMock.Verify(d => d(context), Times.Once()); tracerMock.Verify(t => t.StartSpan(It.IsAny <string>(), null), Times.Never()); }
public async Task Invoke_NoTrace() { var context = new DefaultHttpContext(); var delegateMock = new Mock <RequestDelegate>(); var tracerMock = new Mock <IManagedTracer>(); Func <TraceHeaderContext, IManagedTracer> fakeFactory = f => tracerMock.Object; var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory); await middleware.Invoke(context, _traceHeaderContext); // Since the current tracer is AsyncLocal<>, it will be back to the default after awaiting the middleware invoke Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer()); Assert.False(context.Response.Headers.ContainsKey(TraceHeaderContext.TraceHeader)); delegateMock.Verify(d => d(context), Times.Once()); tracerMock.Verify(t => t.StartSpan(It.IsAny <string>(), null), Times.Never()); }
public async Task Invoke_NoTrace() { var accessor = new HttpContextAccessor { HttpContext = new DefaultHttpContext() }; var context = new DefaultHttpContext(); var delegateMock = new Mock <RequestDelegate>(); var tracerMock = new Mock <IManagedTracer>(); Func <TraceHeaderContext, IManagedTracer> fakeFactory = f => tracerMock.Object; var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory, accessor); await middleware.Invoke(context, _traceHeaderContext); Assert.Equal(tracerMock.Object, ContextTracerManager.GetCurrentTracer(accessor)); Assert.False(context.Response.Headers.ContainsKey(TraceHeaderContext.TraceHeader)); delegateMock.Verify(d => d(context), Times.Once()); tracerMock.Verify(t => t.StartSpan(It.IsAny <string>(), null), Times.Never()); }
public void FromGoogleTrace_NoSpan() { var oldTracer = ContextTracerManager.GetCurrentTracer(); try { string traceId = "dummy_trace_id"; ContextTracerManager.SetCurrentTracer(MockTracer(traceId)); var traceContext = TraceContextForLogEntry.FromGoogleTrace(); Assert.Equal(traceId, traceContext.TraceId); Assert.Null(traceContext.SpanId); } finally { ContextTracerManager.SetCurrentTracer(oldTracer); } }
public async Task Invoke_NoTrace() { var accessor = new HttpContextAccessor { HttpContext = new DefaultHttpContext() }; var context = new DefaultHttpContext(); var delegateMock = new Mock <RequestDelegate>(); var tracerMock = new Mock <IManagedTracer>(); var tracerFactoryMock = new Mock <IManagedTracerFactory>(); tracerFactoryMock.Setup(f => f.CreateTracer(_traceHeaderContext)).Returns(tracerMock.Object); var middleware = new CloudTraceMiddleware(delegateMock.Object, tracerFactoryMock.Object, accessor); await middleware.Invoke(context, _traceHeaderContext); Assert.Equal(tracerMock.Object, ContextTracerManager.GetCurrentTracer(accessor)); delegateMock.Verify(d => d(context), Times.Once()); tracerMock.Verify(t => t.StartSpan(It.IsAny <string>(), null), Times.Never()); tracerMock.Verify(t => t.EndSpan(), Times.Never()); }
public async Task TraceOutgoingAsync() { IHost host = null; try { host = OutgoingHostBuilder.CreateHostBuilder().Build(); await host.StartAsync(); ITraceContext traceContext = new SimpleTraceContext(null, null, true); var tracerFactory = host.Services.GetRequiredService <Func <ITraceContext, IManagedTracer> >(); IManagedTracer tracer = tracerFactory(traceContext); ContextTracerManager.SetCurrentTracer(tracer); // Let's just start a span with the test ID so we can find it faster. // But we don't show this in sample code. using (tracer.StartSpan(_testId)) { // Sample: TraceOutgoingClientFactory IHttpClientFactory clientFactory = host.Services.GetRequiredService <IHttpClientFactory>(); var httpClient = clientFactory.CreateClient("tracesOutgoing"); // Any code that makes outgoing requests. var response = await httpClient.GetAsync("http://weather.com/"); // End sample } var trace = TraceEntryPolling.Default.GetTrace(_testId, _startTime); TraceEntryVerifiers.AssertParentChildSpan(trace, _testId, "http://weather.com/"); } finally { if (host is object) { await host.StopAsync(); } } }
public async Task TraceSingleAsync() { IHost host = null; try { host = TroubleshootingHostBuilder.CreateHostBuilder().Build(); await host.StartAsync(); // Sample: SingleContext ITraceContext traceContext = new SimpleTraceContext(null, null, true); var tracerFactory = host.Services.GetRequiredService <Func <ITraceContext, IManagedTracer> >(); IManagedTracer tracer = tracerFactory(traceContext); ContextTracerManager.SetCurrentTracer(tracer); // End sample // Let's just start a span with the test ID so we can find it faster. // But we don't show this in sample code. using (tracer.StartSpan(_testId)) { // Sample: RunIn IManagedTracer currentTracer = host.Services.GetRequiredService <IManagedTracer>(); currentTracer.RunInSpan( () => Console.WriteLine("Using Cloud Trace from a non ASP.NET Core app"), "testing_tracing"); // End sample } var trace = TraceEntryPolling.Default.GetTrace(_testId, _startTime); TraceEntryVerifiers.AssertParentChildSpan(trace, _testId, "testing_tracing"); } finally { if (host is object) { await host.StopAsync(); } } }
public async Task Invoke_Trace() { var context = CreateHttpContext(); var tracerMock = CreateIManagedTracerMock(context); var delegateMock = new Mock <RequestDelegate>(); delegateMock.Setup(d => d(context)).Returns(Task.CompletedTask); Func <ITraceContext, IManagedTracer> fakeFactory = f => tracerMock.Object; Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer()); var middleware = new CloudTraceMiddleware(delegateMock.Object, fakeFactory, new DefaultCloudTraceNameProvider()); await middleware.Invoke(context, _traceContext, TraceDecisionPredicate.Default, CustomTraceContextPropagator); // Since the current tracer is AsyncLocal<>, it will be back to the default after awaiting the middleware invoke Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer()); AssertCustomTraceContext(context.Response); delegateMock.VerifyAll(); tracerMock.VerifyAll(); }
public async Task SetAndGetInNestedAsyncContexts() { var mockedManagedTracer = new Mock <IManagedTracer>(MockBehavior.Strict).Object; async Task <IManagedTracer> getTracer() { var tracer = ContextTracerManager.GetCurrentTracer(); await Task.Yield(); return(tracer); } async Task <IManagedTracer> setTracerAndGet() { ContextTracerManager.SetCurrentTracer(mockedManagedTracer); await Task.Yield(); return(await getTracer()); } var actualManagedTracer = await setTracerAndGet(); Assert.Equal(mockedManagedTracer, actualManagedTracer); }
public void Unset_NullTraceContext() => Assert.Null(ContextTracerManager.GetCurrentTraceContext());
public void Unset_NullManagedTracer() { Assert.Equal(NullManagedTracer.Instance, ContextTracerManager.GetCurrentTracer()); }