Browse Source

log

feature/protocol-log-Perfect
root 4 months ago
parent
commit
10ea7ff96f
  1. 37
      CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs
  2. 32
      CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs
  3. 16
      CoreAgent.ProtocolClient/ProtocolEngineCore/ProtocolLogProcessor.cs
  4. 36
      modify.md

37
CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs

@ -41,6 +41,8 @@ namespace CoreAgent.Infrastructure.Services.Network
/// <param name="logDetails">协议日志详情</param>
public void OnProtocolLogsReceived(IEnumerable<TransferProtocolLog> logDetails)
{
_logger.LogInformation("OnProtocolLogsReceived 方法开始执行,线程ID: {ThreadId}", Thread.CurrentThread.ManagedThreadId);
if (_disposed)
{
_logger.LogWarning("NetworkProtocolLogObserver已释放,跳过日志处理");
@ -57,6 +59,8 @@ namespace CoreAgent.Infrastructure.Services.Network
var logList = logDetails.ToList();
var logCount = logList.Count;
_logger.LogInformation("OnProtocolLogsReceived 接收到日志数量: {LogCount}", logCount);
if (logCount == 0)
{
_logger.LogDebug("接收到的协议日志集合为空,跳过处理");
@ -64,15 +68,22 @@ namespace CoreAgent.Infrastructure.Services.Network
}
// 使用锁保护整个处理过程,确保线程安全
_logger.LogInformation("OnProtocolLogsReceived 准备获取锁,线程ID: {ThreadId}", Thread.CurrentThread.ManagedThreadId);
lock (_lock)
{
_logger.LogInformation("OnProtocolLogsReceived 已获取锁,开始处理日志,线程ID: {ThreadId}", Thread.CurrentThread.ManagedThreadId);
try
{
ProcessLogsInternal(logList, logCount);
_logger.LogInformation("OnProtocolLogsReceived 日志处理完成,线程ID: {ThreadId}", Thread.CurrentThread.ManagedThreadId);
}
catch (Exception ex)
{
_logger.LogError(ex, "协议日志处理过程中发生异常,数量: {LogCount}", logCount);
_logger.LogError(ex, "协议日志处理过程中发生异常,数量: {LogCount}, 线程ID: {ThreadId}", logCount, Thread.CurrentThread.ManagedThreadId);
}
finally
{
_logger.LogInformation("OnProtocolLogsReceived 释放锁,线程ID: {ThreadId}", Thread.CurrentThread.ManagedThreadId);
}
}
}
@ -84,14 +95,17 @@ namespace CoreAgent.Infrastructure.Services.Network
{
var startTime = DateTime.UtcNow;
_logger.LogDebug("开始处理协议日志,数量: {LogCount}", logCount);
_logger.LogInformation("ProcessLogsInternal 开始处理协议日志,数量: {LogCount}, 线程ID: {ThreadId}", logCount, Thread.CurrentThread.ManagedThreadId);
try
{
// 获取运行时配置键(外层已有锁保护)
_logger.LogInformation("ProcessLogsInternal 准备获取运行时配置键");
string runtimeCode = _context.GetNeConfigKey();
_logger.LogInformation("ProcessLogsInternal 获取到运行时配置键: {RuntimeCode}", runtimeCode);
// 将 CoreAgent.ProtocolClient 的 TransferProtocolLog 转换为 WebSocket 传输层的 MessageTransferProtocolLog
_logger.LogInformation("ProcessLogsInternal 开始转换日志数据格式");
var webSocketLogs = logList.Select(log => new MessageTransferProtocolLog
{
Id = log.Id,
@ -110,28 +124,33 @@ namespace CoreAgent.Infrastructure.Services.Network
RuntimeCode = runtimeCode,
});
ProtocolMessage message = new ProtocolMessage(webSocketLogs.ToArray());
var convertedLogs = webSocketLogs.ToArray();
_logger.LogInformation("ProcessLogsInternal 日志数据格式转换完成,转换后数量: {ConvertedCount}", convertedLogs.Length);
ProtocolMessage message = new ProtocolMessage(convertedLogs);
_logger.LogInformation("ProcessLogsInternal 创建协议消息完成");
// 尝试写入通道并跟踪结果
_logger.LogInformation("ProcessLogsInternal 准备写入通道,设备编码: {DeviceCode}", _context.DeviceCode);
var writeSuccess = _ChannelManager.SendChannel.TryWrite(message);
var processingTime = DateTime.UtcNow - startTime;
if (writeSuccess)
{
_logger.LogDebug("运行编码{RuntimeCode} 协议日志处理成功,数量: {LogCount}, 处理时间: {ProcessingTime}ms",
runtimeCode, logCount, processingTime.TotalMilliseconds);
_logger.LogInformation("运行编码{RuntimeCode} 协议日志处理成功,数量: {LogCount}, 处理时间: {ProcessingTime}ms, 线程ID: {ThreadId}",
runtimeCode, logCount, processingTime.TotalMilliseconds, Thread.CurrentThread.ManagedThreadId);
}
else
{
_logger.LogWarning("运行编码{RuntimeCode} 协议日志写入通道失败,数量: {LogCount}, 处理时间: {ProcessingTime}ms, 通道可能已满或已关闭",
runtimeCode, logCount, processingTime.TotalMilliseconds);
_logger.LogWarning("运行编码{RuntimeCode} 协议日志写入通道失败,数量: {LogCount}, 处理时间: {ProcessingTime}ms, 通道可能已满或已关闭, 线程ID: {ThreadId}",
runtimeCode, logCount, processingTime.TotalMilliseconds, Thread.CurrentThread.ManagedThreadId);
}
}
catch (Exception ex)
{
var processingTime = DateTime.UtcNow - startTime;
_logger.LogError(ex, "协议日志处理异常,数量: {LogCount}, 处理时间: {ProcessingTime}ms",
logCount, processingTime.TotalMilliseconds);
_logger.LogError(ex, "协议日志处理异常,数量: {LogCount}, 处理时间: {ProcessingTime}ms, 线程ID: {ThreadId}",
logCount, processingTime.TotalMilliseconds, Thread.CurrentThread.ManagedThreadId);
throw; // 重新抛出异常,让上层处理
}
}

32
CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs

@ -28,6 +28,9 @@ namespace CoreAgent.Infrastructure.Services.Network
_protocolLogObserver = protocolLogObserver ?? throw new ArgumentNullException(nameof(protocolLogObserver));
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
_clients = new Dictionary<string, ProtocolWsClient>();
// 记录观察者信息
_logger.LogInformation("ProtocolWsClientManager初始化完成,观察者类型: {ObserverType}", _protocolLogObserver.GetType().Name);
}
/// <summary>
@ -43,7 +46,15 @@ namespace CoreAgent.Infrastructure.Services.Network
if (string.IsNullOrEmpty(config.Name))
throw new ArgumentException("配置名称不能为空", nameof(config));
_logger.LogInformation("创建ProtocolWsClient实例: {ClientName}", config.Name);
// 检查观察者状态
if (_protocolLogObserver == null)
{
_logger.LogError("创建ProtocolWsClient时观察者实例为null");
throw new InvalidOperationException("协议日志观察者实例为null");
}
_logger.LogInformation("创建ProtocolWsClient实例: {ClientName}, 观察者类型: {ObserverType}",
config.Name, _protocolLogObserver.GetType().Name);
return new ProtocolWsClient(config, _loggerFactory, _protocolLogObserver);
}
@ -63,9 +74,17 @@ namespace CoreAgent.Infrastructure.Services.Network
return false;
}
// 检查观察者状态
if (_protocolLogObserver == null)
{
_logger.LogError("启动协议客户端时观察者实例为null");
return false;
}
lock (_lock)
{
_logger.LogInformation("开始启动所有协议客户端,配置数量: {ConfigCount}", configs.Length);
_logger.LogInformation("开始启动所有协议客户端,配置数量: {ConfigCount}, 观察者类型: {ObserverType}",
configs.Length, _protocolLogObserver.GetType().Name);
var startedCount = 0;
var failedCount = 0;
@ -76,9 +95,14 @@ namespace CoreAgent.Infrastructure.Services.Network
{
if (!_clients.ContainsKey(config.Name))
{
_logger.LogInformation("创建新的ProtocolWsClient实例: {ClientName}", config.Name);
var client = CreateProtocolWsClient(config);
_clients[config.Name] = client;
}
else
{
_logger.LogInformation("使用已存在的ProtocolWsClient实例: {ClientName}", config.Name);
}
var existingClient = _clients[config.Name];
existingClient.Start();
@ -212,6 +236,9 @@ namespace CoreAgent.Infrastructure.Services.Network
var client = kvp.Value;
var wasConnected = client.IsConnected;
_logger.LogInformation("准备停止协议客户端: {ClientName}, 当前连接状态: {IsConnected}",
kvp.Key, wasConnected);
// 先停止客户端,再释放资源
client.Stop();
client.Dispose();
@ -234,6 +261,7 @@ namespace CoreAgent.Infrastructure.Services.Network
}
// 移除所有客户端条目,确保下次StartAllClients会创建新实例
_logger.LogInformation("清空客户端列表,确保下次启动时创建新实例");
_clients.Clear();
var allDisconnected = disconnectedCount == stoppedCount;

16
CoreAgent.ProtocolClient/ProtocolEngineCore/ProtocolLogProcessor.cs

@ -170,6 +170,15 @@ namespace CoreAgent.ProtocolClient.ProtocolEngineCore
// 添加打印输出 - 通知观察者前的日志
_logger.LogInformation("开始通知协议日志观察者处理转换后的数据,线程ID: {ThreadId}, 日志详情数量: {LogDetailsCount}", threadId, logDetails.Count);
// 检查观察者实例状态
if (_protocolLogObserver == null)
{
_logger.LogError("协议日志观察者实例为null,无法通知");
return;
}
_logger.LogInformation("协议日志观察者实例检查通过,准备过滤日志");
// 过滤掉Info为空或无效的记录
var filteredLogDetails = logDetails.Where(detail =>
!string.IsNullOrWhiteSpace(detail.Info)
@ -178,7 +187,12 @@ namespace CoreAgent.ProtocolClient.ProtocolEngineCore
if (filteredLogDetails.Any())
{
_logger.LogInformation("过滤后有效日志记录数量: {FilteredCount},准备通知观察者", filteredLogDetails.Count);
// 记录调用前的详细信息
_logger.LogInformation("准备调用观察者OnProtocolLogsReceived方法,观察者类型: {ObserverType}", _protocolLogObserver.GetType().Name);
_protocolLogObserver.OnProtocolLogsReceived(filteredLogDetails);
_logger.LogInformation("成功通知协议日志观察者,已处理 {ProcessedCount} 条日志记录", filteredLogDetails.Count);
}
else
@ -188,7 +202,7 @@ namespace CoreAgent.ProtocolClient.ProtocolEngineCore
}
catch (Exception ex)
{
_logger.LogError(ex, "通知协议日志观察者失败");
_logger.LogError(ex, "通知协议日志观察者失败,观察者类型: {ObserverType}", _protocolLogObserver?.GetType().Name ?? "null");
}
_logger.LogDebug("ProcessLogDetails 处理完成,线程ID: {ThreadId}", threadId);

36
modify.md

@ -1,4 +1,5 @@
## 2025-01-02
### 日志规范修改 - GeneralCellularNetworkService和CellularNetworkContext
@ -1279,6 +1280,41 @@
**影响范围**:
# 修改记录
## 2025-08-21
### CoreAgent.Infrastructure/Services/Network/NetworkProtocolLogObserver.cs
- **问题**: 第一次停止协议客户端成功后,第二次启动时 OnProtocolLogsReceived 方法似乎没有被调用
- **修改**: 在 OnProtocolLogsReceived 和 ProcessLogsInternal 方法中添加了详细的跟踪日志
- 添加了方法开始执行的日志记录
- 添加了线程ID跟踪,便于调试多线程问题
- 添加了参数验证和数据处理各阶段的日志记录
- 添加了锁获取和释放的日志记录
- 添加了配置获取、数据转换、通道写入等关键步骤的日志记录
- 将部分 Debug 级别日志提升为 Information 级别,便于问题排查
**修改目的**: 通过详细的日志跟踪,帮助诊断为什么在第二次启动协议客户端时 OnProtocolLogsReceived 方法没有被正确调用的问题。
### CoreAgent.ProtocolClient/ProtocolEngineCore/ProtocolLogProcessor.cs
- **问题**: 第二次启动协议客户端时,虽然日志显示"成功通知协议日志观察者",但 OnProtocolLogsReceived 方法实际没有被处理
- **修改**: 在通知观察者的代码段中添加了更详细的诊断日志
- 添加了观察者实例null检查
- 添加了观察者类型信息记录
- 添加了方法调用前后的详细日志
- 改进了异常处理中的观察者信息记录
**修改目的**: 通过详细的观察者状态检查和方法调用跟踪,帮助诊断观察者实例状态问题,确定是观察者引用问题还是方法调用问题。
### CoreAgent.Infrastructure/Services/Network/ProtocolWsClientManager.cs
- **问题**: 需要检查观察者传递和管理是否存在问题
- **修改**: 在关键方法中添加了观察者状态检查和详细跟踪日志
- 在构造函数中添加了观察者类型信息记录
- 在 CreateProtocolWsClient 方法中添加了观察者null检查和类型信息
- 在 StartAllClients 方法中添加了观察者状态检查和详细启动日志
- 在 StopAllClients 方法中添加了更详细的停止过程日志
- 添加了客户端实例创建和复用的区分日志
**修改目的**: 通过详细的观察者状态跟踪和客户端生命周期日志,帮助诊断观察者传递链路中的问题,确保观察者实例在整个生命周期中的正确性。
## 2025-01-02
### 日志规范修改 - GeneralCellularNetworkService和CellularNetworkContext

Loading…
Cancel
Save