bool LogCompletion(HttpContext httpContext, DiagnosticContextCollector collector, int statusCode, double elapsedMs, Exception ex) { var level = statusCode > 499 ? LogEventLevel.Error : LogEventLevel.Information; if (!Log.IsEnabled(level)) { return(false); } if (!collector.TryComplete(out var collectedProperties)) { collectedProperties = NoProperties; } // Last-in (correctly) wins... var properties = collectedProperties.Concat(new[] { new LogEventProperty("RequestMethod", new ScalarValue(httpContext.Request.Method)), new LogEventProperty("RequestPath", new ScalarValue(GetPath(httpContext))), new LogEventProperty("StatusCode", new ScalarValue(statusCode)), new LogEventProperty("Elapsed", new ScalarValue(elapsedMs)) }); var evt = new LogEvent(DateTimeOffset.Now, level, ex, _messageTemplate, properties); Log.Write(evt); return(false); }
private bool LogCompletion(HttpRequestMessage request, DiagnosticContextCollector collector, HttpStatusCode statusCode, long elapsedTicks) { var logger = Log.ForContext <RequestLoggingHandler>(); if (!logger.IsEnabled(LogLevelDefault)) { return(false); } if (!collector.TryComplete(out var collectedProperties)) { collectedProperties = NoProperties; } var clientType = Type.GetType(_clientName); var name = clientType != null ? clientType.Name : _clientName; // Last-in (correctly) wins... var properties = collectedProperties.Concat(new[] { new LogEventProperty("HttpClient", new ScalarValue(name)), new LogEventProperty("RequestMethod", new ScalarValue(request.Method)), new LogEventProperty("RequestPath", new ScalarValue(request.RequestUri.AbsolutePath)), new LogEventProperty("StatusCode", new ScalarValue((int)statusCode)), new LogEventProperty("Elapsed", new ScalarValue(TimeSpan.FromTicks(elapsedTicks).TotalMilliseconds)) }); var messageTemplate = new MessageTemplateParser().Parse(DefaultRequestCompletionMessageTemplate); var evt = new LogEvent(DateTimeOffset.Now, LogLevelDefault, null, messageTemplate, properties); logger.Write(evt); return(false); }
bool LogCompletion(HttpContext httpContext, DiagnosticContextCollector collector, int statusCode, double elapsedMs, Exception ex) { var logger = Log.ForContext <RequestLoggingMiddleware>(); var level = _getLevel(httpContext, elapsedMs, ex); if (!logger.IsEnabled(level)) { return(false); } // Enrich diagnostic context _enrichDiagnosticContext?.Invoke(_diagnosticContext, httpContext); if (!collector.TryComplete(out var collectedProperties)) { collectedProperties = NoProperties; } // Last-in (correctly) wins... var properties = collectedProperties.Concat(new[] { new LogEventProperty("RequestMethod", new ScalarValue(httpContext.Request.Method)), new LogEventProperty("RequestPath", new ScalarValue(GetPath(httpContext))), new LogEventProperty("StatusCode", new ScalarValue(statusCode)), new LogEventProperty("Elapsed", new ScalarValue(elapsedMs)) }); var evt = new LogEvent(DateTimeOffset.Now, level, ex, _messageTemplate, properties); logger.Write(evt); return(false); }
public LogScope(global::Serilog.ILogger logger, DiagnosticContext diagnosticContext, LogEventLevel level, string messageTemplate, object[] propertyValues, IEnumerable <LogProperty> logProperties) { _logger = logger.NotNull(nameof(logger)); _collector = diagnosticContext.BeginCollection(); _level = level; _messageTemplate = messageTemplate.NotNull(nameof(messageTemplate)); _propertyValues = propertyValues; _logProperties = logProperties; }
private void LogHttpRequest(HttpContext context, DiagnosticContextCollector collector, string requestBody, string finalResponseBody, int finalStatusCode, Stopwatch stopWatch, bool isRequestOk, Exception ex) { stopWatch.Stop(); var endpoint = context.GetEndpoint(); var shouldLogHttpRequest = !(endpoint?.Metadata?.GetMetadata <IgnoreLogAttribute>() is object); if (!shouldLogHttpRequest) { return; } if (_options.EnableResponseLogging || (!isRequestOk && _options.EnableExceptionLogging)) { bool shouldLogRequestData = ShouldLogRequestData(context); JsonDocument requestBodyObject = null; if ((shouldLogRequestData || (!isRequestOk && _options.LogResponseDataOnException)) && !string.IsNullOrWhiteSpace(requestBody)) { try { requestBody = requestBody.MaskFields(_options.MaskedProperties.ToArray(), _options.MaskFormat); } catch (Exception) { } if (requestBody.Length > _options.RequestBodyTextLengthLogLimit) { requestBody = requestBody.Substring(0, _options.RequestBodyTextLengthLogLimit); } else { try { requestBodyObject = System.Text.Json.JsonDocument.Parse(requestBody); } catch (Exception) { } } } else { requestBody = null; } var requestHeader = new Dictionary <string, object>(); if (_options.ShouldLogRequestHeader || (!isRequestOk && _options.LogRequestHeaderOnException)) { try { var valuesByKey = context.Request.Headers.Mask(_options.MaskedProperties.ToArray(), _options.MaskFormat).GroupBy(x => x.Key); foreach (var item in valuesByKey) { if (item.Count() > 1) { requestHeader.Add(item.Key, item.Select(x => x.Value.ToString()).ToArray()); } else { requestHeader.Add(item.Key, item.First().Value.ToString()); } } } catch (Exception) { SelfLog.WriteLine("Cannot parse response header"); } } var userAgentDic = new Dictionary <string, string>(); if (context.Request.Headers.ContainsKey("User-Agent")) { var userAgent = context.Request.Headers["User-Agent"].ToString(); userAgentDic.Add("_Raw", userAgent); try { var uaParser = UAParser.Parser.GetDefault(); var clientInfo = uaParser.Parse(userAgent); userAgentDic.Add("Browser", clientInfo.UA.Family); userAgentDic.Add("BrowserVersion", clientInfo.UA.Major + "." + clientInfo.UA.Minor); userAgentDic.Add("OperatingSystem", clientInfo.OS.Family); userAgentDic.Add("OperatingSystemVersion", clientInfo.OS.Major + "." + clientInfo.OS.Minor); userAgentDic.Add("Device", clientInfo.Device.Family); userAgentDic.Add("DeviceModel", clientInfo.Device.Model); userAgentDic.Add("DeviceManufacturer", clientInfo.Device.Brand); } catch (Exception) { SelfLog.WriteLine("Cannot parse user agent:" + userAgent); } } var requestQuery = new Dictionary <string, object>(); try { var valuesByKey = context.Request.Query.GroupBy(x => x.Key); foreach (var item in valuesByKey) { if (item.Count() > 1) { requestQuery.Add(item.Key, item.Select(x => x.Value.ToString()).ToArray()); } else { requestQuery.Add(item.Key, item.First().Value.ToString()); } } } catch (Exception) { SelfLog.WriteLine("Cannot parse query string"); } var requestData = new { ClientIp = context.Connection.RemoteIpAddress.ToString(), Method = context.Request.Method, Scheme = context.Request.Scheme, Host = context.Request.Host.Value, Path = context.Request.Path.Value, QueryString = context.Request.QueryString.Value, Query = requestQuery, BodyString = requestBody ?? string.Empty, Body = requestBodyObject, Header = requestHeader, UserAgent = userAgentDic, }; bool shouldLogResponseData = ShouldLogResponseData(context); object responseBodyObject = null; if ((shouldLogResponseData || (!isRequestOk && _options.LogResponseDataOnException))) { try { finalResponseBody = finalResponseBody.MaskFields(_options.MaskedProperties.ToArray(), _options.MaskFormat); } catch (Exception) { } if (finalResponseBody != null) { if (finalResponseBody.Length > _options.ResponseBodyTextLengthLogLimit) { finalResponseBody = finalResponseBody.Substring(0, _options.ResponseBodyTextLengthLogLimit); } else { try { responseBodyObject = System.Text.Json.JsonDocument.Parse(finalResponseBody); } catch (Exception) { } } } } else { finalResponseBody = null; } var responseHeader = new Dictionary <string, object>(); if (_options.ShouldLogResponseHeader || (!isRequestOk && _options.LogResponseHeaderOnException)) { try { var valuesByKey = context.Response.Headers.Mask(_options.MaskedProperties.ToArray(), _options.MaskFormat).GroupBy(x => x.Key); foreach (var item in valuesByKey) { if (item.Count() > 1) { responseHeader.Add(item.Key, item.Select(x => x.Value.ToString()).ToArray()); } else { responseHeader.Add(item.Key, item.First().Value.ToString()); } } } catch (Exception) { SelfLog.WriteLine("Cannot parse response header"); } } var responseData = new { StatusCode = finalStatusCode, stopWatch.ElapsedMilliseconds, BodyString = finalResponseBody ?? string.Empty, Body = responseBodyObject, Header = responseHeader }; var level = LogEventLevel.Information; if (finalStatusCode >= 500) { level = LogEventLevel.Error; } else if (finalStatusCode >= 400) { level = LogEventLevel.Warning; } var props = endpoint?.Metadata?.GetOrderedMetadata <LogCustomPropertyAttribute>()? .ToDictionary(x => x.Name, x => x.Value); if (!collector.TryComplete(out var collectedProperties)) { collectedProperties = NoProperties; } _logger.Write(level, ex, DefaultRequestCompletionMessageTemplate, new { Request = requestData, Response = responseData, Properties = props, Context = collectedProperties.ToDictionary(x => x.Name, x => x.Value.ToString()), }); } }