diff --git a/scripts/MongoDB/Navigations.js b/scripts/MongoDB/Navigations.js index dae95468..ed2e8869 100644 --- a/scripts/MongoDB/Navigations.js +++ b/scripts/MongoDB/Navigations.js @@ -635,6 +635,18 @@ "IsResource": NumberInt(0), "Application": "0" }, + { + "_id": ObjectId("5bd9b3d868aa001661776f60"), + "ParentId": "5bd7b8445fa31256f77e4b9c", + "Name": "SQL日志", + "Order": NumberInt(40), + "Icon": "fa fa-database", + "Url": "~/Admin/SQL", + "Category": "0", + "Target": "_self", + "IsResource": NumberInt(0), + "Application": "0" + }, { "_id": ObjectId("5bd7b8445fa31256f77e4b89"), "ParentId": "0", diff --git a/scripts/MySQL/initData.sql b/scripts/MySQL/initData.sql index 11ed8831..b1d0e4a1 100644 --- a/scripts/MySQL/initData.sql +++ b/scripts/MySQL/initData.sql @@ -112,6 +112,7 @@ INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (0 INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (@@identity, '操作日志', 10, 'fa fa-edit', '~/Admin/Logs', '0'); INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (@@identity - 1, '登录日志', 20, 'fa fa-user-circle-o', '~/Admin/Logins', '0'); INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (@@identity - 2, '访问日志', 30, 'fa fa-bars', '~/Admin/Traces', '0'); +INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (@@identity - 3, 'SQL日志', 40, 'fa fa-database', '~/Admin/SQL', '0'); INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (0, '在线用户', 140, 'fa fa-users', '~/Admin/Online', '0'); INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (0, '网站分析', 145, 'fa fa-line-chart', '~/Admin/Analyse', '0'); INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (0, '程序异常', 150, 'fa fa-cubes', '~/Admin/Exceptions', '0'); diff --git a/scripts/MySQL/install.sql b/scripts/MySQL/install.sql index 38076517..21e8bcaf 100644 --- a/scripts/MySQL/install.sql +++ b/scripts/MySQL/install.sql @@ -182,4 +182,11 @@ CREATE TABLE Traces( City VARCHAR (50), RequestUrl VARCHAR (500) NOT NULL, UserAgent VARCHAR (2000) NULL -); \ No newline at end of file +); + +CREATE TABLE DBLogs ( + ID INTEGER PRIMARY KEY Auto_increment, + UserName VARCHAR (50) NULL, + SQL VARCHAR NOT NULL, + LogTime DATETIME NOT NULL +); diff --git a/scripts/Postgresql/initData.sql b/scripts/Postgresql/initData.sql index dd383d44..8281de67 100644 --- a/scripts/Postgresql/initData.sql +++ b/scripts/Postgresql/initData.sql @@ -112,6 +112,7 @@ INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0 INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (currval('navigations_id_seq') - 1, 0, '操作日志', 10, 'fa fa-edit', '~/Admin/Logs', '0'); INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (currval('navigations_id_seq') - 2, 0, '登录日志', 20, 'fa fa-user-circle-o', '~/Admin/Logins', '0'); INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (currval('navigations_id_seq') - 3, 0, '访问日志', 30, 'fa fa-bars', '~/Admin/Traces', '0'); +INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (currval('navigations_id_seq') - 4, 0, 'SQL日志', 40, 'fa fa-database', '~/Admin/SQL', '0'); INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '在线用户', 140, 'fa fa-users', '~/Admin/Online', '0'); INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '网站分析', 145, 'fa fa-line-chart', '~/Admin/Analyse', '0'); INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '程序异常', 150, 'fa fa-cubes', '~/Admin/Exceptions', '0'); diff --git a/scripts/Postgresql/install.sql b/scripts/Postgresql/install.sql index f7779581..981c0b3b 100644 --- a/scripts/Postgresql/install.sql +++ b/scripts/Postgresql/install.sql @@ -182,4 +182,11 @@ CREATE TABLE Traces( City VARCHAR (50), RequestUrl VARCHAR (500) NOT NULL, UserAgent VARCHAR (2000) NULL -); \ No newline at end of file +); + +CREATE TABLE DBLogs ( + ID SERIAL PRIMARY KEY, + UserName VARCHAR (50) NULL, + SQL VARCHAR (2000) NOT NULL, + LogTime DATE NOT NULL +); diff --git a/scripts/SQLite/InitData.sql b/scripts/SQLite/InitData.sql index 8df01f66..a6c5395c 100644 --- a/scripts/SQLite/InitData.sql +++ b/scripts/SQLite/InitData.sql @@ -112,6 +112,7 @@ INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (last_insert_rowid(), '操作日志', 10, 'fa fa-edit', '~/Admin/Logs', '0'); INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (last_insert_rowid() - 1, '登录日志', 20, 'fa fa-user-circle-o', '~/Admin/Logins', '0'); INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (last_insert_rowid() - 2, '访问日志', 30, 'fa fa-bars', '~/Admin/Traces', '0'); +INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (last_insert_rowid() - 3, 'SQL日志', 40, 'fa fa-database', '~/Admin/SQL', '0'); INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, '在线用户', 140, 'fa fa-users', '~/Admin/Online', '0'); INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, '网站分析', 145, 'fa fa-line-chart', '~/Admin/Analyse', '0'); INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, '程序异常', 150, 'fa fa-cubes', '~/Admin/Exceptions', '0'); diff --git a/scripts/SQLite/Install.sql b/scripts/SQLite/Install.sql index ce3fe3a8..cae22b42 100644 --- a/scripts/SQLite/Install.sql +++ b/scripts/SQLite/Install.sql @@ -182,4 +182,11 @@ CREATE TABLE Traces( City VARCHAR (50), RequestUrl VARCHAR (500) NOT NULL, UserAgent VARCHAR (2000) +); + +CREATE TABLE DBLogs ( + ID INTEGER PRIMARY KEY, + UserName VARCHAR (50) COLLATE NOCASE, + SQL VARCHAR NOT NULL, + LogTime DATETIME NOT NULL ); \ No newline at end of file diff --git a/scripts/SqlServer/InitData.sql b/scripts/SqlServer/InitData.sql index 3a248507..ae5875ff 100644 --- a/scripts/SqlServer/InitData.sql +++ b/scripts/SqlServer/InitData.sql @@ -115,6 +115,7 @@ INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (@@Identity, N'操作日志', 10, N'fa fa-edit', N'~/Admin/Logs', N'0') INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (@@Identity - 1, N'登录日志', 20, N'fa fa-user-circle-o', N'~/Admin/Logins', N'0') INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (@@Identity - 2, N'访问日志', 30, N'fa fa-bars', N'~/Admin/Traces', N'0') +INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (@@Identity - 3, N'SQL日志', 40, N'fa fa-database', N'~/Admin/SQL', N'0') INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, N'在线用户', 140, N'fa fa-users', N'~/Admin/Online', N'0') INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, N'网站分析', 145, N'fa fa-line-chart', N'~/Admin/Analyse', N'0') INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, N'程序异常', 150, N'fa fa-cubes', N'~/Admin/Exceptions', N'0') diff --git a/scripts/SqlServer/Install.sql b/scripts/SqlServer/Install.sql index f2d5f0ba..981a3d90 100644 --- a/scripts/SqlServer/Install.sql +++ b/scripts/SqlServer/Install.sql @@ -577,4 +577,30 @@ CREATE TABLE [dbo].[Traces]( GO SET ANSI_PADDING OFF -GO \ No newline at end of file +GO + +/****** Object: Table [dbo].[DBLogs] Script Date: 09/22/2019 22:06:43 ******/ +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +SET ANSI_PADDING ON +GO + +CREATE TABLE [dbo].[DBLogs]( + [ID] [int] IDENTITY(1,1) NOT NULL, + [UserName] [varchar](50) NULL, + [SQL] [nvarchar](max) NOT NULL, + [LogTime] [datetime] NOT NULL, + CONSTRAINT [PK_DBLogs] PRIMARY KEY CLUSTERED +( + [ID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] + +GO + +SET ANSI_PADDING OFF +GO diff --git a/src/admin/Bootstrap.Admin/BootstrapAdmin.db b/src/admin/Bootstrap.Admin/BootstrapAdmin.db index 6594fc99..b8274d32 100644 Binary files a/src/admin/Bootstrap.Admin/BootstrapAdmin.db and b/src/admin/Bootstrap.Admin/BootstrapAdmin.db differ diff --git a/src/admin/Bootstrap.Admin/Controllers/AdminController.cs b/src/admin/Bootstrap.Admin/Controllers/AdminController.cs index 0b920afb..cfb9bc5a 100644 --- a/src/admin/Bootstrap.Admin/Controllers/AdminController.cs +++ b/src/admin/Bootstrap.Admin/Controllers/AdminController.cs @@ -53,6 +53,12 @@ namespace Bootstrap.Admin.Controllers /// public ActionResult Logs() => View(new NavigatorBarModel(this)); + /// + /// + /// + /// + public ActionResult SQL() => View(new NavigatorBarModel(this)); + /// /// /// diff --git a/src/admin/Bootstrap.Admin/Controllers/Api/SQLController.cs b/src/admin/Bootstrap.Admin/Controllers/Api/SQLController.cs new file mode 100644 index 00000000..90842cdb --- /dev/null +++ b/src/admin/Bootstrap.Admin/Controllers/Api/SQLController.cs @@ -0,0 +1,26 @@ +using Bootstrap.Admin.Query; +using Bootstrap.DataAccess; +using Longbow.Web.Mvc; +using Microsoft.AspNetCore.Mvc; + +namespace Bootstrap.Admin.Controllers.Api +{ + /// + /// SQL 语句执行日志 webapi + /// + [Route("api/[controller]")] + [ApiController] + public class SQLController : ControllerBase + { + /// + /// 获取执行日志数据 + /// + /// + /// + [HttpGet] + public QueryData Get([FromQuery]QuerySQLOption value) + { + return value.RetrieveData(); + } + } +} diff --git a/src/admin/Bootstrap.Admin/Query/QuerySQLOption.cs b/src/admin/Bootstrap.Admin/Query/QuerySQLOption.cs new file mode 100644 index 00000000..01bbf00f --- /dev/null +++ b/src/admin/Bootstrap.Admin/Query/QuerySQLOption.cs @@ -0,0 +1,40 @@ +using Bootstrap.DataAccess; +using Longbow.Web.Mvc; +using System; + +namespace Bootstrap.Admin.Query +{ + /// + /// SQL执行查询配置类 + /// + public class QuerySQLOption : PaginationOption + { + /// + /// 获得/设置 用户登录名 + /// + public string UserName { get; set; } + + /// + /// 获得/设置 开始时间 + /// + public DateTime? OperateTimeStart { get; set; } + + /// + /// 获得/设置 结束时间 + /// + public DateTime? OperateTimeEnd { get; set; } + + /// + /// 查询数据方法 + /// + /// + public QueryData RetrieveData() + { + var data = LogHelper.RetrieveDBLogs(this, OperateTimeStart, OperateTimeEnd, UserName); + var ret = new QueryData(); + ret.total = data.TotalItems; + ret.rows = data.Items; + return ret; + } + } +} diff --git a/src/admin/Bootstrap.Admin/Tasks/TasksExtensions.cs b/src/admin/Bootstrap.Admin/Tasks/TasksExtensions.cs index 53cc1a66..e6151237 100644 --- a/src/admin/Bootstrap.Admin/Tasks/TasksExtensions.cs +++ b/src/admin/Bootstrap.Admin/Tasks/TasksExtensions.cs @@ -1,9 +1,10 @@ -using Longbow.Tasks; +using Bootstrap.DataAccess; +using Longbow.Tasks; using Microsoft.Extensions.Hosting; using System; using System.Linq; using System.Threading; -using System.Threading.Tasks; +using Task = System.Threading.Tasks.Task; namespace Microsoft.Extensions.DependencyInjection { @@ -49,6 +50,9 @@ namespace Microsoft.Extensions.DependencyInjection // 创建任务并禁用 TaskServicesManager.GetOrAdd("禁用任务", token => Task.Delay(1000)).Status = SchedulerStatus.Disabled; + + // 真实任务负责批次写入数据执行脚本到日志中 + TaskServicesManager.GetOrAdd("SQL日志", TriggerBuilder.Build(Cron.Minutely())); }); } } diff --git a/src/admin/Bootstrap.Admin/Views/Admin/SQL.cshtml b/src/admin/Bootstrap.Admin/Views/Admin/SQL.cshtml new file mode 100644 index 00000000..bc919c77 --- /dev/null +++ b/src/admin/Bootstrap.Admin/Views/Admin/SQL.cshtml @@ -0,0 +1,80 @@ +@model NavigatorBarModel +@{ + ViewBag.Title = "SQL日志"; +} +@section css { + + + + + + + + +} +@section javascript { + + + + + + + + + + + + + + + + +} +
+
查询条件
+
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+
+
+
+
+ + +
+
+ +
+
+
+
+
+
+
+ 查询结果 +
+
+
+
+
diff --git a/src/admin/Bootstrap.Admin/wwwroot/js/sql.js b/src/admin/Bootstrap.Admin/wwwroot/js/sql.js new file mode 100644 index 00000000..5e0ab2ba --- /dev/null +++ b/src/admin/Bootstrap.Admin/wwwroot/js/sql.js @@ -0,0 +1,18 @@ +$(function () { + var url = 'api/SQL'; + + $('.card-body table').smartTable({ + url: url, + sortName: 'LogTime', + sortOrder: 'desc', + queryParams: function (params) { return $.extend(params, { UserName: $("#txt_username").val(), OperateTimeStart: $("#txt_operate_start").val(), OperateTimeEnd: $("#txt_operate_end").val() }); }, + columns: [ + { title: "所属用户", field: "UserName", sortable: true }, + { title: "执行时间", field: "LogTime", sortable: true }, + { title: "脚本内容", field: "SQL", sortable: false } + ], + exportOptions: { + fileName: "SQL日志数据" + } + }); +}); diff --git a/src/admin/Bootstrap.DataAccess.MongoDB/DBLog.cs b/src/admin/Bootstrap.DataAccess.MongoDB/DBLog.cs new file mode 100644 index 00000000..02c4ccb5 --- /dev/null +++ b/src/admin/Bootstrap.DataAccess.MongoDB/DBLog.cs @@ -0,0 +1,15 @@ +namespace Bootstrap.DataAccess.MongoDB +{ + /// + /// DBLog 实体类 + /// + public class DBLog : DataAccess.DBLog + { + /// + /// 保存数据库脚本日志方法 MongoDB 无脚本 + /// + /// + /// + public override bool Save(DataAccess.DBLog p) => true; + } +} diff --git a/src/admin/Bootstrap.DataAccess.MongoDB/Log.cs b/src/admin/Bootstrap.DataAccess.MongoDB/Log.cs index 92f89d9a..d85c9300 100644 --- a/src/admin/Bootstrap.DataAccess.MongoDB/Log.cs +++ b/src/admin/Bootstrap.DataAccess.MongoDB/Log.cs @@ -8,12 +8,12 @@ using System.Linq; namespace Bootstrap.DataAccess.MongoDB { /// - /// + /// 操作日志实体类 /// public class Log : DataAccess.Log { /// - /// + /// 分页查询操作日志 /// /// /// @@ -64,7 +64,7 @@ namespace Bootstrap.DataAccess.MongoDB } /// - /// + /// 查询所有操作日志 /// /// /// @@ -89,7 +89,7 @@ namespace Bootstrap.DataAccess.MongoDB private static void DeleteLogAsync() => System.Threading.Tasks.Task.Run(() => DbManager.Logs.DeleteMany(log => log.LogTime < DateTime.Now.AddDays(-7))); /// - /// + /// 保存操作日志 /// /// /// diff --git a/src/admin/Bootstrap.DataAccess/Bootstrap.DataAccess.csproj b/src/admin/Bootstrap.DataAccess/Bootstrap.DataAccess.csproj index a19f85b2..03cef29c 100644 --- a/src/admin/Bootstrap.DataAccess/Bootstrap.DataAccess.csproj +++ b/src/admin/Bootstrap.DataAccess/Bootstrap.DataAccess.csproj @@ -7,12 +7,13 @@ - + + diff --git a/src/admin/Bootstrap.DataAccess/DBLog.cs b/src/admin/Bootstrap.DataAccess/DBLog.cs new file mode 100644 index 00000000..a7b6a393 --- /dev/null +++ b/src/admin/Bootstrap.DataAccess/DBLog.cs @@ -0,0 +1,79 @@ +using Longbow.Web.Mvc; +using PetaPoco; +using System; + +namespace Bootstrap.DataAccess +{ + /// + /// 后台数据库脚本执行日志实体类 + /// + [TableName("DBLogs")] + public class DBLog + { + /// + /// 获得/设置 主键ID + /// + public string Id { get; set; } + + /// + /// 获得/设置 当前登陆名 + /// + public string UserName { get; set; } + + /// + /// 获得/设置 数据库执行脚本 + /// + public string SQL { get; set; } + + /// + /// 获取/设置 用户角色关联状态 checked 标示已经关联 '' 标示未关联 + /// + public DateTime LogTime { get; set; } + + /// + /// 查询所有SQL日志信息 + /// + /// + /// + /// + /// + /// + public virtual Page RetrievePages(PaginationOption po, DateTime? startTime, DateTime? endTime, string userName) + { + var sql = new Sql("select * from DBLogs"); + if (startTime.HasValue) sql.Where("LogTime >= @0", startTime.Value); + if (endTime.HasValue) sql.Where("LogTime < @0", endTime.Value.AddDays(1).AddSeconds(-1)); + if (startTime == null && endTime == null) sql.Where("LogTime > @0", DateTime.Today.AddMonths(0 - DictHelper.RetrieveExceptionsLogPeriod())); + if (!string.IsNullOrEmpty(userName)) sql.Where("UserName = @0", userName); + sql.OrderBy($"{po.Sort} {po.Order}"); + + return DbManager.Create().Page(po.PageIndex, po.Limit, sql); + } + + /// + /// 删除日志信息 + /// + /// + private static void DeleteLogAsync() + { + System.Threading.Tasks.Task.Run(() => + { + var dtm = DateTime.Now.AddMonths(0 - DictHelper.RetrieveLogsPeriod()); + DbManager.Create().Execute("delete from DBLogs where LogTime < @0", dtm); + }); + } + + /// + /// 保存新增的日志信息 + /// + /// + /// + public virtual bool Save(DBLog p) + { + if (p == null) throw new ArgumentNullException(nameof(p)); + DeleteLogAsync(); + DbManager.Create(enableLog: false).Save(p); + return true; + } + } +} diff --git a/src/admin/Bootstrap.DataAccess/DbManager.cs b/src/admin/Bootstrap.DataAccess/DbManager.cs index 4e065669..5c587d46 100644 --- a/src/admin/Bootstrap.DataAccess/DbManager.cs +++ b/src/admin/Bootstrap.DataAccess/DbManager.cs @@ -1,4 +1,9 @@ -using PetaPoco; +using Longbow.Data; +using Longbow.Web; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using PetaPoco; using System; using System.Collections.Specialized; @@ -14,12 +19,28 @@ namespace Bootstrap.DataAccess /// /// /// + /// 是否记录日志 /// - public static IDatabase Create(string connectionName = null, bool keepAlive = false) + public static IDatabase Create(string connectionName = null, bool keepAlive = false, bool enableLog = true) { if (Mappers.GetMapper(typeof(Exceptions), null) == null) Mappers.Register(typeof(Exceptions).Assembly, new BootstrapDataAccessConventionMapper()); var db = Longbow.Data.DbManager.Create(connectionName, keepAlive); db.ExceptionThrown += (sender, args) => args.Exception.Log(new NameValueCollection() { ["LastCmd"] = db.LastCommand }); + if (enableLog) + { + db.OnCommandExecuted(async provider => + { + var context = provider.GetRequiredService(); + var userName = context.HttpContext?.User.Identity.Name; + var log = new DBLog() + { + LogTime = DateTime.Now, + SQL = db.LastCommand, + UserName = userName + }; + await LogHelper.AddDBLog(log).ConfigureAwait(false); + }); + } return db; } } diff --git a/src/admin/Bootstrap.DataAccess/Helper/LogHelper.cs b/src/admin/Bootstrap.DataAccess/Helper/LogHelper.cs index ef485a3b..ade01c25 100644 --- a/src/admin/Bootstrap.DataAccess/Helper/LogHelper.cs +++ b/src/admin/Bootstrap.DataAccess/Helper/LogHelper.cs @@ -1,12 +1,15 @@ -using Longbow.Web.Mvc; +using Longbow.Tasks; +using Longbow.Web.Mvc; using PetaPoco; using System; +using System.Collections.Concurrent; using System.Collections.Generic; +using System.Threading; namespace Bootstrap.DataAccess { /// - /// + /// 操作日志相关操作类 /// public static class LogHelper { @@ -36,5 +39,55 @@ namespace Bootstrap.DataAccess log.LogTime = DateTime.Now; return DbContextManager.Create().Save(log); } + + #region 数据库脚本执行日志相关代码 + private static BlockingCollection _messageQueue = new BlockingCollection(new ConcurrentQueue()); + /// + /// 添加数据库日志实体类到内部集合中 + /// + /// + public static System.Threading.Tasks.Task AddDBLog(DBLog log) => System.Threading.Tasks.Task.Run(() => + { + if (!_messageQueue.IsAddingCompleted) + { + _messageQueue.Add(log); + } + }); + + /// + /// 查询所有SQL日志信息 + /// + /// + /// + /// + /// + /// + public static Page RetrieveDBLogs(PaginationOption op, DateTime? startTime, DateTime? endTime, string userName) => DbContextManager.Create().RetrievePages(op, startTime, endTime, userName); + + /// + /// 数据库脚本执行日志任务实体类 + /// + public class DbLogTask : ITask + { + /// + /// 任务执行方法 + /// + /// + /// + public System.Threading.Tasks.Task Execute(CancellationToken cancellationToken) + { + var logs = new List(); + while (_messageQueue.TryTake(out var log)) + { + logs.Add(log); + }; + using (var db = DbManager.Create(enableLog: false)) + { + db.InsertBatch(logs); + } + return System.Threading.Tasks.Task.CompletedTask; + } + } + #endregion } }