Пример #1
0
        /// <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();
                }
            }
        }
Пример #2
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();
                }
            }
        }