Dispenser/DispenserCore/Service/OperationLogHandler.cs

110 lines
3.1 KiB
C#

using System.Collections.Concurrent;
using DispenserCommon.DTO;
using DispenserCommon.Events;
using DispenserCommon.Ioc;
using DispenserCommon.Utils;
using DispenserCore.Context;
using DispenserCore.Model.Entity;
using Masuit.Tools;
using Serilog;
namespace DispenserCore.Service;
/// <summary>
/// 操作日志处理器
/// </summary>
[Component]
public class OperationLogHandler
{
private static readonly BlockingCollection<ActionLog> Queue = new();
private readonly OperationLogService _service = ServiceLocator.GetService<OperationLogService>();
private readonly GlobalSessionHolder _session = ServiceLocator.GetService<GlobalSessionHolder>();
private bool _started;
private readonly object _lock = new();
// 批量罗盘阈值
private const int Batch = 1;
/// <summary>
/// 往队列里面添加操作日志
/// </summary>
/// <param name="_"></param>
/// <param name="actionLog"></param>
[EventAction(EventType.OperationLog)]
public void Record(EventType _, ActionLog actionLog)
{
Queue.Add(actionLog);
if (!_started)
{
Start();
}
}
/// <summary>
/// 启动日志记录处理器
/// </summary>
private void Start()
{
lock (_lock)
{
Task.Run(() =>
{
try
{
_started = true;
while (!Queue.IsCompleted)
{
List<OperationLog> logs = [];
var session = _session.GetSession();
while (Queue.TryTake(out var log))
{
if (log.IsNullOrEmpty()) continue;
var operationLog = new OperationLog
{
Action = log.Name,
Params = JsonUtil.ToJson(log.Params),
Exception = JsonUtil.ToJson(log.Exception),
OperateTime = log.OperateTime
};
if (session != null)
{
operationLog.UserId = session.User.Id;
operationLog.UserName = session.User.UserName;
}
// 将log 写入日志
logs.Add(operationLog);
if (logs.Count < Batch) continue;
// 每10条一批刷新到数据库
FlushToDb(logs);
logs = [];
}
}
}
catch (Exception e)
{
Log.Error(e,"操作日志保存异常: ");
}
}).ConfigureAwait(false);
}
}
/// <summary>
/// 保存到数据库
/// </summary>
private void FlushToDb(IEnumerable<OperationLog> logs)
{
_service.BatchInsert(logs);
}
}