ソースを参照

fix: 修复 DatabaseLoggingWriter 日志写入失败 unhandled exception 导致程序崩溃

许俊杰 2 年 前
コミット
fb9e09542a
1 ファイル変更84 行追加70 行削除
  1. 84 70
      Admin.NET/Admin.NET.Core/Logging/DatabaseLoggingWriter.cs

+ 84 - 70
Admin.NET/Admin.NET.Core/Logging/DatabaseLoggingWriter.cs

@@ -18,9 +18,10 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
 {
     private readonly IServiceScope _serviceScope;
     private readonly SqlSugarRepository<SysLogVis> _sysLogVisRep; // 访问日志
-    private readonly SqlSugarRepository<SysLogOp> _sysLogOpRep;   // 操作日志
-    private readonly SqlSugarRepository<SysLogEx> _sysLogExRep;   // 异常日志
+    private readonly SqlSugarRepository<SysLogOp> _sysLogOpRep; // 操作日志
+    private readonly SqlSugarRepository<SysLogEx> _sysLogExRep; // 异常日志
     private readonly SysConfigService _sysConfigService; // 参数配置服务
+    private readonly ILogger<DatabaseLoggingWriter> _logger; // 日志组件
 
     public DatabaseLoggingWriter(IServiceScopeFactory scopeFactory)
     {
@@ -29,6 +30,7 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
         _sysLogOpRep = _serviceScope.ServiceProvider.GetRequiredService<SqlSugarRepository<SysLogOp>>();
         _sysLogExRep = _serviceScope.ServiceProvider.GetRequiredService<SqlSugarRepository<SysLogEx>>();
         _sysConfigService = _serviceScope.ServiceProvider.GetRequiredService<SysConfigService>();
+        _logger = _serviceScope.ServiceProvider.GetRequiredService<ILogger<DatabaseLoggingWriter>>();
     }
 
     public async void Write(LogMessage logMsg, bool flush)
@@ -64,10 +66,79 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
         var browser = $"{client.UA.Family} {client.UA.Major}.{client.UA.Minor} / {client.Device.Family}";
         var os = $"{client.OS.Family} {client.OS.Major} {client.OS.Minor}";
 
-        // 记录异常日志并发送邮件
-        if (logMsg.Exception != null || loggingMonitor.exception != null)
+        // 捕捉异常,否则会由于 unhandled exception 导致程序崩溃
+        try
         {
-            await _sysLogExRep.InsertAsync(new SysLogEx
+            // 记录异常日志并发送邮件
+            if (logMsg.Exception != null || loggingMonitor.exception != null)
+            {
+                await _sysLogExRep.InsertAsync(new SysLogEx
+                {
+                    ControllerName = loggingMonitor.controllerName,
+                    ActionName = loggingMonitor.actionTypeName,
+                    DisplayTitle = loggingMonitor.displayTitle,
+                    Status = loggingMonitor.returnInformation?.httpStatusCode,
+                    RemoteIp = remoteIPv4,
+                    Location = ipLocation,
+                    Longitude = longitude,
+                    Latitude = latitude,
+                    Browser = browser, // loggingMonitor.userAgent,
+                    Os = os, // loggingMonitor.osDescription + " " + loggingMonitor.osArchitecture,
+                    Elapsed = loggingMonitor.timeOperationElapsedMilliseconds,
+                    LogDateTime = logMsg.LogDateTime,
+                    Account = account,
+                    RealName = realName,
+                    HttpMethod = loggingMonitor.httpMethod,
+                    RequestUrl = loggingMonitor.requestUrl,
+                    RequestParam = (loggingMonitor.parameters == null || loggingMonitor.parameters.Count == 0) ? null : JSON.Serialize(loggingMonitor.parameters[0].value),
+                    ReturnResult = loggingMonitor.returnInformation == null ? null : JSON.Serialize(loggingMonitor.returnInformation),
+                    EventId = logMsg.EventId.Id,
+                    ThreadId = logMsg.ThreadId,
+                    TraceId = logMsg.TraceId,
+                    Exception = JSON.Serialize(loggingMonitor.exception),
+                    Message = logMsg.Message,
+                    CreateUserId = string.IsNullOrWhiteSpace(userId) ? 0 : long.Parse(userId),
+                    TenantId = string.IsNullOrWhiteSpace(tenantId) ? 0 : long.Parse(tenantId),
+                    LogLevel = logMsg.LogLevel
+                });
+
+                // 将异常日志发送到邮件
+                await App.GetRequiredService<IEventPublisher>().PublishAsync("Send:ErrorMail", loggingMonitor.exception);
+
+                return;
+            }
+
+            // 记录访问日志-登录登出
+            if (loggingMonitor.actionName == "userInfo" || loggingMonitor.actionName == "logout")
+            {
+                await _sysLogVisRep.InsertAsync(new SysLogVis
+                {
+                    ControllerName = loggingMonitor.controllerName,
+                    ActionName = loggingMonitor.actionTypeName,
+                    DisplayTitle = loggingMonitor.displayTitle,
+                    Status = loggingMonitor.returnInformation?.httpStatusCode,
+                    RemoteIp = remoteIPv4,
+                    Location = ipLocation,
+                    Longitude = longitude,
+                    Latitude = latitude,
+                    Browser = browser, // loggingMonitor.userAgent,
+                    Os = os, // loggingMonitor.osDescription + " " + loggingMonitor.osArchitecture,
+                    Elapsed = loggingMonitor.timeOperationElapsedMilliseconds,
+                    LogDateTime = logMsg.LogDateTime,
+                    Account = account,
+                    RealName = realName,
+                    CreateUserId = string.IsNullOrWhiteSpace(userId) ? 0 : long.Parse(userId),
+                    TenantId = string.IsNullOrWhiteSpace(tenantId) ? 0 : long.Parse(tenantId),
+                    LogLevel = logMsg.LogLevel
+                });
+
+                return;
+            }
+
+            // 记录操作日志
+            var enabledSysOpLog = await _sysConfigService.GetConfigValue<bool>(CommonConst.SysOpLog);
+            if (!enabledSysOpLog) return;
+            await _sysLogOpRep.InsertAsync(new SysLogOp
             {
                 ControllerName = loggingMonitor.controllerName,
                 ActionName = loggingMonitor.actionTypeName,
@@ -90,78 +161,17 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
                 EventId = logMsg.EventId.Id,
                 ThreadId = logMsg.ThreadId,
                 TraceId = logMsg.TraceId,
-                Exception = JSON.Serialize(loggingMonitor.exception),
+                Exception = loggingMonitor.exception == null ? null : JSON.Serialize(loggingMonitor.exception),
                 Message = logMsg.Message,
                 CreateUserId = string.IsNullOrWhiteSpace(userId) ? 0 : long.Parse(userId),
                 TenantId = string.IsNullOrWhiteSpace(tenantId) ? 0 : long.Parse(tenantId),
                 LogLevel = logMsg.LogLevel
             });
-
-            // 将异常日志发送到邮件
-            await App.GetRequiredService<IEventPublisher>().PublishAsync("Send:ErrorMail", loggingMonitor.exception);
-
-            return;
         }
-
-        // 记录访问日志-登录登出
-        if (loggingMonitor.actionName == "userInfo" || loggingMonitor.actionName == "logout")
+        catch (Exception ex)
         {
-            await _sysLogVisRep.InsertAsync(new SysLogVis
-            {
-                ControllerName = loggingMonitor.controllerName,
-                ActionName = loggingMonitor.actionTypeName,
-                DisplayTitle = loggingMonitor.displayTitle,
-                Status = loggingMonitor.returnInformation?.httpStatusCode,
-                RemoteIp = remoteIPv4,
-                Location = ipLocation,
-                Longitude = longitude,
-                Latitude = latitude,
-                Browser = browser, // loggingMonitor.userAgent,
-                Os = os, // loggingMonitor.osDescription + " " + loggingMonitor.osArchitecture,
-                Elapsed = loggingMonitor.timeOperationElapsedMilliseconds,
-                LogDateTime = logMsg.LogDateTime,
-                Account = account,
-                RealName = realName,
-                CreateUserId = string.IsNullOrWhiteSpace(userId) ? 0 : long.Parse(userId),
-                TenantId = string.IsNullOrWhiteSpace(tenantId) ? 0 : long.Parse(tenantId),
-                LogLevel = logMsg.LogLevel
-            });
-
-            return;
+            _logger.LogError(ex, ex.Message);
         }
-
-        // 记录操作日志
-        var enabledSysOpLog = await _sysConfigService.GetConfigValue<bool>(CommonConst.SysOpLog);
-        if (!enabledSysOpLog) return;
-        await _sysLogOpRep.InsertAsync(new SysLogOp
-        {
-            ControllerName = loggingMonitor.controllerName,
-            ActionName = loggingMonitor.actionTypeName,
-            DisplayTitle = loggingMonitor.displayTitle,
-            Status = loggingMonitor.returnInformation?.httpStatusCode,
-            RemoteIp = remoteIPv4,
-            Location = ipLocation,
-            Longitude = longitude,
-            Latitude = latitude,
-            Browser = browser, // loggingMonitor.userAgent,
-            Os = os, // loggingMonitor.osDescription + " " + loggingMonitor.osArchitecture,
-            Elapsed = loggingMonitor.timeOperationElapsedMilliseconds,
-            LogDateTime = logMsg.LogDateTime,
-            Account = account,
-            RealName = realName,
-            HttpMethod = loggingMonitor.httpMethod,
-            RequestUrl = loggingMonitor.requestUrl,
-            RequestParam = (loggingMonitor.parameters == null || loggingMonitor.parameters.Count == 0) ? null : JSON.Serialize(loggingMonitor.parameters[0].value),
-            ReturnResult = loggingMonitor.returnInformation == null ? null : JSON.Serialize(loggingMonitor.returnInformation),
-            EventId = logMsg.EventId.Id,
-            ThreadId = logMsg.ThreadId,
-            TraceId = logMsg.TraceId,
-            Exception = loggingMonitor.exception == null ? null : JSON.Serialize(loggingMonitor.exception),
-            Message = logMsg.Message,
-            CreateUserId = string.IsNullOrWhiteSpace(userId) ? 0 : long.Parse(userId),
-            TenantId = string.IsNullOrWhiteSpace(tenantId) ? 0 : long.Parse(tenantId),
-            LogLevel = logMsg.LogLevel
-        });
     }
 
     /// <summary>
@@ -177,7 +187,11 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
             var addressList = new List<string>() { ipInfo.Country, ipInfo.Province, ipInfo.City, ipInfo.NetworkOperator };
             return (string.Join("|", addressList.Where(it => it != "0").ToList()), ipInfo.Longitude, ipInfo.Latitude); // 去掉0并用|连接
         }
-        catch { }
+        catch
+        {
+            // 不做处理
+        }
+
         return ("未知", 0, 0);
     }