예제 #1
0
        public async Task Trace_Header()
        {
            string traceId = _traceIdFactory.NextId();
            ulong  spanId  = _spanIdFactory.NextId();

            var uri           = $"/Trace/{nameof(TraceController.Trace)}/{_testId}";
            var childSpanName = EntryData.GetMessage(nameof(TraceController.Trace), _testId);

            using (var server = new TestServer(new WebHostBuilder().UseStartup <TraceTestNoBufferLowQpsApplication>()))
                using (var client = server.CreateClient())
                {
                    var header = TraceHeaderContext.Create(traceId, spanId, shouldTrace: true);
                    client.DefaultRequestHeaders.Add(TraceHeaderContext.TraceHeader, header.ToString());

                    var response = await client.GetAsync(uri);

                    var trace = _polling.GetTrace(uri, _startTime);

                    TraceEntryVerifiers.AssertParentChildSpan(trace, uri, childSpanName);

                    Assert.Equal(traceId, trace.TraceId);
                    var parentSpan = trace.Spans.First(s => s.Name == uri);
                    Assert.Equal(spanId, parentSpan.ParentSpanId);

                    Assert.True(response.Headers.Contains(TraceHeaderContext.TraceHeader));
                    var returnedHeader = response.Headers.GetValues(TraceHeaderContext.TraceHeader).Single();
                    var headerContext  = TraceHeaderContext.FromHeader(returnedHeader);
                    Assert.Equal(traceId, headerContext.TraceId);
                    Assert.Equal(spanId, headerContext.SpanId);
                    Assert.True(headerContext.ShouldTrace);
                }
        }
예제 #2
0
        public async Task Logging_Trace_FromHeader_MultipleSpans()
        {
            string traceId = s_traceIdFactory.NextId();
            ulong  spanId  = s_spanIdFactory.NextId();
            string testId  = IdGenerator.FromGuid();

            var builder = new WebHostBuilder().UseStartup <NoBufferWarningLoggerTestApplication>();

            using (var server = new TestServer(builder))
                using (var client = server.CreateClient())
                {
                    client.DefaultRequestHeaders.Add(TraceHeaderContext.TraceHeader,
                                                     TraceHeaderContext.Create(traceId, spanId, true).ToString());
                    await client.GetAsync($"/Main/{nameof(MainController.LogsInDifferentSpans)}/{testId}");
                }

            _fixture.AddValidator(testId, results =>
            {
                // Span: span-1
                //       Log: span-1
                //       Span: span-1-2
                //             Log: span-1-2
                // Span: span-2
                //       Log: span-2

                string projectId = TestEnvironment.GetTestProjectId();

                // We have 3 logs.
                Assert.Equal(3, results.Count);
                // And the resource name of the trace associated to all of them points to the trace
                // we specified on the header.
                Assert.DoesNotContain(results, entry => !entry.Trace.Contains(projectId));
                Assert.DoesNotContain(results, entry => !entry.Trace.Contains(traceId));

                // Let's get our trace.
                var trace = s_tracePolling.GetTrace(traceId);
                Assert.NotNull(trace);

                // Let's check that all the entries are associated to the correct spans.
                var logEntry1  = Assert.Single(results, e => e.JsonPayload.Fields["message"].StringValue.EndsWith("log-1"));
                var logEntry12 = Assert.Single(results, e => e.JsonPayload.Fields["message"].StringValue.EndsWith("log-1-2"));
                var logEntry2  = Assert.Single(results, e => e.JsonPayload.Fields["message"].StringValue.EndsWith("log-2"));

                var span1 = Assert.Single(trace.Spans, s => EntryData.SpanIdToHex(s.SpanId) == logEntry1.SpanId);
                Assert.EndsWith("span-1", span1.Name);
                var span12 = Assert.Single(trace.Spans, s => EntryData.SpanIdToHex(s.SpanId) == logEntry12.SpanId);
                Assert.EndsWith("span-1-2", span12.Name);
                var span2 = Assert.Single(trace.Spans, s => EntryData.SpanIdToHex(s.SpanId) == logEntry2.SpanId);
                Assert.EndsWith("span-2", span2.Name);

                // Let's check that the spans are correctly created and descend from the span we specified in the header.
                // span-1-2 is a child of span-1
                Assert.Equal(span12.ParentSpanId, span1.SpanId);
                // span-1 and span-2 have the same parent
                Assert.Equal(span1.ParentSpanId, span2.ParentSpanId);
                // The grandparent of span-1 and span-2 is the span we specified on the header.
                var parentSpan = Assert.Single(trace.Spans, s => s.SpanId == span1.ParentSpanId);
                Assert.Equal(spanId, parentSpan.ParentSpanId);
            });
        }
        /// <summary>
        /// Creates an <see cref="TraceHeaderContext"/> based on the current <see cref="HttpContext"/>
        /// and a <see cref="ShouldTraceRequest"/>.
        /// </summary>
        internal static TraceHeaderContext CreateTraceHeaderContext(IServiceProvider provider)
        {
            var accessor           = provider.GetServiceCheckNotNull <IHttpContextAccessor>();
            var shouldTraceRequest = provider.GetServiceCheckNotNull <ShouldTraceRequest>();
            var traceIdFactory     = provider.GetServiceCheckNotNull <TraceIdFactory>();

            string header             = accessor.HttpContext?.Request?.Headers[TraceHeaderContext.TraceHeader];
            var    traceHeaderContext = TraceHeaderContext.FromHeader(header);

            if (traceHeaderContext.ShouldTrace == null && shouldTraceRequest.ShouldTrace != null)
            {
                bool?shouldTrace = shouldTraceRequest.ShouldTrace(accessor.HttpContext?.Request);
                if (shouldTrace == true)
                {
                    return(new TraceHeaderContext(
                               traceHeaderContext.TraceId ?? traceIdFactory.NextId(),
                               traceHeaderContext.SpanId ?? 0, shouldTrace));
                }
                else if (shouldTrace == false)
                {
                    return(new TraceHeaderContext(
                               traceHeaderContext.TraceId, traceHeaderContext.SpanId, shouldTrace));
                }
            }
            return(traceHeaderContext);
        }
예제 #4
0
        public void Log_Trace()
        {
            string traceId       = "105445aa7843bc8bf206b12000100f00";
            string fullTraceName = TraceTarget.ForProject(ProjectId).GetFullTraceName(traceId);

            Predicate <IEnumerable <LogEntry> > matcher = logEntries =>
            {
                LogEntry entry = logEntries.Single();
                return(entry.LogName == new LogName(ProjectId, BaseLogName).ToString() &&
                       entry.Trace == fullTraceName);
            };

            var tracerContext     = TraceHeaderContext.Create(traceId, 81237123, null);
            HeaderDictionary dict = new HeaderDictionary();

            dict[TraceHeaderContext.TraceHeader] = tracerContext.ToString();

            var mockServiceProvider = new Mock <IServiceProvider>();
            var mockAccessor        = new Mock <IHttpContextAccessor>();
            var mockContext         = new Mock <HttpContext>();
            var mockRequest         = new Mock <HttpRequest>();

            mockServiceProvider.Setup(sp => sp.GetService(typeof(IHttpContextAccessor))).Returns(mockAccessor.Object);
            mockAccessor.Setup(a => a.HttpContext).Returns(mockContext.Object);
            mockContext.Setup(c => c.Request).Returns(mockRequest.Object);
            mockRequest.Setup(r => r.Headers).Returns(dict);

            var mockConsumer = new Mock <IConsumer <LogEntry> >();

            mockConsumer.Setup(c => c.Receive(Match.Create(matcher)));
            var logger = GetLogger(mockConsumer.Object, LogLevel.Information, serviceProvider: mockServiceProvider.Object, logName: BaseLogName);

            logger.Log(LogLevel.Error, 0, LogMessage, s_exception, Formatter);
            mockConsumer.VerifyAll();
        }
예제 #5
0
        public async Task Trace_Header()
        {
            string traceId = TraceIdFactory.Create().NextId();
            ulong  spanId  = SpanIdFactory.Create().NextId();

            string testId    = Utils.GetTestId();
            var    startTime = Timestamp.FromDateTime(DateTime.UtcNow);

            var client = _noBufferLowQps.CreateClient();

            var header = TraceHeaderContext.Create(traceId, spanId, shouldTrace: true);

            client.DefaultRequestHeaders.Add(TraceHeaderContext.TraceHeader, header.ToString());
            var response = await client.GetAsync($"/Trace/Trace/{testId}");

            var spanName = TraceController.GetMessage(nameof(TraceController.Trace), testId);
            var trace    = _polling.GetTrace(spanName, startTime);

            Assert.NotNull(trace);
            Assert.Equal(traceId, trace.TraceId);
            Assert.Equal(2, trace.Spans.Count);
            var span = trace.Spans.First(s => s.Name.StartsWith("/Trace"));

            Assert.Equal(spanId, span.ParentSpanId);

            Assert.True(response.Headers.Contains(TraceHeaderContext.TraceHeader));
            var returnedHeader = response.Headers.GetValues(TraceHeaderContext.TraceHeader).Single();
            var headerContext  = TraceHeaderContext.FromHeader(returnedHeader);

            Assert.Equal(traceId, headerContext.TraceId);
            Assert.Equal(spanId, headerContext.SpanId);
            Assert.True(headerContext.ShouldTrace);
        }
예제 #6
0
        public async Task Trace_Header()
        {
            string traceId = TraceIdFactory.Create().NextId();
            ulong  spanId  = SpanIdFactory.Create().NextId();

            string testId    = Utils.GetTestId();
            var    startTime = Timestamp.FromDateTime(DateTime.UtcNow);
            var    builder   = new WebHostBuilder().UseStartup <TraceTestNoBufferLowQpsApplication>();

            using (var server = new TestServer(builder))
            {
                var client = server.CreateClient();

                var header = TraceHeaderContext.Create(traceId, spanId, shouldTrace: true);
                client.DefaultRequestHeaders.Add(TraceHeaderContext.TraceHeader, header.ToString());
                await client.GetAsync($"/Trace/Trace/{testId}");
            }

            var spanName = TraceController.GetMessage(nameof(TraceController.Trace), testId);
            var trace    = _polling.GetTrace(spanName, startTime);

            Assert.NotNull(trace);
            Assert.Equal(traceId, trace.TraceId);
            Assert.Equal(2, trace.Spans.Count);
            var span = trace.Spans.First(s => s.Name.StartsWith("/Trace"));

            Assert.Equal(spanId, span.ParentSpanId);
        }
        /// <summary>
        /// Creates an <see cref="TraceHeaderContext"/> based on the current <see cref="HttpContext"/>.
        /// </summary>
        internal static TraceHeaderContext CreateTraceHeaderContext(IServiceProvider provider)
        {
            var    accessor = provider.GetService <IHttpContextAccessor>();
            string header   = accessor?.HttpContext?.Request?.Headers[TraceHeaderContext.TraceHeader];

            return(TraceHeaderContext.FromHeader(header));
        }
예제 #8
0
        public async Task Logging_Trace_FromHeader_Implicit()
        {
            string traceId = s_traceIdFactory.NextId();
            ulong  spanId  = s_spanIdFactory.NextId();
            string testId  = IdGenerator.FromGuid();

            using (var server = GetTestServer <NoBufferWarningLoggerTestApplication>())
                using (var client = server.CreateClient())
                {
                    client.DefaultRequestHeaders.Add(TraceHeaderContext.TraceHeader,
                                                     TraceHeaderContext.Create(traceId, spanId, true).ToString());
                    await client.GetAsync($"/Main/Critical/{testId}");
                }

            _fixture.AddValidator(testId, results =>
            {
                // We only have one log entry.
                LogEntry entry = Assert.Single(results);

                // And the resource name of the trace associated to it points to the trace
                // we specified on the header.
                Assert.Contains(TestEnvironment.GetTestProjectId(), entry.Trace);
                Assert.Contains(traceId, entry.Trace);

                // Let's get our trace.
                var trace = s_tracePolling.GetTrace(traceId);
                Assert.NotNull(trace);

                // The span associated to our entry needs to be part of that trace.
                // (We created this span on the middleware to encompass the whole request)
                var entrySpan = Assert.Single(trace.Spans, s => EntryData.SpanIdToHex(s.SpanId) == entry.SpanId);
                // And its parent needs to be the span specified in the header
                Assert.Equal(spanId, entrySpan.ParentSpanId);
            });
        }
        /// <summary>
        /// Creates an <see cref="TraceHeaderContext"/> based on the current <see cref="HttpContext"/>
        /// and a <see cref="TraceDecisionPredicate"/>.
        /// Used by default to obtain trace context, if user code has not specified a trace context provider.
        /// </summary>
        internal static TraceHeaderContext ProvideGoogleTraceHeaderContext(IServiceProvider serviceProvider)
        {
            var    accessor = serviceProvider.GetRequiredService <IHttpContextAccessor>();
            string header   = accessor.HttpContext?.Request?.Headers[TraceHeaderContext.TraceHeader];

            return(TraceHeaderContext.FromHeader(header));
        }
예제 #10
0
        public void FromRequest_ForceTrace_NullFunc()
        {
            var context = TraceHeaderContext.FromHeader(CreateTraceHeaderValue(1), null);

            Assert.Equal(SpanId, context.SpanId);
            Assert.Equal(TraceId, context.TraceId);
            Assert.True(context.ShouldTrace);
        }
예제 #11
0
        public void Create()
        {
            var context = TraceHeaderContext.Create(TraceId, SpanId, true);

            Assert.Equal(SpanId, context.SpanId);
            Assert.Equal(TraceId, context.TraceId);
            Assert.True(context.ShouldTrace);
        }
예제 #12
0
        public void CreateTraceHeaderContext_UseShouldTraceFallback()
        {
            var header        = $"{_traceId}/{_spanId};";
            var provider      = CreateProviderForTraceHeaderContext(header);
            var headerContext = AspNetCoreTraceExtensions.ProvideGoogleTraceHeaderContext(provider);

            Assert.Equal(TraceHeaderContext.FromHeader(header).ToString(), headerContext.ToString());
        }
예제 #13
0
        public void CreateTraceHeaderContext_UseBackUpFunc()
        {
            var header        = $"{_traceId}/{_spanId};";
            var provider      = CreateProviderForTraceHeaderContext(header);
            var headerContext = CloudTraceExtension.CreateTraceHeaderContext(provider);

            Assert.Equal(TraceHeaderContext.FromHeader(header).ToString(), headerContext.ToString());
        }
예제 #14
0
        public void FromRequest_ValidTrace()
        {
            var context = TraceHeaderContext.FromHeader(CreateTraceHeaderValue(1));

            Assert.True(SpanId == context.SpanId);
            Assert.Equal(TraceId, context.TraceId);
            Assert.True(context.ShouldTrace);
        }
예제 #15
0
        public void FromRequest_ForceTrace_NoHeader()
        {
            var context = TraceHeaderContext.FromHeader("", () => true);

            Assert.NotNull(context.TraceId);
            Assert.Equal((ulong)0, context.SpanId);
            Assert.True(context.ShouldTrace);
        }
예제 #16
0
        public void CreateOptions_NoTrace()
        {
            var factory = TraceHeaderTraceOptionsFactory.Create();

            var contextNoTrace = new TraceHeaderContext(null, null, false);
            var optionsNoTrace = factory.CreateOptions(contextNoTrace);

            Assert.False(optionsNoTrace.ShouldTrace);
        }
예제 #17
0
        public void CreateOptions_Trace()
        {
            var factory = TraceHeaderTraceOptionsFactory.Create();

            var contextTrace = new TraceHeaderContext(null, null, true);
            var optionsTrace = factory.CreateOptions(contextTrace);

            Assert.True(optionsTrace.ShouldTrace);
        }
예제 #18
0
        public void FromRequest_ValidNoTrace()
        {
            var wrapper = CreateWrapperWithTraceHeader(CreateTraceHeaderValue(0));
            var context = TraceHeaderContext.FromWrapper(wrapper);

            Assert.True(SpanId == context.SpanId);
            Assert.Equal(TraceId, context.TraceId);
            Assert.False(context.ShouldTrace);
        }
예제 #19
0
        public void FromRequest_ForceTrace(bool?shouldTrace)
        {
            var context = TraceHeaderContext.FromHeader(
                CreateTraceHeaderValue(), () => shouldTrace);

            Assert.Equal(TraceId, context.TraceId);
            Assert.Equal(SpanId, context.SpanId);
            Assert.Equal(shouldTrace, context.ShouldTrace);
        }
        /// <summary>
        /// Creates an <see cref="TraceHeaderContext"/> based on the current <see cref="HttpContext"/>
        /// and a <see cref="ShouldTraceRequest"/>.
        /// </summary>
        internal static TraceHeaderContext CreateTraceHeaderContext(IServiceProvider provider)
        {
            var accessor           = provider.GetServiceCheckNotNull <IHttpContextAccessor>();
            var shouldTraceRequest = provider.GetServiceCheckNotNull <ShouldTraceRequest>();

            string       header          = accessor.HttpContext?.Request?.Headers[TraceHeaderContext.TraceHeader];
            Func <bool?> shouldTraceFunc = () => shouldTraceRequest?.ShouldTrace(accessor.HttpContext?.Request);

            return(TraceHeaderContext.FromHeader(header, shouldTraceFunc));
        }
예제 #21
0
        /// <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();
                }
            }
        }
예제 #22
0
        private static void AssertGoogleTraceHeader(HttpResponseMessage response, string traceId, ulong?spanId, bool?shouldTrace)
        {
            string headerValue = Assert.Single(response.Headers.GetValues(TraceHeaderContext.TraceHeader));
            var    header      = TraceHeaderContext.FromHeader(headerValue);

            Assert.Equal(traceId, header.TraceId);
            Assert.Equal(spanId, header.SpanId);
            Assert.Equal(shouldTrace, header.ShouldTrace);

            AssertNoCustomTraceHeader(response);
        }
예제 #23
0
        /// <summary>
        /// Gets the full trace name if the log target is a project, we have an
        /// HTTP accessor and a valid trace header exists on the current context.
        /// If the trace name cannot be determined null is returned.
        /// See: See: https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry
        /// </summary>
        internal string GetTraceName()
        {
            if (_traceTarget == null || _accessor == null)
            {
                return(null);
            }

            string header       = _accessor.HttpContext?.Request?.Headers[TraceHeaderContext.TraceHeader];
            var    traceContext = TraceHeaderContext.FromHeader(header);

            return(traceContext.TraceId == null ? null : _traceTarget.GetFullTraceName(traceContext.TraceId));
        }
 protected override Task <HttpResponseMessage> SendAsync(
     HttpRequestMessage request, CancellationToken cancellationToken)
 {
     if (_context != null)
     {
         var traceHeader    = request.Headers.GetValues(TraceHeaderContext.TraceHeader).First();
         var currentContext = TraceHeaderContext.FromHeader(traceHeader);
         Assert.Equal(_context.TraceId, currentContext.TraceId);
         Assert.Equal(_context.SpanId, currentContext.SpanId);
         Assert.Equal(_context.ShouldTrace, currentContext.ShouldTrace);
     }
     return(Task.FromResult(new HttpResponseMessage()));
 }
예제 #25
0
        /// <summary>
        /// Gets the full trace name if the log target is a project, we have an
        /// HTTP accessor and a valid trace header exists on the current context.
        /// If the trace name cannot be determined null is returned.
        /// See: See: https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry
        /// </summary>
        internal string GetTraceName()
        {
            var httpContext = _serviceProvider?.GetService <IHttpContextAccessor>()?.HttpContext;

            if (_traceTarget == null || httpContext == null)
            {
                return(null);
            }

            string header       = httpContext.Request?.Headers[TraceHeaderContext.TraceHeader];
            var    traceContext = TraceHeaderContext.FromHeader(header);

            return(traceContext.TraceId == null ? null : _traceTarget.GetFullTraceName(traceContext.TraceId));
        }
예제 #26
0
        public void ToStringTest()
        {
            var context = TraceHeaderContext.Create(TraceId, SpanId, true);

            Assert.Equal($"{TraceId}/{SpanId};o=1", context.ToString());

            context = TraceHeaderContext.Create(TraceId, SpanId, null);
            Assert.Equal($"{TraceId}/{SpanId};", context.ToString());

            context = TraceHeaderContext.Create(TraceId, SpanId, false);
            Assert.Equal($"{TraceId}/{SpanId};o=0", context.ToString());

            context = TraceHeaderContext.Create(null, null, false);
            Assert.Equal("/;o=0", context.ToString());
        }
        public void CreateManagedTracer()
        {
            var context           = TraceHeaderContext.Create(null, null, false);
            var tracerFactoryMock = new Mock <IManagedTracerFactory>();

            tracerFactoryMock.Setup(f => f.CreateTracer(context)).Returns(NullManagedTracer.Instance);
            var mockProvider = new Mock <IServiceProvider>();

            mockProvider.Setup(p => p.GetService(typeof(TraceHeaderContext))).Returns(context);
            mockProvider.Setup(p => p.GetService(typeof(IManagedTracerFactory))).Returns(tracerFactoryMock.Object);

            var tracer = CloudTraceExtension.CreateManagedTracer(mockProvider.Object);

            Assert.IsType(typeof(NullManagedTracer), tracer);
            tracerFactoryMock.VerifyAll();
            mockProvider.VerifyAll();
        }
        /// <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 requrest header. Cannot 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 HttpContext so
            // the tracer can be used in other places.
            var tracer = _tracerFactory.CreateTracer(traceHeaderContext);

            ContextTracerManager.SetCurrentTracer(_accessor, 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.
                tracer.StartSpan(httpContext.Request.Path);
                try
                {
                    await _next(httpContext).ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    StackTrace stackTrace = new StackTrace(e, true);
                    tracer.SetStackTrace(stackTrace);
                    throw;
                }
                finally
                {
                    tracer.AnnotateSpan(Labels.AgentLabel);
                    tracer.AnnotateSpan(Labels.FromHttpContext(httpContext));
                    tracer.EndSpan();
                }
            }
        }
예제 #29
0
        public async Task Logging_Trace()
        {
            string   traceId   = "105445aa7843bc8bf206b12000100f00";
            string   testId    = Utils.GetTestId();
            DateTime startTime = DateTime.UtcNow;

            var builder = new WebHostBuilder().UseStartup <NoBufferWarningLoggerTestApplication>();

            using (var server = new TestServer(builder))
                using (var client = server.CreateClient())
                {
                    client.DefaultRequestHeaders.Add(TraceHeaderContext.TraceHeader,
                                                     TraceHeaderContext.Create(traceId, 81237123, null).ToString());
                    await client.GetAsync($"/Main/Critical/{testId}");

                    var results = _polling.GetEntries(startTime, testId, 1, LogSeverity.Critical);
                    Assert.Contains(Utils.GetProjectIdFromEnvironment(), results.Single().Trace);
                    Assert.Contains(traceId, results.Single().Trace);
                }
        }
        public void CreateTraceHeaderContext()
        {
            string header = $"{TraceId}/{SpanId};o=1";

            var context = new DefaultHttpContext();
            var request = new DefaultHttpRequest(context);

            request.Headers[TraceHeaderContext.TraceHeader] = header;

            var accessor = new HttpContextAccessor();

            accessor.HttpContext = context;

            Mock <IServiceProvider> mockProvider = new Mock <IServiceProvider>();

            mockProvider.Setup(p => p.GetService(typeof(IHttpContextAccessor))).Returns(accessor);

            var headerContext = CloudTraceExtension.CreateTraceHeaderContext(mockProvider.Object);

            Assert.Equal(TraceHeaderContext.FromHeader(header).ToString(), headerContext.ToString());
        }