private async Task SafeLog(DateTime requestTime, long responseMillis, int statusCode, string method, string path, string queryString, string requestBody, string responseBody, string ipAddress, ApplicationUser user) { // Do not log these events login, logout, getuserinfo... if ((path.ToLower().StartsWith("/api/account/")) || (path.ToLower().StartsWith("/api/UserProfile/"))) { return; } if (requestBody.Length > 256) { requestBody = $"(Truncated to 200 chars) {requestBody.Substring(0, 200)}"; } // If the response body was an ApiResponse we should just save the Result object if (responseBody.Contains("\"result\":")) { try { ApiResponse apiResponse = JsonConvert.DeserializeObject <ApiResponse>(responseBody); responseBody = Regex.Replace(apiResponse.Result.ToString(), @"(""[^""\\]*(?:\\.[^""\\]*)*"")|\s+", "$1"); } catch { } } if (responseBody.Length > 256) { responseBody = $"(Truncated to 200 chars) {responseBody.Substring(0, 200)}"; } if (queryString.Length > 256) { queryString = $"(Truncated to 200 chars) {queryString.Substring(0, 200)}"; } await _apiLogService.Log(new ApiLogItem { RequestTime = requestTime, ResponseMillis = responseMillis, StatusCode = statusCode, Method = method, Path = path, QueryString = queryString, RequestBody = requestBody, ResponseBody = responseBody ?? String.Empty, IPAddress = ipAddress, ApplicationUserId = user == null ? Guid.Empty : user.Id }); }
public async Task InvokeAsync(HttpContext httpContext) { try { var request = httpContext.Request; if (IsSwagger(httpContext) || request.Path.StartsWithSegments(new PathString("/test"))) { await _next(httpContext); } else { Stopwatch stopWatch = Stopwatch.StartNew(); var requestTime = DateTime.UtcNow; var formattedRequest = await FormatRequest(request); var originalBodyStream = httpContext.Response.Body; using (var responseBody = new MemoryStream()) { httpContext.Response.Body = responseBody; try { var response = httpContext.Response; response.Body = responseBody; await _next.Invoke(httpContext); string responseBodyContent = null; if (httpContext.Response.StatusCode == (int)HttpStatusCode.OK) { responseBodyContent = await FormatResponse(response); await HandleSuccessRequestAsync(httpContext, responseBodyContent, httpContext.Response.StatusCode); } else { await HandleNotSuccessRequestAsync(httpContext, httpContext.Response.StatusCode); } stopWatch.Stop(); #region Log Request / Response if (_enableAPILogging) { try { await responseBody.CopyToAsync(originalBodyStream); await _apiLogService.Log(new ApiLogItem { RequestTime = requestTime, ResponseMillis = stopWatch.ElapsedMilliseconds, StatusCode = response.StatusCode, Method = request.Method, Path = request.Path, QueryString = request.QueryString.ToString(), RequestBody = formattedRequest, ResponseBody = responseBodyContent, IPAddress = httpContext.Connection.RemoteIpAddress.ToString() }); } catch (Exception ex) { _logger.LogWarning("An Inner Middleware exception occurred on SafeLog: " + ex.Message); } } #endregion } catch (System.Exception ex) { _logger.LogWarning("An Inner Middleware exception occurred: " + ex.Message); await HandleExceptionAsync(httpContext, ex); } finally { responseBody.Seek(0, SeekOrigin.Begin); await responseBody.CopyToAsync(originalBodyStream); } } } } catch (Exception ex) { // We can't do anything if the response has already started, just abort. if (httpContext.Response.HasStarted) { _logger.LogWarning("A Middleware exception occurred, but response has already started!"); throw; } await HandleExceptionAsync(httpContext, ex); throw; } }
private async Task SafeLog(DateTime requestTime, long responseMillis, int statusCode, string method, string path, string queryString, string requestBody, string responseBody, string ipAddress, ApplicationUser user) { // Do not log these events login, logout, getuserinfo... if ((path.ToLower().StartsWith("/api/account/")) || (path.ToLower().StartsWith("/api/UserProfile/")) || (method.ToLower() == "get" && path.Count(c => c == '/') == 2) // Do not log 'GET all' events like: /api/todo ) { return; } //Uncomment if truncation is needed //if (requestBody.Length > 256) //{ // requestBody = $"(Truncated to 200 chars) {requestBody.Substring(0, 200)}"; //} // If the response body was an ApiResponse we should just save the Result object if (responseBody.Contains("\"result\":")) { try { ApiResponse apiResponse = JsonConvert.DeserializeObject <ApiResponse>(responseBody); responseBody = Regex.Replace(apiResponse.Result.ToString(), @"(""[^""\\]*(?:\\.[^""\\]*)*"")|\s+", "$1"); } catch { } } //Uncomment if truncation is needed //if (responseBody.Length > 256) //{ // responseBody = $"(Truncated to 200 chars) {responseBody.Substring(0, 200)}"; //} if (queryString.Length > 256) { queryString = $"(Truncated to 200 chars) {queryString.Substring(0, 200)}"; } if (method.ToUpper() == "PUT") { JObject item = JObject.Parse(requestBody.Substring(requestBody.IndexOf('{'))); var resp = await _apiLogService.GetLastGet(path + "/" + item["id"].Value <string>(), user.Id); if (resp != null && resp.StatusCode == 200) { //ApiLogItem oldItem = JsonConvert.DeserializeObject<ApiLogItem>(resp.Result.ToString()); responseBody = "[" + responseBody + "," + resp.ResponseBody + "]"; } } await _apiLogService.Log(new ApiLogItem { RequestTime = requestTime, ResponseMillis = responseMillis, StatusCode = statusCode, Method = method, Path = path, QueryString = queryString, RequestBody = requestBody, ResponseBody = responseBody ?? String.Empty, IPAddress = ipAddress, ApplicationUserId = user == null ? Guid.Empty : user.Id }); }