From 8372a3a0d4d0c618dec3c0abd38b83a16d8f8024 Mon Sep 17 00:00:00 2001 From: anjoy8 <3143422472@qq.com> Date: Wed, 23 Aug 2023 16:13:42 +0800 Subject: [PATCH] feat: :tada: test log sql operate log --- Blog.Core.Api/Blog.Core.xml | 14 +- Blog.Core.Api/appsettings.json | 3 + Blog.Core.Common/DB/Aop/SqlsugarAop.cs | 6 +- .../HttpContextUser/AspNetUser.cs | 2 +- .../ServiceExtensions/AppConfigSetup.cs | 10 + .../AutofacModuleRegister.cs | 6 + .../ServiceExtensions/SqlsugarSetup.cs | 239 ++++++++++-------- 7 files changed, 169 insertions(+), 111 deletions(-) diff --git a/Blog.Core.Api/Blog.Core.xml b/Blog.Core.Api/Blog.Core.xml index 566d345..667dcfd 100644 --- a/Blog.Core.Api/Blog.Core.xml +++ b/Blog.Core.Api/Blog.Core.xml @@ -1393,9 +1393,21 @@ - 缓存管理 + 动态建表 CURD + + + 动态type + + + + + + 动态type 继承BaseEntity + + + 测试建表 diff --git a/Blog.Core.Api/appsettings.json b/Blog.Core.Api/appsettings.json index d94a760..82fc206 100644 --- a/Blog.Core.Api/appsettings.json +++ b/Blog.Core.Api/appsettings.json @@ -57,6 +57,9 @@ "TranAOP": { "Enabled": true }, + "UserAuditAOP": { + "Enabled": false + }, "SqlAOP": { "Enabled": true, "LogToFile": { diff --git a/Blog.Core.Common/DB/Aop/SqlsugarAop.cs b/Blog.Core.Common/DB/Aop/SqlsugarAop.cs index f165ef4..826984e 100644 --- a/Blog.Core.Common/DB/Aop/SqlsugarAop.cs +++ b/Blog.Core.Common/DB/Aop/SqlsugarAop.cs @@ -11,7 +11,7 @@ namespace Blog.Core.Common.DB.Aop; public static class SqlSugarAop { - public static void OnLogExecuting(ISqlSugarClient sqlSugarScopeProvider, string sql, SugarParameter[] p, ConnectionConfig config) + public static void OnLogExecuting(ISqlSugarClient sqlSugarScopeProvider, string user, string table, string operate, string sql, SugarParameter[] p, ConnectionConfig config) { try { @@ -25,8 +25,8 @@ public static class SqlSugarAop { using (LogContextExtension.Create.SqlAopPushProperty(sqlSugarScopeProvider)) { - Log.Information("------------------ \r\n ConnId:[{ConnId}]【SQL语句】: \r\n {Sql}", - config.ConfigId, UtilMethods.GetNativeSql( sql, p)); + Log.Information("------------------ \r\n User:[{User}] Table:[{Table}] Operate:[{Operate}] ConnId:[{ConnId}]【SQL语句】: \r\n {Sql}", + user, table, operate, config.ConfigId, UtilMethods.GetNativeSql(sql, p)); } } } diff --git a/Blog.Core.Common/HttpContextUser/AspNetUser.cs b/Blog.Core.Common/HttpContextUser/AspNetUser.cs index 1ceaa45..dfa8794 100644 --- a/Blog.Core.Common/HttpContextUser/AspNetUser.cs +++ b/Blog.Core.Common/HttpContextUser/AspNetUser.cs @@ -48,7 +48,7 @@ namespace Blog.Core.Common.HttpContextUser public bool IsAuthenticated() { - return _accessor.HttpContext.User.Identity.IsAuthenticated; + return _accessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false; } diff --git a/Blog.Core.Extensions/ServiceExtensions/AppConfigSetup.cs b/Blog.Core.Extensions/ServiceExtensions/AppConfigSetup.cs index d7a1f90..680a191 100644 --- a/Blog.Core.Extensions/ServiceExtensions/AppConfigSetup.cs +++ b/Blog.Core.Extensions/ServiceExtensions/AppConfigSetup.cs @@ -79,6 +79,15 @@ namespace Blog.Core.Extensions { ConsoleHelper.WriteSuccessLine($"Transaction AOP: True"); } + // 审计AOP + if (!AppSettings.app(new string[] { "AppSettings", "UserAuditAOP", "Enabled" }).ObjToBool()) + { + Console.WriteLine($"UserAudit AOP: False"); + } + else + { + ConsoleHelper.WriteSuccessLine($"UserAudit AOP: True"); + } // 数据库Sql执行AOP if (!AppSettings.app(new string[] { "AppSettings", "SqlAOP", "OutToLogFile", "Enabled" }).ObjToBool()) @@ -251,6 +260,7 @@ namespace Blog.Core.Extensions new string[] { "缓存AOP", AppSettings.app("AppSettings", "CachingAOP", "Enabled") }, new string[] { "服务日志AOP", AppSettings.app("AppSettings", "LogAOP", "Enabled") }, new string[] { "事务AOP", AppSettings.app("AppSettings", "TranAOP", "Enabled") }, + new string[] { "服务审计AOP", AppSettings.app("AppSettings", "UserAuditAOP", "Enabled") }, new string[] { "Sql执行AOP", AppSettings.app("AppSettings", "SqlAOP", "Enabled") }, new string[] { "Sql执行AOP控制台输出", AppSettings.app("AppSettings", "SqlAOP", "LogToConsole", "Enabled") }, }; diff --git a/Blog.Core.Extensions/ServiceExtensions/AutofacModuleRegister.cs b/Blog.Core.Extensions/ServiceExtensions/AutofacModuleRegister.cs index 4836c40..4236bfb 100644 --- a/Blog.Core.Extensions/ServiceExtensions/AutofacModuleRegister.cs +++ b/Blog.Core.Extensions/ServiceExtensions/AutofacModuleRegister.cs @@ -57,6 +57,12 @@ namespace Blog.Core.Extensions cacheType.Add(typeof(BlogLogAOP)); } + if (AppSettings.app(new string[] { "AppSettings", "UserAuditAOP", "Enabled" }).ObjToBool()) + { + builder.RegisterType(); + cacheType.Add(typeof(BlogUserAuditAOP)); + } + builder.RegisterGeneric(typeof(BaseRepository<>)).As(typeof(IBaseRepository<>)).InstancePerDependency(); //注册仓储 builder.RegisterGeneric(typeof(BaseServices<>)).As(typeof(IBaseServices<>)).InstancePerDependency(); //注册服务 diff --git a/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs b/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs index dd5c02b..9cf9903 100644 --- a/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs +++ b/Blog.Core.Extensions/ServiceExtensions/SqlsugarSetup.cs @@ -11,126 +11,153 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using Blog.Core.Common.Caches; +using Blog.Core.Common.Core; +using Blog.Core.Common.HttpContextUser; +using static Grpc.Core.ChannelOption; +using System.Text.RegularExpressions; namespace Blog.Core.Extensions { - /// - /// SqlSugar 启动服务 - /// - public static class SqlsugarSetup - { - private static readonly MemoryCache Cache = new MemoryCache(new MemoryCacheOptions()); + /// + /// SqlSugar 启动服务 + /// + public static class SqlsugarSetup + { + private static readonly MemoryCache Cache = new MemoryCache(new MemoryCacheOptions()); - public static void AddSqlsugarSetup(this IServiceCollection services) - { - if (services == null) throw new ArgumentNullException(nameof(services)); + public static void AddSqlsugarSetup(this IServiceCollection services) + { + if (services == null) throw new ArgumentNullException(nameof(services)); - // 默认添加主数据库连接 - MainDb.CurrentDbConnId = AppSettings.app(new string[] {"MainDB"}); + // 默认添加主数据库连接 + MainDb.CurrentDbConnId = AppSettings.app(new string[] { "MainDB" }); - BaseDBConfig.MutiConnectionString.slaveDbs.ForEach(s => - { - BaseDBConfig.AllSlaveConfigs.Add(new SlaveConnectionConfig() - { - HitRate = s.HitRate, - ConnectionString = s.Connection - }); - }); + BaseDBConfig.MutiConnectionString.slaveDbs.ForEach(s => + { + BaseDBConfig.AllSlaveConfigs.Add(new SlaveConnectionConfig() + { + HitRate = s.HitRate, + ConnectionString = s.Connection + }); + }); - BaseDBConfig.MutiConnectionString.allDbs.ForEach(m => - { - var config = new ConnectionConfig() - { - ConfigId = m.ConnId.ObjToString().ToLower(), - ConnectionString = m.Connection, - DbType = (DbType) m.DbType, - IsAutoCloseConnection = true, - // Check out more information: https://github.com/anjoy8/Blog.Core/issues/122 - //IsShardSameThread = false, - MoreSettings = new ConnMoreSettings() - { - //IsWithNoLockQuery = true, - IsAutoRemoveDataCache = true, - SqlServerCodeFirstNvarchar = true, - }, - // 从库 - SlaveConnectionConfigs = BaseDBConfig.AllSlaveConfigs, - // 自定义特性 - ConfigureExternalServices = new ConfigureExternalServices() - { - DataInfoCacheService = new SqlSugarCacheService(), - EntityService = (property, column) => - { - if (column.IsPrimarykey && property.PropertyType == typeof(int)) - { - column.IsIdentity = true; - } - } - }, - InitKeyType = InitKeyType.Attribute - }; - if (SqlSugarConst.LogConfigId.ToLower().Equals(m.ConnId.ToLower())) - { - BaseDBConfig.LogConfig = config; - } - else - { - BaseDBConfig.ValidConfig.Add(config); - } + BaseDBConfig.MutiConnectionString.allDbs.ForEach(m => + { + var config = new ConnectionConfig() + { + ConfigId = m.ConnId.ObjToString().ToLower(), + ConnectionString = m.Connection, + DbType = (DbType)m.DbType, + IsAutoCloseConnection = true, + // Check out more information: https://github.com/anjoy8/Blog.Core/issues/122 + //IsShardSameThread = false, + MoreSettings = new ConnMoreSettings() + { + //IsWithNoLockQuery = true, + IsAutoRemoveDataCache = true, + SqlServerCodeFirstNvarchar = true, + }, + // 从库 + SlaveConnectionConfigs = BaseDBConfig.AllSlaveConfigs, + // 自定义特性 + ConfigureExternalServices = new ConfigureExternalServices() + { + DataInfoCacheService = new SqlSugarCacheService(), + EntityService = (property, column) => + { + if (column.IsPrimarykey && property.PropertyType == typeof(int)) + { + column.IsIdentity = true; + } + } + }, + InitKeyType = InitKeyType.Attribute + }; + if (SqlSugarConst.LogConfigId.ToLower().Equals(m.ConnId.ToLower())) + { + BaseDBConfig.LogConfig = config; + } + else + { + BaseDBConfig.ValidConfig.Add(config); + } - BaseDBConfig.AllConfigs.Add(config); - }); + BaseDBConfig.AllConfigs.Add(config); + }); - if (BaseDBConfig.LogConfig is null) - { - throw new ApplicationException("未配置Log库连接"); - } - - // SqlSugarScope是线程安全,可使用单例注入 - // 参考:https://www.donet5.com/Home/Doc?typeId=1181 - services.AddSingleton(o => - { - return new SqlSugarScope(BaseDBConfig.AllConfigs, db => - { - BaseDBConfig.ValidConfig.ForEach(config => - { - var dbProvider = db.GetConnectionScope((string) config.ConfigId); + if (BaseDBConfig.LogConfig is null) + { + throw new ApplicationException("未配置Log库连接"); + } - // 打印SQL语句 - dbProvider.Aop.OnLogExecuting = (s, parameters) => - SqlSugarAop.OnLogExecuting(dbProvider, s, parameters, config); + // SqlSugarScope是线程安全,可使用单例注入 + // 参考:https://www.donet5.com/Home/Doc?typeId=1181 + services.AddSingleton(o => + { + return new SqlSugarScope(BaseDBConfig.AllConfigs, db => + { + BaseDBConfig.ValidConfig.ForEach(config => + { + var dbProvider = db.GetConnectionScope((string)config.ConfigId); - // 数据审计 - dbProvider.Aop.DataExecuting = SqlSugarAop.DataExecuting; + // 打印SQL语句 + dbProvider.Aop.OnLogExecuting = (s, parameters) => + { + var user = InternalApp.RootServices.GetService(); + SqlSugarAop.OnLogExecuting(dbProvider, user?.Name.ObjToString(), ExtractTableName(s), Enum.GetName(typeof(SugarActionType), dbProvider.SugarActionType), s, parameters, config); + }; - // 配置实体假删除过滤器 - RepositorySetting.SetDeletedEntityFilter(dbProvider); - // 配置实体数据权限 - RepositorySetting.SetTenantEntityFilter(dbProvider); - }); - }); - }); - } + // 数据审计 + dbProvider.Aop.DataExecuting = SqlSugarAop.DataExecuting; - private static string GetWholeSql(SugarParameter[] paramArr, string sql) - { - foreach (var param in paramArr) - { - sql.Replace(param.ParameterName, param.Value.ObjToString()); - } + // 配置实体假删除过滤器 + RepositorySetting.SetDeletedEntityFilter(dbProvider); + // 配置实体数据权限 + RepositorySetting.SetTenantEntityFilter(dbProvider); + }); + }); + }); + } - return sql; - } + private static string GetWholeSql(SugarParameter[] paramArr, string sql) + { + foreach (var param in paramArr) + { + sql.Replace(param.ParameterName, param.Value.ObjToString()); + } - private static string GetParas(SugarParameter[] pars) - { - string key = "【SQL参数】:"; - foreach (var param in pars) - { - key += $"{param.ParameterName}:{param.Value}\n"; - } + return sql; + } - return key; - } - } + private static string GetParas(SugarParameter[] pars) + { + string key = "【SQL参数】:"; + foreach (var param in pars) + { + key += $"{param.ParameterName}:{param.Value}\n"; + } + + return key; + } + + private static string ExtractTableName(string sql) + { + // 匹配 SQL 语句中的表名的正则表达式 + //string regexPattern = @"\s*(?:UPDATE|DELETE\s+FROM|SELECT\s+\*\s+FROM)\s+(\w+)"; + string regexPattern = @"(?i)(?:FROM|UPDATE|DELETE\s+FROM)\s+`(.+?)`"; + Regex regex = new Regex(regexPattern, RegexOptions.IgnoreCase); + Match match = regex.Match(sql); + + if (match.Success) + { + // 提取匹配到的表名 + return match.Groups[1].Value; + } + else + { + // 如果没有匹配到表名,则返回空字符串或者抛出异常等处理 + return string.Empty; + } + } + } } \ No newline at end of file