AuditLog.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. using System.ComponentModel.DataAnnotations.Schema;
  2. using Abp.Auditing;
  3. using Abp.Domain.Entities;
  4. using Abp.Extensions;
  5. using Abp.Runtime.Validation;
  6. using Abp.UI;
  7. namespace VberZero.BaseSystem;
  8. /// <summary>
  9. ///
  10. /// </summary>
  11. [Table("Sys_AuditLogs")]
  12. public class AuditLog : Entity<long>, IMayHaveTenant
  13. {
  14. public static int MaxServiceNameLength = 256;
  15. public static int MaxMethodNameLength = 256;
  16. public static int MaxParametersLength = 1024;
  17. public static int MaxReturnValueLength = 1024;
  18. public static int MaxClientIpAddressLength = 64;
  19. public static int MaxClientNameLength = 128;
  20. public static int MaxBrowserInfoLength = 512;
  21. public static int MaxExceptionMessageLength = 1024;
  22. public static int MaxExceptionLength = 2000;
  23. public static int MaxCustomDataLength = 2000;
  24. public virtual int? TenantId { get; set; }
  25. public virtual long? UserId { get; set; }
  26. /// <summary>
  27. /// 服务(类/接口)名称
  28. /// </summary>
  29. public virtual string ServiceName { get; set; }
  30. /// <summary>
  31. /// 执行的方法名称
  32. /// </summary>
  33. public virtual string MethodName { get; set; }
  34. /// <summary>
  35. /// 服务(类/接口)名称 (Lang)
  36. /// </summary>
  37. public virtual string ServiceNameLang { get; set; }
  38. /// <summary>
  39. /// 执行的方法名称 (Lang)
  40. /// </summary>
  41. public virtual string MethodNameLang { get; set; }
  42. /// <summary>
  43. /// 调用参数
  44. /// </summary>
  45. public virtual string Parameters { get; set; }
  46. /// <summary>
  47. /// 返回值
  48. /// </summary>
  49. public virtual string ReturnValue { get; set; }
  50. /// <summary>
  51. /// 方法执行的开始时间。
  52. /// </summary>
  53. public virtual DateTime ExecutionTime { get; set; }
  54. /// <summary>
  55. /// 方法调用的总持续时间(以毫秒为单位)。
  56. /// </summary>
  57. public virtual int ExecutionDuration { get; set; }
  58. /// <summary>
  59. /// 客户端的 IP 地址。
  60. /// </summary>
  61. public virtual string ClientIpAddress { get; set; }
  62. /// <summary>
  63. /// 客户端的名称(通常是计算机名称)。
  64. /// </summary>
  65. public virtual string ClientName { get; set; }
  66. /// <summary>
  67. /// 如果在 Web 请求中调用此方法,则浏览器信息。
  68. /// </summary>
  69. public virtual string BrowserInfo { get; set; }
  70. /// <summary>
  71. /// 存储<see cref="Exception"/>的消息内容。
  72. /// </summary>
  73. public virtual string ExceptionMessage { get; set; }
  74. /// <summary>
  75. /// 异常对象,如果在方法执行期间发生异常。
  76. /// </summary>
  77. public virtual string Exception { get; set; }
  78. /// <summary>
  79. /// <see cref="AuditInfo.ImpersonatorUserId"/>.
  80. /// </summary>
  81. public virtual long? ImpersonatorUserId { get; set; }
  82. /// <summary>
  83. /// <see cref="AuditInfo.ImpersonatorTenantId"/>.
  84. /// </summary>
  85. public virtual int? ImpersonatorTenantId { get; set; }
  86. /// <summary>
  87. /// <see cref="AuditInfo.CustomData"/>.
  88. /// </summary>
  89. public virtual string CustomData { get; set; }
  90. public virtual int LogType { get; set; }
  91. /// <summary>
  92. /// 从给定的 <paramref name="auditInfo"/> 创建一个新的 CreateFromAuditInfo。
  93. /// </summary>
  94. /// <param name="auditInfo"></param>
  95. public static AuditLog CreateFromAuditInfo(AuditInfo auditInfo)
  96. {
  97. var exceptionMessage = GetAbpClearException(auditInfo.Exception);
  98. return new AuditLog
  99. {
  100. TenantId = auditInfo.TenantId,
  101. UserId = auditInfo.UserId,
  102. LogType = 0,
  103. ServiceName = auditInfo.ServiceName.TruncateWithPostfix(MaxServiceNameLength),
  104. MethodName = auditInfo.MethodName.TruncateWithPostfix(MaxMethodNameLength),
  105. Parameters = auditInfo.Parameters.TruncateWithPostfix(MaxParametersLength),
  106. ReturnValue = auditInfo.ReturnValue.TruncateWithPostfix(MaxReturnValueLength),
  107. ExecutionTime = auditInfo.ExecutionTime,
  108. ExecutionDuration = auditInfo.ExecutionDuration,
  109. ClientIpAddress = auditInfo.ClientIpAddress.TruncateWithPostfix(MaxClientIpAddressLength),
  110. ClientName = auditInfo.ClientName.TruncateWithPostfix(MaxClientNameLength),
  111. BrowserInfo = auditInfo.BrowserInfo.TruncateWithPostfix(MaxBrowserInfoLength),
  112. Exception = exceptionMessage.TruncateWithPostfix(MaxExceptionLength),
  113. ExceptionMessage = auditInfo.Exception?.Message.TruncateWithPostfix(MaxExceptionMessageLength),
  114. ImpersonatorUserId = auditInfo.ImpersonatorUserId,
  115. ImpersonatorTenantId = auditInfo.ImpersonatorTenantId,
  116. CustomData = auditInfo.CustomData.TruncateWithPostfix(MaxCustomDataLength)
  117. };
  118. }
  119. public override string ToString()
  120. {
  121. return
  122. $"AUDIT LOG: {ServiceName}.{MethodName} is executed by user {UserId} in {ExecutionDuration} ms from {ClientIpAddress} IP address.";
  123. }
  124. /// <summary>
  125. /// 使审计异常更加明确
  126. /// </summary>
  127. /// <param name="exception"></param>
  128. /// <returns></returns>
  129. public static string GetAbpClearException(Exception exception)
  130. {
  131. var clearMessage = "";
  132. switch (exception)
  133. {
  134. case null:
  135. return null;
  136. case AbpValidationException abpValidationException:
  137. clearMessage = "共有" + abpValidationException.ValidationErrors.Count + "条验证错误:";
  138. foreach (var validationResult in abpValidationException.ValidationErrors)
  139. {
  140. var memberNames = "";
  141. if (validationResult.MemberNames.Any())
  142. {
  143. memberNames = " (" + string.Join(", ", validationResult.MemberNames) + ")";
  144. }
  145. clearMessage += "\r\n" + validationResult.ErrorMessage + memberNames;
  146. }
  147. break;
  148. case UserFriendlyException userFriendlyException:
  149. clearMessage =
  150. $"错误代码:{userFriendlyException.Code}\r\n错误信息:{userFriendlyException.Details}";
  151. break;
  152. }
  153. return exception + (clearMessage.IsNullOrWhiteSpace() ? "" : "\r\n\r\n" + clearMessage);
  154. }
  155. }