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