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;
///
/// 操作日志处理器
///
[Component]
public class OperationLogHandler
{
private static readonly BlockingCollection Queue = new();
private readonly OperationLogService _service = ServiceLocator.GetService();
private readonly GlobalSessionHolder _session = ServiceLocator.GetService();
private bool _started;
private readonly object _lock = new();
// 批量罗盘阈值
private const int Batch = 1;
///
/// 往队列里面添加操作日志
///
///
///
[EventAction(EventType.OperationLog)]
public void Record(EventType _, ActionLog actionLog)
{
Queue.Add(actionLog);
if (!_started)
{
Start();
}
}
///
/// 启动日志记录处理器
///
private void Start()
{
lock (_lock)
{
Task.Run(() =>
{
try
{
_started = true;
while (!Queue.IsCompleted)
{
List 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);
}
}
///
/// 保存到数据库
///
private void FlushToDb(IEnumerable logs)
{
_service.BatchInsert(logs);
}
}