|
- using HealthMonitor.Common;
- using HealthMonitor.WebApi.Controllers.Api;
- using Microsoft.AspNetCore.Http;
- using Microsoft.Extensions.Logging;
- using Newtonsoft.Json;
- using System.IO;
- using System.Net;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.Text;
-
- namespace HealthMonitor.WebApi.Middleware
- {
- public class LoggingMiddleware
- {
- private readonly RequestDelegate _next;
- private readonly ILogger<LoggingMiddleware> _logger;
-
- public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger)
- {
- _next = next;
- _logger = logger;
- }
-
- //public async Task InvokeAsync(HttpContext context)
- //{
- // //// 在请求处理之前记录日志
- // //using (_logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = "" }))
- // using (new CustomizeStopWatch(nameof(LoggingMiddleware), _logger))
- // {
- // var request = await FormatRequest(context.Request);
-
- // _logger.LogInformation(request);
-
- // var originalBodyStream = context.Response.Body;
-
- // using var responseBody = new MemoryStream();
- // context.Response.Body = responseBody;
-
- // await _next(context);
-
- // var response = await FormatResponse(context.Response);
-
- // _logger.LogInformation(response);
-
- // await responseBody.CopyToAsync(originalBodyStream);
- // }
- //}
-
- public async Task InvokeAsync(HttpContext context)
- {
- //// 在请求处理之前记录日志
- //using (_logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = "" }))
- using (new CustomizeStopWatch(nameof(LoggingMiddleware), _logger))
- {
- using var responseBody = new MemoryStream();
- var originalBodyStream = context.Response.Body;
- try
- {
-
- var request = await FormatRequest(context.Request);
- _logger.LogInformation(request);
- context.Response.Body = responseBody;
- await _next(context);
- }
- catch (Exception ex)
- {
- await HandleExceptionAsync(context, ex); // 捕获异常了 在HandleExceptionAsync中处理
- }
-
- var response = await FormatResponse(context.Response);
- _logger.LogInformation(response);
- await responseBody.CopyToAsync(originalBodyStream);
- }
- }
-
- private async Task<string> FormatRequest(HttpRequest request)
- {
- request.EnableBuffering();
-
- var body = await new StreamReader(request.Body).ReadToEndAsync();
- var formattedBody = FormatJson(body);
-
- request.Body.Position = 0;
-
- return $"请求: {request.Scheme} {request.Host}{request.Path} {request.QueryString} {formattedBody}";
- }
-
- private async Task<string> FormatResponse(HttpResponse response)
- {
- response.Body.Seek(0, SeekOrigin.Begin);
-
- var body = await new StreamReader(response.Body).ReadToEndAsync();
- var formattedBody = FormatJson(body);
-
- response.Body.Seek(0, SeekOrigin.Begin);
-
- return $"响应: {response.StatusCode}: {formattedBody}";
- }
-
- private static string FormatJson(string json)
- {
- if (string.IsNullOrEmpty(json))
- {
- return string.Empty;
- }
-
- try
- {
- var obj = JsonConvert.DeserializeObject(json);
- // return JsonConvert.SerializeObject(obj, Formatting.Indented);
- return JsonConvert.SerializeObject(obj);
- }
- catch
- {
- return json;
- }
- }
-
- private async Task HandleExceptionAsync(HttpContext context, Exception exception)
- {
- context.Response.ContentType = "application/json"; // 返回json 类型
- var response = context.Response;
-
- var errorResponse = new ErrorResponse
- {
- Success = false
- }; // 自定义的异常错误信息类型
- switch (exception)
- {
- case ApplicationException ex:
- if (ex.Message.Contains("Invalid token"))
- {
- response.StatusCode = (int)HttpStatusCode.Forbidden;
- errorResponse.Message = ex.Message;
- break;
- }
- response.StatusCode = (int)HttpStatusCode.BadRequest;
- errorResponse.Message = ex.Message;
- break;
- case KeyNotFoundException ex:
- response.StatusCode = (int)HttpStatusCode.NotFound;
- errorResponse.Message = ex.Message;
- break;
- default:
- response.StatusCode = (int)HttpStatusCode.InternalServerError;
- errorResponse.Message = "Internal Server errors. Check Logs!";
- break;
- }
- //_logger.LogError(exception.Message);
- //var result =JsonConvert.SerializeObject(ApiResponse<object>.Fail(response.StatusCode, $"{exception.Message}"));
- //await context.Response.WriteAsync(JsonConvert.SerializeObject(result));
-
- // Create the error response using ApiResponse.Fail
- var apiResponse = ApiResponse<object>.Fail(response.StatusCode, $"{exception.Message}\n{exception.InnerException}\n{exception.StackTrace}");
-
- // Convert the ApiResponse to JSON string
- var resultJson = JsonConvert.SerializeObject(apiResponse);
-
- // Convert the JSON string to bytes using UTF-8 encoding
- var resultBytes = Encoding.UTF8.GetBytes(resultJson);
-
- await response.Body.WriteAsync(resultBytes, 0, resultBytes.Length);
-
- var responseStr = await FormatResponse(context.Response);
-
- _logger.LogError(responseStr);
- }
-
- internal class ErrorResponse
- {
- public bool Success { get; set; }
-
- public string Message { get; set; } = String.Empty;
- }
- }
- }
|