Esempio n. 1
0
        /// <summary>
        /// Invokes this middleware instance on the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns>A middleware invocation/execution task.</returns>
        public async Task Invoke(HttpContext context)
        {
            // as we learned from a field issue, apparently a middleware can even be invoked without a valid HttPContext:
            string requestId = null;

            requestId = context?.Features?
                        .Get <IHttpRequestIdentifierFeature>()?
                        .TraceIdentifier;

#if (NETSTANDARD2_1 || NETCOREAPP3_0)
            context?.Request.EnableBuffering();
#else
            context?.Request.EnableRewind();
#endif

            using (_logger.BeginScope($"Request: {requestId ?? string.Empty}"))
            {
                NetworkTelemetry networkTelemetry = null;

                try
                {
                    if (TelemetryCollector.Instance.IsAutocollecting && context != null && context.Request != null)
                    {
                        int?telemetryStatusCode = null;
                        telemetryStatusCode = context?.Response?.StatusCode;

                        networkTelemetry = new NetworkTelemetry(
                            method: context.Request.Method,
                            url: context.Request.Host.Value + context.Request.Path,
                            eventStart: DateTime.UtcNow,
                            eventEnd: null,
                            statusCode: telemetryStatusCode
                            );
                        TelemetryCollector.Instance.Capture(new Telemetry(TelemetrySource.Server, TelemetryLevel.Info, networkTelemetry));
                    }

                    if (RollbarScope.Current != null && RollbarScope.Current.HttpContext != null)
                    {
                        RollbarScope.Current.HttpContext.HttpAttributes = new RollbarHttpAttributes(context);
                    }

                    await this._nextRequestProcessor(context);
                }
                catch (System.Exception ex)
                {
                    if (networkTelemetry != null)
                    {
                        networkTelemetry.StatusCode =
                            context?.Response?.StatusCode.ToString();
                        networkTelemetry.FinalizeEvent();
                    }

                    if (!RollbarLocator.RollbarInstance.Config.CaptureUncaughtExceptions)
                    {
                        // just rethrow since the Rollbar SDK is configured not to auto-capture
                        // uncaught exceptions:
                        throw;
                    }

                    if (RollbarScope.Current != null &&
                        RollbarLocator.RollbarInstance.Config.MaxItems > 0
                        )
                    {
                        RollbarScope.Current.IncrementLogItemsCount();
                        if (RollbarScope.Current.LogItemsCount == RollbarLocator.RollbarInstance.Config.MaxItems)
                        {
                            // the Rollbar SDK just reached MaxItems limit, report this fact and pause further logging within this scope:
                            RollbarLocator.RollbarInstance.Warning(RollbarScope.MaxItemsReachedWarning);
                            throw;
                        }
                        else if (RollbarScope.Current.LogItemsCount > RollbarLocator.RollbarInstance.Config.MaxItems)
                        {
                            // just rethrow since the Rollbar SDK already exceeded MaxItems limit:
                            throw;
                        }
                    }
                    else
                    {
                        IRollbarPackage rollbarPackage = new ExceptionPackage(ex, $"{nameof(RollbarMiddleware)} processed uncaught exception.");
                        if (context != null)
                        {
                            if (context.Request != null)
                            {
                                rollbarPackage = new HttpRequestPackageDecorator(rollbarPackage, context.Request, true);
                            }
                            if (context.Response != null)
                            {
                                rollbarPackage = new HttpResponsePackageDecorator(rollbarPackage, context.Response, true);
                            }
                        }
                        RollbarLocator.RollbarInstance.Critical(rollbarPackage);
                    }

                    throw new RollbarMiddlewareException(ex);
                }
                finally
                {
                    if (context != null &&
                        context.Response != null &&
                        RollbarScope.Current != null &&
                        RollbarScope.Current.HttpContext != null &&
                        RollbarScope.Current.HttpContext.HttpAttributes != null
                        )
                    {
                        RollbarScope.Current.HttpContext.HttpAttributes.ResponseStatusCode = context.Response.StatusCode;
                    }

                    if (networkTelemetry != null)
                    {
                        if (string.IsNullOrWhiteSpace(networkTelemetry.StatusCode))
                        {
                            networkTelemetry.StatusCode = context?.Response?.StatusCode.ToString();
                        }
                        networkTelemetry.FinalizeEvent();
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Invokes this middleware instance on the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns>A middleware invocation/execution task.</returns>
        public async Task Invoke(HttpContext context)
        {
            // as we learned from a field issue, apparently a middleware can even be invoked without a valid HttPContext:
            string requestId = null;

            requestId = context?.Features?
                        .Get <IHttpRequestIdentifierFeature>()?
                        .TraceIdentifier;
            using (_logger.BeginScope($"Request: {requestId ?? string.Empty}"))
            {
                NetworkTelemetry networkTelemetry = null;

                try
                {
                    if (TelemetryCollector.Instance.IsAutocollecting && context != null && context.Request != null)
                    {
                        int?telemetryStatusCode = null;
                        telemetryStatusCode = context?.Response?.StatusCode;

                        networkTelemetry = new NetworkTelemetry(
                            method: context.Request.Method,
                            url: context.Request.Host.Value + context.Request.Path,
                            eventStart: DateTime.UtcNow,
                            eventEnd: null,
                            statusCode: telemetryStatusCode
                            );
                        TelemetryCollector.Instance.Capture(new Telemetry(TelemetrySource.Server, TelemetryLevel.Info, networkTelemetry));
                    }

                    RollbarScope.Current.HttpContext.HttpAttributes = new RollbarHttpAttributes(context);
                    await this._nextRequestProcessor(context);
                }
                catch (System.Exception ex)
                {
                    if (networkTelemetry != null)
                    {
                        networkTelemetry.StatusCode = context?.Response?.StatusCode.ToString();
                        networkTelemetry.FinalizeEvent();
                    }

                    if (!RollbarLocator.RollbarInstance.Config.CaptureUncaughtExceptions)
                    {
                        // just rethrow since the Rollbar SDK is configured not to auto-capture uncaught exceptions:
                        throw ex;
                    }

                    if (RollbarScope.Current != null &&
                        RollbarLocator.RollbarInstance.Config.MaxItems > 0
                        )
                    {
                        RollbarScope.Current.IncrementLogItemsCount();
                        if (RollbarScope.Current.LogItemsCount == RollbarLocator.RollbarInstance.Config.MaxItems)
                        {
                            // the Rollbar SDK just reached MaxItems limit, report this fact and pause further logging within this scope:
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                            RollbarLocator.RollbarInstance.Warning(RollbarScope.MaxItemsReachedWarning);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                            throw ex;
                        }
                        else if (RollbarScope.Current.LogItemsCount > RollbarLocator.RollbarInstance.Config.MaxItems)
                        {
                            // just rethrow since the Rollbar SDK already exceeded MaxItems limit:
                            throw ex;
                        }
                    }
                    else
                    {
                        // let's custom build the Data object that includes the exception
                        // along with the current HTTP request context:
                        DTOs.Data data = new DTOs.Data(
                            config: RollbarLocator.RollbarInstance.Config,
                            body: new DTOs.Body(ex),
                            custom: null,
                            request: (context != null) ? new DTOs.Request(null, context.Request) : null
                            )
                        {
                            Level = ErrorLevel.Critical,
                        };

                        // log the Data object (the exception + the HTTP request data):
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                        RollbarLocator.RollbarInstance.Log(data);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    }

                    throw new System.Exception("The included internal exception processed by the Rollbar middleware", ex);
                }
                finally
                {
                    if (context != null &&
                        context.Response != null &&
                        RollbarScope.Current != null &&
                        RollbarScope.Current.HttpContext != null &&
                        RollbarScope.Current.HttpContext.HttpAttributes != null
                        )
                    {
                        RollbarScope.Current.HttpContext.HttpAttributes.StatusCode = context.Response.StatusCode;
                    }

                    if (networkTelemetry != null)
                    {
                        if (string.IsNullOrWhiteSpace(networkTelemetry.StatusCode))
                        {
                            networkTelemetry.StatusCode = context?.Response?.StatusCode.ToString();
                        }
                        networkTelemetry.FinalizeEvent();
                    }
                }
            }
        }