Example #1
0
        public void ToString_ExceptionWithPropertyThrowingAnError_ShouldNotThrow()
        {
            var logMessage = new LogMessage { Exception = new Exception("TEST", new ErrorThrowingException()) };
            var logMessageToString = logMessage.ToString();

            Assert.IsNotNull(logMessageToString);
            Assert.Greater(logMessageToString.Length, 0);
        }
        /// <summary>
        ///   Registra nel log delle informazioni relative a request e response.
        /// </summary>
        /// <param name="context">Il contesto di Owin.</param>
        /// <returns>Task per proseguire nella catena di middleware.</returns>
        public async override Task Invoke(IOwinContext context)
        {
            // Recupero le informazioni su request e response.
            var owinRequest = context.Request;
            var owinResponse = context.Response;
            var requestId = context.Environment[Constants.RequestIdVariable];

            // Se la richiesta risulta tra quelle da ignorare, devo fare poco e niente.
            var uriIsIgnored = context.Environment.ContainsKey(Constants.UriIgnoredVariable);
            if (uriIsIgnored)
            {
                try
                {
                    // Eseguo il prossimo componente.
                    await Next.Invoke(context);
                }
#pragma warning disable CC0004 // Catch block cannot be empty
                catch (Exception ex) when (_log.Fatal(new LogMessage { Context = "Processing request", Exception = ex }))
                {
                    // Eccezione rilanciata in automatico, la funzione di log ritorna sempre FALSE.
                }
#pragma warning restore CC0004 // Catch block cannot be empty

                // Termino qui il componente di middleware.
                return;
            }

            // Log request
            if (_log.IsTraceEnabled)
            {
                try
                {
                    // Effettuo il log del body della richiesta se:
                    // 1) Mi è consentito dalle impostazioni del componente.
                    // 2) Il Content-Type presente rientra in quelli umanamente leggibili.
                    var body = string.Empty;
                    if (_settings.LoggingFilter.HasFlag(HttpLoggingFilter.LogRequestBody)
                        && owinRequest.ContentType != null
                        && _settings.LoggedContentTypesRegex.IsMatch(owinRequest.ContentType))
                    {
                        body = await FormatBodyStreamAsync(owinRequest.Body);
                    }

                    _log.Trace(new LogMessage
                    {
                        ShortMessage = $"Request '{requestId}' at '{owinRequest.Uri.SafeToString()}'",
                        LongMessage = body,
                        Context = "Logging request",
                        Arguments = new[]
                        {
                            KeyValuePair.Create("request_method", owinRequest.Method),
                            KeyValuePair.Create("request_headers", SafeHeadersToString(owinRequest.Headers)),
                            KeyValuePair.Create("request_uri", owinRequest.Uri.AbsoluteUri),
                            KeyValuePair.Create("request_remote_ip_address", owinRequest.RemoteIpAddress),
                            KeyValuePair.Create("request_user_agent", owinRequest.Headers.Get("User-Agent"))
                        }
                    });
                }
                catch (Exception ex)
                {
                    // Eccezione NON rilanciata.
                    _log.Catching(new LogMessage { Context = "Logging request", Exception = ex });
                }
            }

            IPerfResult perf = null;
            try
            {
                // Run inner handlers and record time.
                using (_perfMonitorFactory.Create(out perf))
                {
                    await Next.Invoke(context);
                }
            }
#pragma warning disable CC0004 // Catch block cannot be empty
            catch (Exception ex) when (_log.Fatal(new LogMessage { Context = "Processing request", Exception = ex }))
            {
                // Eccezione rilanciata in automatico, la funzione di log ritorna sempre FALSE.
            }
#pragma warning restore CC0004 // Catch block cannot be empty

            // Log response
            if (_log.IsTraceEnabled)
            {
                try
                {
                    // Effettuo il log del body della risposta se:
                    // 1) Mi è consentito dalle impostazioni del componente.
                    // 2) Il Content-Type presente rientra in quelli umanamente leggibili.
                    var body = string.Empty;
                    if (_settings.LoggingFilter.HasFlag(HttpLoggingFilter.LogResponseBody)
                        && owinResponse.ContentType != null
                        && _settings.LoggedContentTypesRegex.IsMatch(owinResponse.ContentType))
                    {
                        // Estraggo una stringa con il contenuto della response.
                        body = await FormatBodyStreamAsync(owinResponse.Body);
                    }

                    var responseLogMsg = new LogMessage
                    {
                        ShortMessage = $"Response '{requestId}' for '{owinRequest.Uri.SafeToString()}'",
                        LongMessage = body,
                        Context = "Logging response",
                        Arguments = new[]
                        {
                            KeyValuePair.Create("response_status_code", owinResponse.StatusCode.ToString()),
                            KeyValuePair.Create("response_headers", SafeHeadersToString(owinResponse.Headers)),
                            KeyValuePair.Create("response_elapsed_msec", perf?.ElapsedMillisecondsString() ?? "0"),
                            KeyValuePair.Create("response_working_set_mb", perf?.WorkingSetMegabytesString() ?? "0"),
                        }
                    };

                    // Se il codice HTTP della risposta è nel gruppo dei codici di errore, allora il
                    // messaggio di log sarà di tipo ERROR. Altrimenti, sarà un semplice TRACE.
                    if (owinResponse.StatusCode >= 400)
                    {
                        _log.Error(responseLogMsg);
                    }
                    else
                    {
                        _log.Trace(responseLogMsg);
                    }
                }
                catch (Exception ex)
                {
                    // Eccezione NON rilanciata.
                    _log.Catching(new LogMessage { Context = "Logging response", Exception = ex });
                }
            }
        }