LoggingMiddleware.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Mvc.Controllers;
  3. using Microsoft.Data.SqlClient;
  4. using Microsoft.Extensions.Primitives;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Net;
  10. using System.Net.Sockets;
  11. using System.Text;
  12. using System.Text.Json;
  13. using System.Threading.Tasks;
  14. using Microsoft.AspNetCore.Mvc;
  15. using MTWorkHR.Core.UnitOfWork;
  16. using MTWorkHR.Application.Services;
  17. using MTWorkHR.Core.Global;
  18. using Microsoft.Extensions.Logging;
  19. namespace MTWorkHR.Application.Middlewares
  20. {
  21. public class LoggingMiddleware
  22. {
  23. private readonly RequestDelegate _next;
  24. private readonly ILogger<LoggingMiddleware> _logger;
  25. public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger)
  26. {
  27. _next = next;
  28. _logger = logger;
  29. }
  30. public async Task Invoke(HttpContext context, IUnitOfWorkLog unitOfWork)
  31. {
  32. try
  33. {
  34. await _next(context);
  35. }
  36. catch (Exception error)
  37. {
  38. //Get target controller info
  39. _logger.LogError(error, "An error occurred during request processing");
  40. var controllerActionDescriptor = context?
  41. .GetEndpoint()?
  42. .Metadata
  43. .GetMetadata<ControllerActionDescriptor>();
  44. //get controllerName & actionName
  45. var controllerName = controllerActionDescriptor?.ControllerName;
  46. var actionName = controllerActionDescriptor?.ActionName;
  47. //get QueryString
  48. var req = context?.Request;
  49. var QueryString = req?.QueryString.Value?.ToString();
  50. // get request body
  51. string bodyStr;
  52. req.EnableBuffering();
  53. req.Body.Seek(0, SeekOrigin.Begin);
  54. req.Body.Position = 0;
  55. using (StreamReader reader
  56. = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true))
  57. {
  58. bodyStr = await reader.ReadToEndAsync();
  59. }
  60. //**Get Log service and entity info by refliction
  61. //Get target log entity by the traget controller name
  62. Type? entityType = Type.GetType("MTWorkHR.Core.Entities." + "User" + "Log, MTWorkHR.Core");
  63. var logServiceWithGenericType = typeof(LogService<>).MakeGenericType(entityType);
  64. dynamic service = Activator.CreateInstance(logServiceWithGenericType, new object[] { unitOfWork });
  65. var msg = error is AppException ? ((AppException)error).ErrorMessage : error.Message;
  66. var errorNum = error is AppException ? ((AppException)error).ErrorNumber : 0;
  67. // int errorNum = 0;
  68. // int.TryParse(errorNo, out errorNum);
  69. dynamic logEnitity = Activator.CreateInstance(entityType, new object[] {
  70. controllerName+"/"+actionName, QueryString, bodyStr, DateTime.Now, "",GetLocalIPAddress(), GetServerIp(context), GetUserExternalIp(context), "", "", msg, error?.InnerException?.Message });
  71. //finally call service.create to insert the log
  72. await service.Create(logEnitity);
  73. //****
  74. switch (error)
  75. {
  76. case AppException e:
  77. {
  78. context.Response.Clear();
  79. context.Response.ContentType = "text/plain";
  80. context.Response.StatusCode = StatusCodes.Status400BadRequest;
  81. context.Response.StatusCode = e.ErrorNumber switch
  82. {
  83. ExceptionEnum.EmailNotExist => StatusCodes.Status401Unauthorized,
  84. ExceptionEnum.NotAuthorized => StatusCodes.Status401Unauthorized,
  85. ExceptionEnum.WrongCredentials => StatusCodes.Status401Unauthorized,
  86. _ => StatusCodes.Status400BadRequest
  87. };
  88. await context.Response.WriteAsJsonAsync(
  89. new BadRequestResult
  90. {
  91. ErrorMsg = errorNum ==0 ? "Internal Server Error" : "" + ((AppException)error).ErrorMessage + "",
  92. ErrorNo = (int)errorNum
  93. });
  94. return;
  95. }
  96. default:
  97. {
  98. context.Response.Clear();
  99. context.Response.ContentType = "text/plain";
  100. context.Response.StatusCode = StatusCodes.Status500InternalServerError;
  101. await context.Response.WriteAsync( "Internal Server Error" );
  102. return;
  103. }
  104. }
  105. }
  106. }
  107. public static string GetServerIp(HttpContext context)
  108. {
  109. try
  110. {
  111. IPAddress ipAddressString = context.Connection.LocalIpAddress;
  112. string REMOTE_ADDR = context.GetServerVariable("REMOTE_ADDR");
  113. string LOCAL_ADDR = context.GetServerVariable("LOCAL_ADDR");
  114. string SERVER_ADDR = context.GetServerVariable("SERVER_ADDR");
  115. string REMOTE_HOST = context.GetServerVariable("REMOTE_HOST");
  116. string result = "LocalIpAddress: "+ipAddressString.ToString();
  117. result += " REMOTE_ADDR: " + REMOTE_ADDR + " LOCAL_ADDR:" + LOCAL_ADDR
  118. + " SERVER_ADDR:" + SERVER_ADDR + " REMOTE_HOST:" + REMOTE_HOST;
  119. return result;
  120. }
  121. catch (Exception e)
  122. {
  123. return "";
  124. }
  125. }
  126. public static string GetLocalIPAddress()
  127. {
  128. try
  129. {
  130. var host = Dns.GetHostEntry(Dns.GetHostName());
  131. foreach (var ip in host.AddressList)
  132. {
  133. if (ip.AddressFamily == AddressFamily.InterNetwork)
  134. {
  135. return ip.ToString();
  136. }
  137. }
  138. return "";
  139. }
  140. catch (Exception e)
  141. {
  142. return "";
  143. }
  144. }
  145. public static string GetUserExternalIp(HttpContext context)
  146. {
  147. try
  148. {
  149. IPAddress remoteIpAddress = context.Connection.RemoteIpAddress;
  150. string result = "";
  151. if (remoteIpAddress != null)
  152. {
  153. // If we got an IPV6 address, then we need to ask the network for the IPV4 address
  154. // This usually only happens when the browser is on the same machine as the server.
  155. if (remoteIpAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
  156. {
  157. remoteIpAddress = System.Net.Dns.GetHostEntry(remoteIpAddress).AddressList
  158. .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
  159. }
  160. result = remoteIpAddress.ToString();
  161. }
  162. return result;
  163. }
  164. catch (Exception e)
  165. {
  166. return "";
  167. }
  168. }
  169. }
  170. public class BadRequestResult
  171. {
  172. public string ErrorMsg { get; set; }
  173. public int ErrorNo { get; set; }
  174. }
  175. }