Browse Source

增加数据库日志写入器

zuohuaijun 3 years ago
parent
commit
8e807c3750

+ 0 - 1
Admin.NET/Admin.NET.Application/Service/TestService.cs

@@ -1,6 +1,5 @@
 using Admin.NET.Application.Const;
 using Furion.DatabaseAccessor;
-using Furion.Logging;
 using Microsoft.AspNetCore.Authorization;
 
 namespace Admin.NET.Application.Serice;

+ 3 - 3
Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj

@@ -20,9 +20,9 @@
 
   <ItemGroup>
     <PackageReference Include="Caching.CSRedis" Version="3.8.3" />
-    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="3.9.1" />
-    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="3.9.1" />
-    <PackageReference Include="Furion.Pure" Version="3.9.1" />
+    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="3.9.2" />
+    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="3.9.2" />
+    <PackageReference Include="Furion.Pure" Version="3.9.2" />
     <PackageReference Include="Magicodes.IE.Excel" Version="2.6.4" />
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.7" />
     <PackageReference Include="MySql.Data" Version="8.0.29" />

+ 14 - 63
Admin.NET/Admin.NET.Core/Admin.NET.Core.xml

@@ -775,79 +775,25 @@
             系统操作日志表
             </summary>
         </member>
-        <member name="P:Admin.NET.Core.SysLogOp.Success">
+        <!-- Badly formed XML comment ignored for member "P:Admin.NET.Core.SysLogOp.LogName" -->
+        <member name="P:Admin.NET.Core.SysLogOp.LogLevel">
             <summary>
-            是否执行成功(Y-是,N-否)
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.Message">
-            <summary>
-            具体消息
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.Ip">
-            <summary>
-            IP地址
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.Location">
-            <summary>
-            地址
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.Browser">
-            <summary>
-            浏览器
+            日志级别
             </summary>
         </member>
-        <member name="P:Admin.NET.Core.SysLogOp.Os">
+        <member name="P:Admin.NET.Core.SysLogOp.EventId">
             <summary>
-            操作系统
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.Url">
-            <summary>
-            请求地址
+            事件Id
             </summary>
         </member>
-        <member name="P:Admin.NET.Core.SysLogOp.ClassName">
-            <summary>
-            类名称
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.MethodName">
-            <summary>
-            方法名称
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.ReqMethod">
-            <summary>
-            请求方式(GET POST PUT DELETE)
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.Param">
-            <summary>
-            请求参数
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.Result">
-            <summary>
-            返回结果
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.ElapsedTime">
+        <member name="P:Admin.NET.Core.SysLogOp.Message">
             <summary>
-            耗时(毫秒)
+            日志消息
             </summary>
         </member>
-        <member name="P:Admin.NET.Core.SysLogOp.UserName">
+        <member name="P:Admin.NET.Core.SysLogOp.Exception">
             <summary>
-            账号名称
-            </summary>
-        </member>
-        <member name="P:Admin.NET.Core.SysLogOp.RealName">
-            <summary>
-            真实姓名
+            异常对象
             </summary>
         </member>
         <member name="T:Admin.NET.Core.SysLogVis">
@@ -2891,6 +2837,11 @@
             <param name="context"></param>
             <returns></returns>
         </member>
+        <member name="T:Admin.NET.Core.DbLoggingWriter">
+            <summary>
+            数据库日志写入器
+            </summary>
+        </member>
         <member name="T:Admin.NET.Core.CacheOptions">
             <summary>
             缓存配置选项

+ 18 - 87
Admin.NET/Admin.NET.Core/Entity/SysLogOp.cs

@@ -1,4 +1,6 @@
-namespace Admin.NET.Core;
+using Microsoft.Extensions.Logging;
+
+namespace Admin.NET.Core;
 
 /// <summary>
 /// 系统操作日志表
@@ -6,103 +8,32 @@
 [SugarTable("sys_log_op", "系统操作日志表")]
 public class SysLogOp : EntityBase
 {
-    /// <summary>
-    /// 是否执行成功(Y-是,N-否)
-    /// </summary>
-    [SugarColumn(ColumnDescription = "是否执行成功")]
-    public YesNoEnum Success { get; set; }
-
-    /// <summary>
-    /// 具体消息
-    /// </summary>
-    [SugarColumn(ColumnDescription = "具体消息", ColumnDataType = "longtext,text,clob")]
-    public string Message { get; set; }
-
-    /// <summary>
-    /// IP地址
-    /// </summary>
-    [SugarColumn(ColumnDescription = "IP地址", Length = 20)]
-    [MaxLength(20)]
-    public string Ip { get; set; }
-
-    /// <summary>
-    /// 地址
-    /// </summary>
-    [SugarColumn(ColumnDescription = "地址", Length = 300)]
-    [MaxLength(300)]
-    public string Location { get; set; }
-
-    /// <summary>
-    /// 浏览器
-    /// </summary>
-    [SugarColumn(ColumnDescription = "浏览器", Length = 100)]
-    [MaxLength(100)]
-    public string Browser { get; set; }
-
-    /// <summary>
-    /// 操作系统
+    /// 类别名称
     /// </summary>
-    [SugarColumn(ColumnDescription = "操作系统", Length = 100)]
-    [MaxLength(100)]
-    public string Os { get; set; }
+    [SugarColumn(ColumnDescription = "类别名称", Length = 200)]
+    public string LogName { get; set; }
 
     /// <summary>
-    /// 请求地址
+    /// 日志级别
     /// </summary>
-    [SugarColumn(ColumnDescription = "请求地址", Length = 100)]
-    [MaxLength(100)]
-    public string Url { get; set; }
+    [SugarColumn(ColumnDescription = "日志级别", Length = 20)]
+    public string LogLevel { get; set; }
 
     /// <summary>
-    /// 类名称
+    /// 事件Id
     /// </summary>
-    [SugarColumn(ColumnDescription = "类名称", Length = 100)]
-    [MaxLength(100)]
-    public string ClassName { get; set; }
+    [SugarColumn(ColumnDescription = "事件Id", ColumnDataType = "longtext,text,clob")]
+    public string EventId { get; set; }
 
     /// <summary>
-    /// 方法名称
+    /// 日志消息
     /// </summary>
-    [SugarColumn(ColumnDescription = "方法名称", Length = 100)]
-    [MaxLength(100)]
-    public string MethodName { get; set; }
-
-    /// <summary>
-    /// 请求方式(GET POST PUT DELETE)
-    /// </summary>
-    [SugarColumn(ColumnDescription = "请求方式", Length = 10)]
-    [MaxLength(10)]
-    public string ReqMethod { get; set; }
-
-    /// <summary>
-    /// 请求参数
-    /// </summary>
-    [SugarColumn(ColumnDescription = "请求参数", ColumnDataType = "longtext,text,clob")]
-    public string Param { get; set; }
-
-    /// <summary>
-    /// 返回结果
-    /// </summary>
-    [SugarColumn(ColumnDescription = "返回结果", ColumnDataType = "longtext,text,clob")]
-    public string Result { get; set; }
-
-    /// <summary>
-    /// 耗时(毫秒)
-    /// </summary>
-    [SugarColumn(ColumnDescription = "耗时")]
-    public long ElapsedTime { get; set; }
-
-    /// <summary>
-    /// 账号名称
-    /// </summary>
-    [SugarColumn(ColumnDescription = "账号名称", Length = 20)]
-    [MaxLength(20)]
-    public string UserName { get; set; }
+    [SugarColumn(ColumnDescription = "日志消息", ColumnDataType = "longtext,text,clob")]
+    public string Message { get; set; }
 
     /// <summary>
-    /// 真实姓名
+    /// 异常对象
     /// </summary>
-    [SugarColumn(ColumnDescription = "真实姓名", Length = 20)]
-    [MaxLength(20)]
-    public string RealName { get; set; }
+    [SugarColumn(ColumnDescription = "异常对象", ColumnDataType = "longtext,text,clob")]
+    public string Exception { get; set; }  
 }

+ 45 - 45
Admin.NET/Admin.NET.Core/Filter/ActionFilter.cs

@@ -5,60 +5,60 @@
 /// </summary>
 public class ActionFilter : IAsyncActionFilter
 {
-    private readonly IEventPublisher _eventPublisher;
-
-    public ActionFilter(IEventPublisher eventPublisher)
+    public ActionFilter()
     {
-        _eventPublisher = eventPublisher;
+
     }
 
     public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
     {
-        // 是否有禁用操作日志属性
-        if (context.ActionDescriptor.EndpointMetadata.Any(m => m.GetType() == typeof(NotLogAttribute)))
-        {
-            await next();
-            return;
-        }
+        await next();
+
+        //// 是否有禁用操作日志属性
+        //if (context.ActionDescriptor.EndpointMetadata.Any(m => m.GetType() == typeof(NotLogAttribute)))
+        //{
+        //    await next();
+        //    return;
+        //}
 
-        // 是否开启操作日志
-        var sysOpLog = await App.GetService<SysConfigService>().GetConfigCache(CommonConst.SysOpLog);
-        if (string.IsNullOrWhiteSpace(sysOpLog) || !bool.Parse(sysOpLog))
-        {
-            await next();
-            return;
-        }
+        //// 是否开启操作日志
+        //var sysOpLog = await App.GetService<SysConfigService>().GetConfigCache(CommonConst.SysOpLog);
+        //if (string.IsNullOrWhiteSpace(sysOpLog) || !bool.Parse(sysOpLog))
+        //{
+        //    await next();
+        //    return;
+        //}
 
-        var sw = new Stopwatch();
-        sw.Start();
-        var actionContext = await next();
-        sw.Stop();
+        //var sw = new Stopwatch();
+        //sw.Start();
+        //var actionContext = await next();
+        //sw.Stop();
 
-        var httpContext = context.HttpContext;
-        var httpRequest = httpContext.Request;
+        //var httpContext = context.HttpContext;
+        //var httpRequest = httpContext.Request;
 
-        var isRequestSucceed = actionContext.Exception == null; // 判断是否请求成功(没有异常就是成功)
-        var headers = httpRequest.Headers;
-        var clientInfo = headers.ContainsKey("User-Agent") ? Parser.GetDefault().Parse(headers["User-Agent"]) : null;
-        var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
-        var ip = httpContext.GetRemoteIpAddressToIPv4();
+        //var isRequestSucceed = actionContext.Exception == null; // 判断是否请求成功(没有异常就是成功)
+        //var headers = httpRequest.Headers;
+        //var clientInfo = headers.ContainsKey("User-Agent") ? Parser.GetDefault().Parse(headers["User-Agent"]) : null;
+        //var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
+        //var ip = httpContext.GetRemoteIpAddressToIPv4();
 
-        await _eventPublisher.PublishAsync("Add:OpLog", new SysLogOp
-        {
-            Success = isRequestSucceed ? YesNoEnum.Y : YesNoEnum.N,
-            Ip = ip,
-            Location = httpRequest.GetRequestUrlAddress(),
-            Browser = clientInfo?.UA.Family + clientInfo?.UA.Major,
-            Os = clientInfo?.OS.Family + clientInfo?.OS.Major,
-            Url = httpRequest.Path,
-            ClassName = context.Controller.ToString(),
-            MethodName = actionDescriptor?.ActionName,
-            ReqMethod = httpRequest.Method,
-            Param = context.ActionArguments.Count < 1 ? string.Empty : JSON.Serialize(context.ActionArguments),
-            Result = actionContext.Result?.GetType() == typeof(JsonResult) ? JSON.Serialize(actionContext.Result) : string.Empty,
-            ElapsedTime = sw.ElapsedMilliseconds,
-            UserName = httpContext.User?.FindFirstValue(ClaimConst.UserName),
-            RealName = httpContext.User?.FindFirstValue(ClaimConst.RealName)
-        });
+        //await _eventPublisher.PublishAsync("Add:OpLog", new SysLogOp
+        //{
+        //    Success = isRequestSucceed ? YesNoEnum.Y : YesNoEnum.N,
+        //    Ip = ip,
+        //    Location = httpRequest.GetRequestUrlAddress(),
+        //    Browser = clientInfo?.UA.Family + clientInfo?.UA.Major,
+        //    Os = clientInfo?.OS.Family + clientInfo?.OS.Major,
+        //    Url = httpRequest.Path,
+        //    ClassName = context.Controller.ToString(),
+        //    MethodName = actionDescriptor?.ActionName,
+        //    ReqMethod = httpRequest.Method,
+        //    Param = context.ActionArguments.Count < 1 ? string.Empty : JSON.Serialize(context.ActionArguments),
+        //    Result = actionContext.Result?.GetType() == typeof(JsonResult) ? JSON.Serialize(actionContext.Result) : string.Empty,
+        //    ElapsedTime = sw.ElapsedMilliseconds,
+        //    UserName = httpContext.User?.FindFirstValue(ClaimConst.UserName),
+        //    RealName = httpContext.User?.FindFirstValue(ClaimConst.RealName)
+        //});
     }
 }

+ 28 - 0
Admin.NET/Admin.NET.Core/Logging/DbLoggingWriter.cs

@@ -0,0 +1,28 @@
+using Furion.Logging;
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// 数据库日志写入器
+/// </summary>
+public class DbLoggingWriter : IDatabaseLoggingWriter
+{
+    private readonly SqlSugarRepository<SysLogOp> _sysOpLogRep;
+
+    public DbLoggingWriter(SqlSugarRepository<SysLogOp> sysOpLogRep)
+    {
+        _sysOpLogRep = sysOpLogRep;
+    }
+
+    public async void Write(LogMessage logMsg, bool flush)
+    {
+        await _sysOpLogRep.InsertAsync(new SysLogOp
+        {
+            LogName = logMsg.LogName,
+            LogLevel = logMsg.LogLevel.ToString(),
+            EventId = JSON.Serialize(logMsg.EventId),
+            Message = logMsg.Message,
+            Exception = logMsg.Exception == null ? "" : JSON.Serialize(logMsg.Exception),
+        });
+    }
+}

+ 16 - 12
Admin.NET/Admin.NET.Web.Core/Startup.cs

@@ -81,20 +81,30 @@ public class Startup : AppStartup
         // 日志记录
         services.AddLogging(builder =>
         {
-            builder.AddFile("logs/{0:yyyyMMdd}.log", options =>
+            // 错误级别日志归类
+            builder.AddFile("logs/error.log", options =>
             {
-                options.FileNameRule = fileName =>
+                options.WriteFilter = (logMsg) =>
                 {
-                    return string.Format(fileName, DateTime.UtcNow);
+                    return logMsg.LogLevel == LogLevel.Error;
                 };
             });
-            builder.AddFile("logs/error.log", options =>
+            // 每天创建一个日志文件
+            builder.AddFile("logs/{0:yyyyMMdd}.log", options =>
             {
-                options.WriteFilter = (logMsg) =>
+                options.FileNameRule = fileName =>
                 {
-                    return logMsg.LogLevel == LogLevel.Error;
+                    return string.Format(fileName, DateTime.UtcNow);
                 };
             });
+            // 日志写入数据库
+            builder.AddDatabase<DbLoggingWriter>();
+        });
+
+        // 设置雪花Id算法机器码
+        YitIdHelper.SetIdGenerator(new IdGeneratorOptions
+        {
+            WorkerId = App.GetOptions<SnowIdOptions>().WorkerId
         });
     }
 
@@ -135,11 +145,5 @@ public class Startup : AppStartup
                 name: "default",
                 pattern: "{controller=Home}/{action=Index}/{id?}");
         });
-
-        // 设置雪花Id算法机器码
-        YitIdHelper.SetIdGenerator(new IdGeneratorOptions
-        {
-            WorkerId = App.GetOptions<SnowIdOptions>().WorkerId
-        });
     }
 }

+ 3 - 0
Admin.NET/Admin.NET.Web.Entry/appsettings.Development.json

@@ -13,6 +13,9 @@
       "MinimumLevel": "Information",
       "FileSizeLimitBytes": 5120,
       "MaxRollingFiles": 100
+    },
+    "Database": {
+      "MinimumLevel": "Information"
     }
   }
 }

+ 3 - 0
Admin.NET/Admin.NET.Web.Entry/appsettings.json

@@ -15,6 +15,9 @@
       "MinimumLevel": "Information",
       "FileSizeLimitBytes": 5120,
       "MaxRollingFiles": 100
+    },
+    "Database": {
+      "MinimumLevel": "Information"
     }
   },
   "AllowedHosts": "*"