using System; using System.Collections.Generic; namespace CncSimulator.Core { /// 日志条目 public class LogEntry { /// 时间戳 public DateTime Timestamp { get; set; } /// 地址端口 public int AddressPort { get; set; } /// 设备数量 public int DeviceCount { get; set; } /// 关键数据摘要 public string KeyData { get; set; } /// 完整JSON public string FullJson { get; set; } /// 响应耗时(毫秒) public long Duration { get; set; } } /// 异常记录条目 public class ErrorRecord { /// 时间戳 public DateTime Timestamp { get; set; } /// 异常类型: http500, timeout, empty, malformed, refuse public string ErrorType { get; set; } /// 异常描述 public string Description { get; set; } /// 影响设备数 public int AffectedDevices { get; set; } } /// /// 日志记录器。同时写入内存环形缓冲和log4net文件。 /// public class LogRecorder { private readonly int _capacity; private readonly LogEntry[] _buffer; private int _writeIndex; private int _count; private readonly object _lock = new object(); private readonly log4net.ILog _log; // 异常记录列表(独立于请求日志) private readonly List _errors = new List(); private readonly object _errorLock = new object(); public LogRecorder(int capacity = 200) { _capacity = capacity; _buffer = new LogEntry[capacity]; _writeIndex = 0; _count = 0; _log = log4net.LogManager.GetLogger(typeof(LogRecorder)); } /// 记录一次返回 public void Record(int addressPort, int deviceCount, string keyData, string fullJson, long durationMs) { var entry = new LogEntry { Timestamp = DateTime.Now, AddressPort = addressPort, DeviceCount = deviceCount, KeyData = keyData, FullJson = fullJson, Duration = durationMs }; lock (_lock) { _buffer[_writeIndex] = entry; _writeIndex = (_writeIndex + 1) % _capacity; if (_count < _capacity) _count++; } // 写文件日志 _log.Info($"[{addressPort}] 返回{deviceCount}台设备, 耗时{durationMs}ms"); _log.Info($"[{addressPort}] 关键数据: {keyData}"); } /// 记录一次异常 public void RecordError(string errorType, string description, int affectedDevices) { var record = new ErrorRecord { Timestamp = DateTime.Now, ErrorType = errorType, Description = description, AffectedDevices = affectedDevices }; lock (_errorLock) { _errors.Add(record); // 限制数量 if (_errors.Count > 1000) _errors.RemoveAt(0); } _log.Warn($"[异常] 类型={errorType}, 影响{affectedDevices}台设备: {description}"); } /// 获取所有异常记录 public List GetErrors() { lock (_errorLock) { return new List(_errors); } } /// 获取异常次数统计 public int GetErrorCount() { lock (_errorLock) { return _errors.Count; } } /// 获取最近的日志 public List GetRecentLogs(int count) { var result = new List(); lock (_lock) { int toRead = Math.Min(count, _count); // 从最新到最旧 for (int i = 0; i < toRead; i++) { int idx = (_writeIndex - 1 - i + _capacity) % _capacity; result.Add(_buffer[idx]); } } return result; } /// 获取最新一条日志 public LogEntry GetLatest() { lock (_lock) { if (_count == 0) return null; int idx = (_writeIndex - 1 + _capacity) % _capacity; return _buffer[idx]; } } } }