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