using LibCameraSharp; using Microsoft.Extensions.Logging; namespace GSS2.Test; public sealed class LibCameraLogSink : IDisposable { private readonly ILogger _logger; private readonly ILogger _loggerCamera; private readonly ILogger _loggerRPI; private readonly ILogger _loggerDeviceEnumerator; private readonly ILogger _loggerIPAProxy; private readonly ILogger _loggerWRAPPER; private bool _disposedValue; public LibCameraLogSink(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger("LibCamera"); _loggerCamera = loggerFactory.CreateLogger("LibCamera-Camera"); _loggerRPI = loggerFactory.CreateLogger("LibCamera-RPI"); _loggerDeviceEnumerator = loggerFactory.CreateLogger("LibCamera-DeviceEnumerator"); _loggerIPAProxy = loggerFactory.CreateLogger("LibCamera-IPAProxy"); _loggerWRAPPER = loggerFactory.CreateLogger("LibCamera-WRAPPER"); Log.Initialize(); Log.SetLevel("Camera", Log.LogLevelEnum.DEBUG); Log.SetLevel("RPI", Log.LogLevelEnum.DEBUG); Log.SetLevel("DeviceEnumerator", Log.LogLevelEnum.DEBUG); Log.SetLevel("IPAProxy", Log.LogLevelEnum.DEBUG); Log.SetLevel("WRAPPER", Log.LogLevelEnum.DEBUG); Log.LogReceived += OnLogReceived; } private void OnLogReceived(object? sender, Log.LogEventArgs e) { if (_disposedValue) return; try { var level = MapLogLevel(e.Level); var logger = e.Category switch { "Camera" => _loggerCamera, "RPI" => _loggerRPI, "DeviceEnumerator" => _loggerDeviceEnumerator, "IPAProxy" => _loggerIPAProxy, "WRAPPER" => _loggerWRAPPER, _ => null }; if (logger is not null && logger.IsEnabled(level)) logger.Log(level, new EventId(0, $"{e.ThreadId} {e.File}"), e, null, static (state, _) => $"{state.Message}"); else if (logger is null && _logger.IsEnabled(level)) _logger.Log(level, new EventId(0, $"{e.ThreadId} {e.File}"), e, null, static (state, _) => $"[{state.Category}] {state.Message}"); } catch { } } private static LogLevel MapLogLevel(Log.LogLevelEnum level) => level switch { Log.LogLevelEnum.DEBUG => LogLevel.Debug, Log.LogLevelEnum.INFO => LogLevel.Information, Log.LogLevelEnum.WARN => LogLevel.Warning, Log.LogLevelEnum.ERROR => LogLevel.Error, Log.LogLevelEnum.FATAL => LogLevel.Critical, _ => LogLevel.None }; private void Dispose(bool disposing) { if (!_disposedValue) { if (disposing) { Log.LogReceived -= OnLogReceived; } _disposedValue = true; } } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } }