feat(#I12FGX): 增加数据库日志功能

comment #I12FGX

link https://gitee.com/LongbowEnterprise/dashboard/issues?id=I12FGX
This commit is contained in:
Argo Zhang 2019-09-22 22:22:29 +08:00
parent 165ee1a960
commit 13fd8e2109
No known key found for this signature in database
GPG Key ID: 152E398953DDF19F
7 changed files with 174 additions and 11 deletions

View File

@ -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()));
}); });
} }
} }

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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" />

View File

@ -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;
}
}
}

View File

@ -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;
} }
} }

View File

@ -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
} }
} }