No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

LoggingMiddleware.cs 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using Confluent.Kafka;
  2. using Microsoft.AspNetCore.Http;
  3. using Newtonsoft.Json;
  4. using System.Net;
  5. using System.Text;
  6. using TelpoKafkaConsole.Common;
  7. using TelpoKafkaConsole.WebApi.Controllers.Api;
  8. namespace TelpoKafkaConsole.WebApi.Middleware
  9. {
  10. public class LoggingMiddleware
  11. {
  12. private readonly RequestDelegate _next;
  13. private readonly ILogger<LoggingMiddleware> _logger;
  14. public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger)
  15. {
  16. _next = next;
  17. _logger = logger;
  18. }
  19. //public async Task InvokeAsync(HttpContext context)
  20. //{
  21. // //// 在请求处理之前记录日志
  22. // //using (_logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = "" }))
  23. // using (new CustomizeStopWatch(nameof(LoggingMiddleware), _logger))
  24. // {
  25. // var request = await FormatRequest(context.Request);
  26. // _logger.LogInformation(request);
  27. // var originalBodyStream = context.Response.Body;
  28. // using var responseBody = new MemoryStream();
  29. // context.Response.Body = responseBody;
  30. // await _next(context);
  31. // var response = await FormatResponse(context.Response);
  32. // _logger.LogInformation(response);
  33. // await responseBody.CopyToAsync(originalBodyStream);
  34. // }
  35. //}
  36. public async Task InvokeAsync(HttpContext context)
  37. {
  38. //// 在请求处理之前记录日志
  39. //using (_logger.BeginScope(new Dictionary<string, object> { ["RequestId"] = "" }))
  40. using (new CustomizeStopWatch(nameof(LoggingMiddleware), _logger))
  41. {
  42. using var responseBody = new MemoryStream();
  43. var originalBodyStream = context.Response.Body;
  44. try
  45. {
  46. var request = await FormatRequest(context.Request);
  47. _logger.LogInformation(request);
  48. context.Response.Body = responseBody;
  49. await _next(context);
  50. var response = await FormatResponse(context.Response);
  51. _logger.LogInformation(response);
  52. // await responseBody.CopyToAsync(originalBodyStream);
  53. }
  54. catch (Exception ex)
  55. {
  56. await HandleExceptionAsync(context, ex); // 捕获异常了 在HandleExceptionAsync中处理
  57. }
  58. //var response = await FormatResponse(context.Response);
  59. //_logger.LogInformation(response);
  60. await responseBody.CopyToAsync(originalBodyStream);
  61. }
  62. }
  63. private async Task<string> FormatRequest(HttpRequest request)
  64. {
  65. request.EnableBuffering();
  66. var body = await new StreamReader(request.Body).ReadToEndAsync();
  67. var formattedBody = FormatJson(body);
  68. request.Body.Position = 0;
  69. return $"请求: {request.Scheme} {request.Host}{request.Path} {request.QueryString} {formattedBody}";
  70. }
  71. private async Task<string> FormatResponse(HttpResponse response)
  72. {
  73. response.Body.Seek(0, SeekOrigin.Begin);
  74. var body = await new StreamReader(response.Body).ReadToEndAsync();
  75. var formattedBody = FormatJson(body);
  76. response.Body.Seek(0, SeekOrigin.Begin);
  77. return $"响应: {response.StatusCode}: {formattedBody}";
  78. }
  79. private static string FormatJson(string json)
  80. {
  81. if (string.IsNullOrEmpty(json))
  82. {
  83. return string.Empty;
  84. }
  85. try
  86. {
  87. var obj = JsonConvert.DeserializeObject(json);
  88. // return JsonConvert.SerializeObject(obj, Formatting.Indented);
  89. return JsonConvert.SerializeObject(obj);
  90. }
  91. catch
  92. {
  93. return json;
  94. }
  95. }
  96. private async Task HandleExceptionAsync(HttpContext context, Exception exception)
  97. {
  98. context.Response.ContentType = "application/json"; // 返回json 类型
  99. var response = context.Response;
  100. var errorResponse = new ErrorResponse
  101. {
  102. Success = false
  103. }; // 自定义的异常错误信息类型
  104. switch (exception)
  105. {
  106. case ApplicationException ex:
  107. if (ex.Message.Contains("Invalid token"))
  108. {
  109. response.StatusCode = (int)HttpStatusCode.Forbidden;
  110. errorResponse.Message = ex.Message;
  111. break;
  112. }
  113. response.StatusCode = (int)HttpStatusCode.BadRequest;
  114. errorResponse.Message = ex.Message;
  115. break;
  116. case KeyNotFoundException ex:
  117. response.StatusCode = (int)HttpStatusCode.NotFound;
  118. errorResponse.Message = ex.Message;
  119. break;
  120. default:
  121. response.StatusCode = (int)HttpStatusCode.InternalServerError;
  122. errorResponse.Message = "Internal Server errors. Check Logs!";
  123. break;
  124. }
  125. //var apiResponse = ApiResponse<object>.Fail(response.StatusCode, $"{exception.Message}\n{exception.InnerException}\n{exception.StackTrace}");
  126. var apiResponse = ApiResponse<object>.Fail(response.StatusCode, $"{exception.Message}");
  127. var resultJson = JsonConvert.SerializeObject(apiResponse);
  128. var resultBytes = Encoding.UTF8.GetBytes(resultJson);
  129. await response.Body.WriteAsync(resultBytes, 0, resultBytes.Length);
  130. var responseStr = await FormatResponse(context.Response);
  131. _logger.LogError(responseStr);
  132. }
  133. internal class ErrorResponse
  134. {
  135. public bool Success { get; set; }
  136. public string Message { get; set; } = String.Empty;
  137. }
  138. }
  139. }