feat(#I12FGX): 增加数据库日志功能
comment #I12FGX link https://gitee.com/LongbowEnterprise/dashboard/issues?id=I12FGX
This commit is contained in:
parent
165ee1a960
commit
13fd8e2109
|
@ -1,9 +1,10 @@
|
||||||
using Longbow.Tasks;
|
using Bootstrap.DataAccess;
|
||||||
|
using Longbow.Tasks;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using Task = System.Threading.Tasks.Task;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyInjection
|
namespace Microsoft.Extensions.DependencyInjection
|
||||||
{
|
{
|
||||||
|
@ -49,6 +50,9 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
|
|
||||||
// 创建任务并禁用
|
// 创建任务并禁用
|
||||||
TaskServicesManager.GetOrAdd("禁用任务", token => Task.Delay(1000)).Status = SchedulerStatus.Disabled;
|
TaskServicesManager.GetOrAdd("禁用任务", token => Task.Delay(1000)).Status = SchedulerStatus.Disabled;
|
||||||
|
|
||||||
|
// 真实任务负责批次写入数据执行脚本到日志中
|
||||||
|
TaskServicesManager.GetOrAdd<LogHelper.DbLogTask>("数据库脚本执行日志", TriggerBuilder.Build(Cron.Minutely()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
namespace Bootstrap.DataAccess.MongoDB
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DBLog 实体类
|
||||||
|
/// </summary>
|
||||||
|
public class DBLog : DataAccess.DBLog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 保存数据库脚本日志方法 MongoDB 无脚本
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override bool Save(DataAccess.DBLog p) => true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,12 +8,12 @@ using System.Linq;
|
||||||
namespace Bootstrap.DataAccess.MongoDB
|
namespace Bootstrap.DataAccess.MongoDB
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// 操作日志实体类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Log : DataAccess.Log
|
public class Log : DataAccess.Log
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// 分页查询操作日志
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="po"></param>
|
/// <param name="po"></param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
|
@ -64,7 +64,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// 查询所有操作日志
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="endTime"></param>
|
||||||
|
@ -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)));
|
private static void DeleteLogAsync() => System.Threading.Tasks.Task.Run(() => DbManager.Logs.DeleteMany(log => log.LogTime < DateTime.Now.AddDays(-7)));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// 保存操作日志
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="log"></param>
|
/// <param name="log"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
|
|
@ -7,12 +7,13 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.2.21" />
|
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.2.21" />
|
||||||
<PackageReference Include="Longbow.Configuration" Version="2.2.7" />
|
<PackageReference Include="Longbow.Configuration" Version="2.2.7" />
|
||||||
<PackageReference Include="Longbow.Data" Version="2.3.7" />
|
<PackageReference Include="Longbow.Data" Version="2.3.8-beta" />
|
||||||
<PackageReference Include="Longbow.GiteeAuth" Version="2.2.0" />
|
<PackageReference Include="Longbow.GiteeAuth" Version="2.2.0" />
|
||||||
<PackageReference Include="Longbow.GitHubAuth" Version="2.2.0" />
|
<PackageReference Include="Longbow.GitHubAuth" Version="2.2.0" />
|
||||||
<PackageReference Include="Longbow.Logging" Version="2.2.13" />
|
<PackageReference Include="Longbow.Logging" Version="2.2.13" />
|
||||||
<PackageReference Include="Longbow.PetaPoco" Version="1.0.2" />
|
<PackageReference Include="Longbow.PetaPoco" Version="1.0.2" />
|
||||||
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
|
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
|
||||||
|
<PackageReference Include="Longbow.Tasks" Version="2.2.23" />
|
||||||
<PackageReference Include="Longbow.Web" Version="2.2.16" />
|
<PackageReference Include="Longbow.Web" Version="2.2.16" />
|
||||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="PetaPoco.Extensions" Version="1.0.9" />
|
<PackageReference Include="PetaPoco.Extensions" Version="1.0.9" />
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
using Longbow.Web.Mvc;
|
||||||
|
using PetaPoco;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Bootstrap.DataAccess
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 后台数据库脚本执行日志实体类
|
||||||
|
/// </summary>
|
||||||
|
[TableName("DBLogs")]
|
||||||
|
public class DBLog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获得/设置 主键ID
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获得/设置 当前登陆名
|
||||||
|
/// </summary>
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获得/设置 数据库执行脚本
|
||||||
|
/// </summary>
|
||||||
|
public string SQL { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取/设置 用户角色关联状态 checked 标示已经关联 '' 标示未关联
|
||||||
|
/// </summary>
|
||||||
|
public DateTime LogTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询所有操作日志信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="po"></param>
|
||||||
|
/// <param name="startTime"></param>
|
||||||
|
/// <param name="endTime"></param>
|
||||||
|
/// <param name="userName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual Page<DBLog> 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<DBLog>(po.PageIndex, po.Limit, sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除日志信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存新增的日志信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public virtual bool Save(DBLog p)
|
||||||
|
{
|
||||||
|
if (p == null) throw new ArgumentNullException(nameof(p));
|
||||||
|
DeleteLogAsync();
|
||||||
|
DbManager.Create(enableLog: false).Save(p);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
|
|
||||||
|
@ -14,12 +19,28 @@ namespace Bootstrap.DataAccess
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="connectionName"></param>
|
/// <param name="connectionName"></param>
|
||||||
/// <param name="keepAlive"></param>
|
/// <param name="keepAlive"></param>
|
||||||
|
/// <param name="log">是否记录日志</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
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());
|
if (Mappers.GetMapper(typeof(Exceptions), null) == null) Mappers.Register(typeof(Exceptions).Assembly, new BootstrapDataAccessConventionMapper());
|
||||||
var db = Longbow.Data.DbManager.Create(connectionName, keepAlive);
|
var db = Longbow.Data.DbManager.Create(connectionName, keepAlive);
|
||||||
db.ExceptionThrown += (sender, args) => args.Exception.Log(new NameValueCollection() { ["LastCmd"] = db.LastCommand });
|
db.ExceptionThrown += (sender, args) => args.Exception.Log(new NameValueCollection() { ["LastCmd"] = db.LastCommand });
|
||||||
|
if (enableLog)
|
||||||
|
{
|
||||||
|
db.OnCommandExecuted(async provider =>
|
||||||
|
{
|
||||||
|
var context = provider.GetRequiredService<IHttpContextAccessor>();
|
||||||
|
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;
|
return db;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
using Longbow.Web.Mvc;
|
using Longbow.Tasks;
|
||||||
|
using Longbow.Web.Mvc;
|
||||||
using PetaPoco;
|
using PetaPoco;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Bootstrap.DataAccess
|
namespace Bootstrap.DataAccess
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// 操作日志相关操作类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class LogHelper
|
public static class LogHelper
|
||||||
{
|
{
|
||||||
|
@ -36,5 +39,45 @@ namespace Bootstrap.DataAccess
|
||||||
log.LogTime = DateTime.Now;
|
log.LogTime = DateTime.Now;
|
||||||
return DbContextManager.Create<Log>().Save(log);
|
return DbContextManager.Create<Log>().Save(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region 数据库脚本执行日志相关代码
|
||||||
|
private static BlockingCollection<DBLog> _messageQueue = new BlockingCollection<DBLog>(new ConcurrentQueue<DBLog>());
|
||||||
|
/// <summary>
|
||||||
|
/// 添加数据库日志实体类到内部集合中
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="log"></param>
|
||||||
|
public static System.Threading.Tasks.Task AddDBLog(DBLog log) => System.Threading.Tasks.Task.Run(() =>
|
||||||
|
{
|
||||||
|
if (!_messageQueue.IsAddingCompleted)
|
||||||
|
{
|
||||||
|
_messageQueue.Add(log);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 数据库脚本执行日志任务实体类
|
||||||
|
/// </summary>
|
||||||
|
public class DbLogTask : ITask
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 任务执行方法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public System.Threading.Tasks.Task Execute(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var logs = new List<DBLog>();
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue