Пример #1
0
        /// <summary>
        /// Handles the <see cref="HttpContext"/>.
        /// </summary>
        public async Task InvokeAsync(HttpContext context)
        {
            var hub = _getHub();

            if (!hub.IsEnabled)
            {
                await _next(context).ConfigureAwait(false);

                return;
            }

            await hub.ConfigureScopeAsync(async scope =>
            {
                // Attempt to start a transaction from the trace header if it exists
                var traceHeader = TryGetSentryTraceHeader(context);

                // Defer setting name until other middlewares have finished
                var transaction = traceHeader is not null
                    ? hub.StartTransaction(
                    "Unknown Route",
                    "http.server",
                    traceHeader
                    )
                    : hub.StartTransaction(
                    "Unknown Route",
                    "http.server"
                    );

                _options.DiagnosticLogger?.LogInfo(
                    "Started transaction: Span ID: {0}, Trace ID: {1}",
                    transaction.SpanId,
                    transaction.TraceId
                    );

                // Put the transaction on the scope
                scope.Transaction = transaction;

                try
                {
                    await _next(context).ConfigureAwait(false);
                }
                finally
                {
                    // Try to resolve the route
                    if (context.TryGetTransactionName() is { } transactionName)
                    {
                        transaction.Name = transactionName;
                    }

                    transaction.Finish(
                        SpanStatusConverter.FromHttpStatusCode(context.Response.StatusCode)
                        );
                }
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// Handles the <see cref="HttpContext"/>.
        /// </summary>
        public async Task InvokeAsync(HttpContext context)
        {
            var hub = _getHub();

            if (!hub.IsEnabled)
            {
                await _next(context).ConfigureAwait(false);

                return;
            }

            var transaction = TryStartTransaction(context);

            // Expose the transaction on the scope so that the user
            // can retrieve it and start child spans off of it.
            hub.ConfigureScope(scope =>
            {
                scope.Transaction   = transaction;
                scope.OnEvaluating += (_, _) => scope.Populate(context, _options);
            });

            try
            {
                await _next(context).ConfigureAwait(false);
            }
            finally
            {
                if (transaction is not null)
                {
                    // The routing middleware may have ran after ours, so
                    // try to get the transaction name again.
                    if (context.TryGetTransactionName() is { } transactionName)
                    {
                        if (!string.Equals(transaction.Name, transactionName, StringComparison.Ordinal))
                        {
                            _options.DiagnosticLogger?.LogDebug(
                                "Changed transaction name from '{0}' to '{1}' after request pipeline executed.",
                                transaction.Name,
                                transactionName
                                );
                        }

                        transaction.Name = transactionName;
                    }

                    transaction.Finish(
                        SpanStatusConverter.FromHttpStatusCode(context.Response.StatusCode)
                        );
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Finishes an active Sentry transaction that encompasses the currently executing HTTP request (if present).
        /// </summary>
        public static void FinishSentryTransaction(this HttpContext httpContext)
        {
            if (!httpContext.Items.Contains(HttpContextTransactionItemName))
            {
                return;
            }

            if (httpContext.Items[HttpContextTransactionItemName] is not ISpan transaction)
            {
                return;
            }

            var status = SpanStatusConverter.FromHttpStatusCode(httpContext.Response.StatusCode);

            transaction.Finish(status);
        }
Пример #4
0
        /// <summary>
        /// Handles the <see cref="HttpContext"/>.
        /// </summary>
        public async Task InvokeAsync(HttpContext context)
        {
            var hub = _getHub();

            if (!hub.IsEnabled)
            {
                await _next(context).ConfigureAwait(false);

                return;
            }

            var transaction = TryStartTransaction(context);
            var initialName = transaction?.Name;

            // Expose the transaction on the scope so that the user
            // can retrieve it and start child spans off of it.
            hub.ConfigureScope(scope =>
            {
                scope.Transaction = transaction;
            });

            Exception?exception = null;

            try
            {
                await _next(context).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                exception = e;
            }
            finally
            {
                if (transaction is not null)
                {
                    // The Transaction name was altered during the pipeline execution,
                    // That could be done by user interference or by some Event Capture
                    // That triggers ScopeExtensions.Populate.
                    if (transaction.Name != initialName)
                    {
                        _options.LogDebug(
                            "transaction name set from '{0}' to '{1}' during request pipeline execution.",
                            initialName,
                            transaction.Name);
                    }
                    // try to get the transaction name.
                    else if (context.TryGetTransactionName() is { } transactionName&&
                             !string.IsNullOrEmpty(transactionName))
                    {
                        _options.LogDebug(
                            "Changed transaction '{0}', name set to '{1}' after request pipeline executed.",
                            transaction.SpanId,
                            transactionName);

                        transaction.Name = transactionName;
                    }

                    var status = SpanStatusConverter.FromHttpStatusCode(context.Response.StatusCode);

                    // If no Name was found for Transaction, fallback to UnknownRoute name.
                    if (transaction.Name == string.Empty)
                    {
                        transaction.Name = UnknownRouteTransactionName;
                    }

                    if (exception is null)
                    {
                        transaction.Finish(status);
                    }
                    // Status code not yet changed to 500 but an exception does exist
                    // so lets avoid passing the misleading 200 down and close only with
                    // the exception instance that will be inferred as errored.
                    else if (status == SpanStatus.Ok)
                    {
                        transaction.Finish(exception);
                    }
                    else
                    {
                        transaction.Finish(exception, status);
                    }
                }

                if (exception is not null)
                {
                    ExceptionDispatchInfo.Capture(exception).Throw();
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Handles the <see cref="HttpContext"/>.
        /// </summary>
        public async Task InvokeAsync(HttpContext context)
        {
            var hub = _getHub();

            if (!hub.IsEnabled)
            {
                await _next(context).ConfigureAwait(false);

                return;
            }

            var transaction = TryStartTransaction(context);

            // Expose the transaction on the scope so that the user
            // can retrieve it and start child spans off of it.
            hub.ConfigureScope(scope =>
            {
                scope.Transaction   = transaction;
                scope.OnEvaluating += (_, _) => scope.Populate(context, _options);
            });

            Exception?exception = null;

            try
            {
                await _next(context).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                exception = e;
            }
            finally
            {
                if (transaction is not null)
                {
                    // The routing middleware may have ran after ours, so
                    // try to get the transaction name again.
                    if (context.TryGetTransactionName() is { } transactionName)
                    {
                        if (!string.Equals(transaction.Name, transactionName, StringComparison.Ordinal))
                        {
                            _options.DiagnosticLogger?.LogDebug(
                                "Changed transaction name from '{0}' to '{1}' after request pipeline executed.",
                                transaction.Name,
                                transactionName
                                );
                        }

                        transaction.Name = transactionName;
                    }

                    var status = SpanStatusConverter.FromHttpStatusCode(context.Response.StatusCode);
                    if (exception is null)
                    {
                        transaction.Finish(status);
                    }
                    // Status code not yet changed to 500 but an exception does exist
                    // so lets avoid passing the misleading 200 down and close only with
                    // the exception instance that will be inferred as errored.
                    else if (status == SpanStatus.Ok)
                    {
                        transaction.Finish(exception);
                    }
                    else
                    {
                        transaction.Finish(exception, status);
                    }
                }

                if (exception is not null)
                {
                    ExceptionDispatchInfo.Capture(exception).Throw();
                }
            }
        }