规范并补充日志内容

This commit is contained in:
2026-01-16 14:30:42 +08:00
parent 4e0bb33ce2
commit fd6a82eb4e
28 changed files with 325 additions and 537 deletions

View File

@@ -6,7 +6,7 @@ using SHH.Contracts.Grpc;
namespace SHH.CameraService;
/// <summary>
/// gRPC 指令分发器
/// gRpc 指令分发器
/// 职责:接收从 GrpcCommandReceiverWorker 传入的 Proto 消息,解析参数并路由至具体的 Handler。
/// </summary>
public class CommandDispatcher
@@ -29,14 +29,14 @@ public class CommandDispatcher
/// <summary>
/// 执行指令分发
/// </summary>
/// <param name="protoMsg">从 gRPC Server Streaming 接收到的原始 Proto 指令对象</param>
/// <param name="protoMsg">从 gRpc Server Streaming 接收到的原始 Proto 指令对象</param>
public async Task DispatchAsync(CommandPayloadProto protoMsg)
{
if (protoMsg == null) return;
string cmdCode = protoMsg.CmdCode; // 例如 "Sync_Camera"
_gRpcLog.Information($"[gRPC] 响应请求, 业务:{protoMsg.CmdCode}, 请求ID:{protoMsg.RequestId}, 业务分发.");
_gRpcLog.Debug($"[gRPC] 响应请求, {protoMsg.CmdCode}, 请求ID:{protoMsg.RequestId}, 业务分发 => {protoMsg}");
_gRpcLog.Information($"[gRpc] 响应请求, 业务:{protoMsg.CmdCode}, 请求ID:{protoMsg.RequestId}, 业务分发.");
_gRpcLog.Debug($"[gRpc] 响应请求, {protoMsg.CmdCode}, 请求ID:{protoMsg.RequestId}, 业务分发 => {protoMsg}");
try
{
@@ -51,20 +51,20 @@ public class CommandDispatcher
// 3. 调用具体业务执行
await handler.ExecuteAsync(token);
_gRpcLog.Information($"[gRPC] 业务:{protoMsg.CmdCode}, 请求ID:{protoMsg.RequestId}, 执行成功.");
_gRpcLog.Information($"[gRpc] 业务:{protoMsg.CmdCode}, 请求ID:{protoMsg.RequestId}, 执行成功.");
}
else
{
_gRpcLog.Warning($"[gRPC] 业务:{protoMsg.CmdCode}, 请求ID:{protoMsg.RequestId}, 未找到指令处理器.");
_gRpcLog.Warning($"[gRpc] 业务:{protoMsg.CmdCode}, 请求ID:{protoMsg.RequestId}, 未找到指令处理器.");
}
}
catch (Exception ex)
{
_gRpcLog.Error($"[gRPC] 业务:{protoMsg.CmdCode}, 请求ID:{protoMsg.RequestId}, 执行指令处理异常: {ex.Message}.");
_gRpcLog.Error($"[gRpc] 业务:{protoMsg.CmdCode}, 请求ID:{protoMsg.RequestId}, 执行指令处理异常: {ex.Message}.");
}
// 注意:关于 ACK (require_ack)
// 在 NetMQ 时代需要手动回发结果,在 gRPC Server Streaming 模式下,
// 在 NetMQ 时代需要手动回发结果,在 gRpc Server Streaming 模式下,
// 建议通过 Unary RPC (例如另设一个 ReportCommandResult 方法) 异步上报执行结果。
}
}

View File

@@ -1,44 +1,52 @@
using System.Diagnostics;
using Ayay.SerilogLogs;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using SHH.CameraSdk;
using System.Diagnostics;
namespace SHH.CameraService;
/// <summary>
/// 父进程守护服务 (BackgroundService)
/// <para>核心逻辑:定期检查启动本服务的父进程是否存活,若父进程退出(如 UI 崩溃),则触发本服务自动退出,避免孤儿进程占用相机硬件资源。</para>
/// </summary>
public class ParentProcessSentinel : BackgroundService
{
private readonly ServiceConfig _config;
private readonly IHostApplicationLifetime _lifetime;
private readonly ILogger<ParentProcessSentinel> _logger;
private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core);
/// <summary>
/// 使用统一的结构化日志记录器SourceContext 设置为 Core 模块
/// </summary>
public ParentProcessSentinel(
ServiceConfig config,
IHostApplicationLifetime lifetime,
ILogger<ParentProcessSentinel> logger)
IHostApplicationLifetime lifetime)
{
_config = config;
_lifetime = lifetime;
_logger = logger;
}
/// <summary>
/// 执行后台守护逻辑
/// </summary>
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
int pid = _config.ParentPid;
// 如果 PID 为 0 或负数,说明不需要守护(可能是手动启动调试)
// 1. 验证 PID 合法性。如果 PID 为 0 或负数,可能是手动启动调试模式,不执行守护逻辑
if (pid <= 0)
{
_logger.LogInformation("未指定有效的父进程 PID守护模式已禁用。");
_sysLog.Warning("[Sentinel] 未指定有效的父进程 PID ({ParentPid}),守护模式已禁用,服务将持续运行.", pid);
return;
}
_logger.LogInformation($"父进程守护已启动,正在监控 PID: {pid}");
_sysLog.Information("[Sentinel] 父进程守护已启动,正在监控目标 PID: {ParentPid}", pid);
while (!stoppingToken.IsCancellationRequested)
{
if (!IsParentRunning(pid))
{
_logger.LogWarning($"[ALERT] 检测到父进程 (PID:{pid}) 已退出!正在终止当前服务...");
_sysLog.Warning("[Sentinel] ### ALERT ### 检测到父进程 (PID:{ParentPid}) 已退出!正在下发系统终止信号...", pid);
// 触发程序优雅退出
_lifetime.StopApplication();
@@ -52,6 +60,11 @@ public class ParentProcessSentinel : BackgroundService
}
}
/// <summary>
/// 核心状态判定:通过 PID 获取进程快照并检查存活状态
/// </summary>
/// <param name="pid">父进程 ID</param>
/// <returns>存活返回 True已消亡返回 False</returns>
private bool IsParentRunning(int pid)
{
try
@@ -72,7 +85,7 @@ public class ParentProcessSentinel : BackgroundService
}
catch (Exception ex)
{
_logger.LogError(ex, "检查父进程状态时发生未知错误,默认为存活");
_sysLog.Debug("[Sentinel] 无法定位 PID 为 {ParentPid} 的进程,判定为已退出.", pid);
return true; // 发生未知错误时,保守起见认为它还活着
}
}