diff --git a/SHH.CameraSdk/Core/Features/FrameConsumer.cs b/SHH.CameraSdk/Core/Features/FrameConsumer.cs index 881aeea..7c382da 100644 --- a/SHH.CameraSdk/Core/Features/FrameConsumer.cs +++ b/SHH.CameraSdk/Core/Features/FrameConsumer.cs @@ -15,7 +15,7 @@ public class FrameConsumer : IDisposable { #region --- 私有资源与状态 (Private Resources & States) --- - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); /// 帧缓冲队列(容量1):仅存储最新一帧,保证零延迟渲染 /// BlockingCollection 封装线程安全操作,GetConsumingEnumerable 支持取消令牌 diff --git a/SHH.CameraSdk/Core/Manager/CameraManager.cs b/SHH.CameraSdk/Core/Manager/CameraManager.cs index a49329e..d05773c 100644 --- a/SHH.CameraSdk/Core/Manager/CameraManager.cs +++ b/SHH.CameraSdk/Core/Manager/CameraManager.cs @@ -11,7 +11,7 @@ public class CameraManager : IDisposable, IAsyncDisposable { #region --- 1. 核心资源与状态 (Fields & States) --- - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); /// 全局设备实例池(线程安全),Key = 设备唯一标识 private readonly ConcurrentDictionary _cameraPool = new(); diff --git a/SHH.CameraSdk/Core/Pipeline/ProcessingPipeline.cs b/SHH.CameraSdk/Core/Pipeline/ProcessingPipeline.cs index 60671ad..5fcc485 100644 --- a/SHH.CameraSdk/Core/Pipeline/ProcessingPipeline.cs +++ b/SHH.CameraSdk/Core/Pipeline/ProcessingPipeline.cs @@ -15,7 +15,7 @@ public class ProcessingPipeline { #region --- 私有资源与状态 (Private Resources & States) --- - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); /// 任务队列(有界通道):存储待处理的帧任务 private readonly Channel _queue; diff --git a/SHH.CameraSdk/Core/Resilience/CameraCoordinator.cs b/SHH.CameraSdk/Core/Resilience/CameraCoordinator.cs index 399e9da..5c51340 100644 --- a/SHH.CameraSdk/Core/Resilience/CameraCoordinator.cs +++ b/SHH.CameraSdk/Core/Resilience/CameraCoordinator.cs @@ -15,7 +15,7 @@ public class CameraCoordinator { #region --- 私有资源与配置 (Private Resources & Configurations) --- - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); /// 已注册的相机设备集合(线程安全,支持并发添加与遍历) private readonly ConcurrentBag _cameras = new(); diff --git a/SHH.CameraSdk/Core/Scheduling/FrameController.cs b/SHH.CameraSdk/Core/Scheduling/FrameController.cs index 5005d41..e1bf959 100644 --- a/SHH.CameraSdk/Core/Scheduling/FrameController.cs +++ b/SHH.CameraSdk/Core/Scheduling/FrameController.cs @@ -11,7 +11,7 @@ namespace SHH.CameraSdk; /// public class FrameController { - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); // 需求字典 private readonly ConcurrentDictionary _requirements = new(); diff --git a/SHH.CameraSdk/Core/Services/BaseFrameProcessor.cs b/SHH.CameraSdk/Core/Services/BaseFrameProcessor.cs index 2f9339b..20bc05e 100644 --- a/SHH.CameraSdk/Core/Services/BaseFrameProcessor.cs +++ b/SHH.CameraSdk/Core/Services/BaseFrameProcessor.cs @@ -19,7 +19,7 @@ namespace SHH.CameraSdk { #region --- 受保护成员 --- - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); /// Worker 线程池,负责具体的帧处理任务 protected readonly List _workers = new List(); @@ -165,7 +165,7 @@ namespace SHH.CameraSdk { #region --- 私有成员 --- - private static ILogger _gRpcLog = Log.ForContext("SourceContext", LogModules.gRpc); + private ILogger _gRpcLog = Log.ForContext("SourceContext", LogModules.gRpc); /// 线程内任务队列,容量限制100,防止内存溢出 private readonly BlockingCollection<(long DeviceId, SmartFrame Frame, FrameDecision Decision)> _taskQueue = new BlockingCollection<(long, SmartFrame, FrameDecision)>(100); diff --git a/SHH.CameraSdk/Core/Services/DisplayWindowManager.cs b/SHH.CameraSdk/Core/Services/DisplayWindowManager.cs index 3ab373f..5eaa026 100644 --- a/SHH.CameraSdk/Core/Services/DisplayWindowManager.cs +++ b/SHH.CameraSdk/Core/Services/DisplayWindowManager.cs @@ -20,7 +20,7 @@ namespace SHH.CameraSdk { #region --- 内部窗口上下文类 --- - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); /// /// 单个窗口的上下文信息载体 diff --git a/SHH.CameraSdk/Core/Services/ProcessingConfigManager.cs b/SHH.CameraSdk/Core/Services/ProcessingConfigManager.cs index 1d9b692..62edc09 100644 --- a/SHH.CameraSdk/Core/Services/ProcessingConfigManager.cs +++ b/SHH.CameraSdk/Core/Services/ProcessingConfigManager.cs @@ -9,7 +9,7 @@ namespace SHH.CameraSdk; /// public class ProcessingConfigManager { - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); // 内存字典:Key=设备ID, Value=配置对象 private readonly ConcurrentDictionary _configs = new(); diff --git a/SHH.CameraSdk/Drivers/BaseVideoSource.cs b/SHH.CameraSdk/Drivers/BaseVideoSource.cs index 0ff2a8f..256a2bf 100644 --- a/SHH.CameraSdk/Drivers/BaseVideoSource.cs +++ b/SHH.CameraSdk/Drivers/BaseVideoSource.cs @@ -1,4 +1,6 @@ -namespace SHH.CameraSdk; +using Serilog; + +namespace SHH.CameraSdk; /// /// [架构基类] 工业级视频源抽象核心 (V3.3.4 严格匹配版) @@ -39,6 +41,8 @@ public abstract class BaseVideoSource : IVideoSource, IAsyncDisposable, IDeviceC } } + protected abstract ILogger _sdkLog { get; } + #region --- 1. 核心配置与锁机制 (Core Config & Locks) --- /// diff --git a/SHH.CameraSdk/Drivers/HikVision/HikVideoSource.cs b/SHH.CameraSdk/Drivers/HikVision/HikVideoSource.cs index 394fccf..ad91d83 100644 --- a/SHH.CameraSdk/Drivers/HikVision/HikVideoSource.cs +++ b/SHH.CameraSdk/Drivers/HikVision/HikVideoSource.cs @@ -20,7 +20,8 @@ public class HikVideoSource : BaseVideoSource, #region --- 静态资源 (Global Resources) --- // 日志实例 - private static ILogger _sdkLog = Log.ForContext("SourceContext", LogModules.HikVisionSdk); + protected override ILogger _sdkLog => Log.ForContext("SourceContext", LogModules.HikVisionSdk); + // 静态路由表 private static readonly ConcurrentDictionary _instances = new(); // 全局异常回调 @@ -108,7 +109,7 @@ public class HikVideoSource : BaseVideoSource, if (!HikSdkManager.Initialize()) { - _sdkLog.Error("HikVision Sdk 初始化失败."); + _sdkLog.Error("[SDK] HikVision Sdk 初始化失败."); throw new CameraException(CameraErrorCode.SdkNotInitialized, "HikVision Sdk 初始化失败.", DeviceBrand.HikVision); } @@ -117,8 +118,8 @@ public class HikVideoSource : BaseVideoSource, HikNativeMethods.NET_DVR_SetExceptionCallBack_V30(0, IntPtr.Zero, _globalExceptionCallback, IntPtr.Zero); // [审计] 记录登录动作 - AddAuditLog($"Hik 正在执行登录 => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}"); - _sdkLog.Information($"Hik 正在执行登录 => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}"); + _sdkLog.Information($"[SDK] Hik 正在执行登录 => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}"); + AddAuditLog($"[SDK] Hik 正在执行登录 => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}"); var devInfo = new HikNativeMethods.NET_DEVICEINFO_V30(); int newUserId = HikNativeMethods.NET_DVR_Login_V30( @@ -138,7 +139,9 @@ public class HikVideoSource : BaseVideoSource, } _instances.TryAdd(_userId, this); - AddAuditLog($"物理登录成功 (UserID: {_userId})"); + + _sdkLog.Information($"[SDK] Hik 登录成功 => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}"); + AddAuditLog($"[SDK] Hik 登录成功 => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}"); // 开启取流 if (!StartRealPlay()) @@ -147,11 +150,13 @@ public class HikVideoSource : BaseVideoSource, throw new CameraException(HikErrorMapper.Map(err), $"预览失败: {err}", DeviceBrand.HikVision, (int)err); } - AddAuditLog($"网络取流成功 (StreamType: {_config.StreamType})"); + _sdkLog.Debug($"[SDK] Hik 网络取流成功 => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}"); + AddAuditLog($"[SDK] Hik 网络取流成功 => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}"); } catch (Exception ex) { - AddAuditLog($"启动异常: {ex.Message}"); + _sdkLog.Error($"[SDK] Hik 启动异常. => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}"); + AddAuditLog($"[SDK] Hik 启动异常. => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}"); CleanupSync(); throw; } @@ -161,9 +166,14 @@ public class HikVideoSource : BaseVideoSource, protected override async Task OnStopAsync() { Interlocked.Increment(ref _connectionEpoch); - AddAuditLog("正在执行停止流程..."); + + _sdkLog.Debug($"[SDK] Hik 正在执行停止流程. => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}"); + AddAuditLog($"[SDK] Hik 正在执行停止流程. => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}"); + await Task.Run(() => CleanupSync()); - AddAuditLog("设备已停止"); + + _sdkLog.Information($"[SDK] Hik 设备已停止. => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}"); + AddAuditLog($"[SDK] Hik 设备已停止. => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}"); } private void CleanupSync() @@ -218,6 +228,8 @@ public class HikVideoSource : BaseVideoSource, if (options.StreamType.HasValue) { int targetStream = options.StreamType.Value; + + _sdkLog.Debug($"[SDK] Hik 收到码流切换请求. => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}, 播放句柄:{_realPlayHandle}"); AddAuditLog($"收到码流切换请求: {targetStream},开始执行热切换..."); lock (_initLock) @@ -244,12 +256,14 @@ public class HikVideoSource : BaseVideoSource, // D. 重新开启预览 if (StartRealPlay()) { - AddAuditLog($"码流热切换成功 (当前: {(_config.StreamType == 0 ? "主" : "子")}码流)"); + _sdkLog.Information($"[SDK] Hik 码流热切换成功. => 当前: {(_config.StreamType == 0 ? "主" : "子")}码流), ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}, 播放句柄:{_realPlayHandle}"); + AddAuditLog($"[SDK] Hik 码流热切换成功. => 当前: {(_config.StreamType == 0 ? "主" : "子")}码流), ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}, 播放句柄:{_realPlayHandle}"); } else { uint err = HikNativeMethods.NET_DVR_GetLastError(); - AddAuditLog($"码流切换失败: {err}"); + _sdkLog.Information($"[SDK] Hik 码流切换失败. => Err:{err}, ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}, 播放句柄:{_realPlayHandle}"); + AddAuditLog($"[SDK] Hik 码流切换失败. => Err:{err}, ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}, 播放句柄:{_realPlayHandle}"); } } } @@ -258,7 +272,8 @@ public class HikVideoSource : BaseVideoSource, if (options.RenderHandle.HasValue) { // 如果是硬解码模式,可以在这里调用 PlayM4_Play(port, newHandle) - AddAuditLog($"收到新句柄绑定请求: {options.RenderHandle}"); + _sdkLog.Information($"[SDK] Hik 收到新句柄绑定请求, 新句柄:{options.RenderHandle}. => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}, 播放句柄:{_realPlayHandle}"); + AddAuditLog($"[SDK] Hik 收到新句柄绑定请求, 新句柄:{options.RenderHandle}. => ID:{_config.Id} IP:{_config.IpAddress} Port:{_config.Port} Name:{_config.Name}, UserID: {_userId}, 播放句柄:{_realPlayHandle}"); } } @@ -425,7 +440,10 @@ public class HikVideoSource : BaseVideoSource, { if (_instances.TryGetValue(lUserID, out var instance)) { - instance.AddAuditLog($"SDK报警异常: 0x{dwType:X}"); // 写入审计 + Log.ForContext("SourceContext", LogModules.HikVisionSdk) + .Error($"Hik SDK 报警异常: 0x{dwType:X}, UserId: {lUserID} "); + + instance.AddAuditLog($"SDK报警 User:{pUser} 异常: 0x{dwType:X}, UserId: {lUserID}"); // 写入审计 instance.ReportError(new CameraException( CameraErrorCode.NetworkUnreachable, $"SDK全局异常: 0x{dwType:X}", diff --git a/SHH.CameraService/Core/CommandDispatcher.cs b/SHH.CameraService/Core/CommandDispatcher.cs index 8a26f09..9e8892b 100644 --- a/SHH.CameraService/Core/CommandDispatcher.cs +++ b/SHH.CameraService/Core/CommandDispatcher.cs @@ -11,7 +11,7 @@ namespace SHH.CameraService; /// public class CommandDispatcher { - private static ILogger _gRpcLog = Log.ForContext("SourceContext", LogModules.gRpc); + private ILogger _gRpcLog = Log.ForContext("SourceContext", LogModules.gRpc); private readonly Dictionary _handlers; /// diff --git a/SHH.CameraService/Core/ParentProcessSentinel.cs b/SHH.CameraService/Core/ParentProcessSentinel.cs index 80af562..2b06166 100644 --- a/SHH.CameraService/Core/ParentProcessSentinel.cs +++ b/SHH.CameraService/Core/ParentProcessSentinel.cs @@ -14,7 +14,7 @@ public class ParentProcessSentinel : BackgroundService { private readonly ServiceConfig _config; private readonly IHostApplicationLifetime _lifetime; - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); /// /// 使用统一的结构化日志记录器,SourceContext 设置为 Core 模块 diff --git a/SHH.CameraService/GrpcImpls/Handlers/DeviceConfigHandler.cs b/SHH.CameraService/GrpcImpls/Handlers/DeviceConfigHandler.cs index 10334b3..c3eea7a 100644 --- a/SHH.CameraService/GrpcImpls/Handlers/DeviceConfigHandler.cs +++ b/SHH.CameraService/GrpcImpls/Handlers/DeviceConfigHandler.cs @@ -11,7 +11,7 @@ namespace SHH.CameraService; /// public class DeviceConfigHandler : ICommandHandler { - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); private readonly CameraManager _cameraManager; diff --git a/SHH.CameraService/GrpcImpls/Handlers/DeviceStatusHandler.cs b/SHH.CameraService/GrpcImpls/Handlers/DeviceStatusHandler.cs index d324e99..d1b32a5 100644 --- a/SHH.CameraService/GrpcImpls/Handlers/DeviceStatusHandler.cs +++ b/SHH.CameraService/GrpcImpls/Handlers/DeviceStatusHandler.cs @@ -16,7 +16,7 @@ namespace SHH.CameraService; /// public class DeviceStatusHandler : BackgroundService { - private static ILogger _gRpcLog = Log.ForContext("SourceContext", LogModules.gRpc); + private ILogger _gRpcLog = Log.ForContext("SourceContext", LogModules.gRpc); private readonly CameraManager _manager; private readonly ServiceConfig _config; diff --git a/SHH.CameraService/GrpcImpls/Handlers/RemoveCameraHandler.cs b/SHH.CameraService/GrpcImpls/Handlers/RemoveCameraHandler.cs index 58b9efe..708a9d2 100644 --- a/SHH.CameraService/GrpcImpls/Handlers/RemoveCameraHandler.cs +++ b/SHH.CameraService/GrpcImpls/Handlers/RemoveCameraHandler.cs @@ -11,7 +11,7 @@ namespace SHH.CameraService /// public class RemoveCameraHandler : ICommandHandler { - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); private readonly CameraManager _cameraManager; diff --git a/SHH.CameraService/GrpcImpls/ImageFactory/ImageMonitorController.cs b/SHH.CameraService/GrpcImpls/ImageFactory/ImageMonitorController.cs index 6d828e1..2b1c3bc 100644 --- a/SHH.CameraService/GrpcImpls/ImageFactory/ImageMonitorController.cs +++ b/SHH.CameraService/GrpcImpls/ImageFactory/ImageMonitorController.cs @@ -15,7 +15,7 @@ namespace SHH.CameraService; /// public class ImageMonitorController : BackgroundService { - private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); + private ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core); // 注入所有注册的目标(云端、大屏等),实现动态分发 private readonly IEnumerable _targets; diff --git a/SHH.CameraService/GrpcImpls/ImageProcs/GrpcSenderWorker.cs b/SHH.CameraService/GrpcImpls/ImageProcs/GrpcSenderWorker.cs index cc0dce1..055df53 100644 --- a/SHH.CameraService/GrpcImpls/ImageProcs/GrpcSenderWorker.cs +++ b/SHH.CameraService/GrpcImpls/ImageProcs/GrpcSenderWorker.cs @@ -13,7 +13,7 @@ namespace SHH.CameraService; /// public class GrpcSenderWorker : BackgroundService { - private static ILogger _gRpcLog = Log.ForContext("SourceContext", LogModules.gRpc); + private ILogger _gRpcLog = Log.ForContext("SourceContext", LogModules.gRpc); private readonly StreamTarget _target; private readonly string _grpcUrl;