From 0cabcba1b840657cd0e6a573d3e76b53cababf49 Mon Sep 17 00:00:00 2001 From: Jeroen Saey Date: Fri, 13 Feb 2026 08:56:32 +0100 Subject: [PATCH] Updated --- .../EonaCatCoreLogger/FileLoggerProvider.cs | 55 +++++++++++++++---- .../EonaCatCoreLogger/HttpLogger.cs | 19 ++++++- .../Internal/BatchingLoggerProvider.cs | 13 ++++- EonaCat.Logger/Managers/LogManager.cs | 1 + EonaCat.Logger/Servers/Splunk/Splunk.cs | 4 ++ EonaCat.Logger/Servers/Tcp/Tcp.cs | 11 +++- EonaCat.Logger/Servers/Udp/Udp.cs | 11 +++- 7 files changed, 97 insertions(+), 17 deletions(-) diff --git a/EonaCat.Logger/EonaCatCoreLogger/FileLoggerProvider.cs b/EonaCat.Logger/EonaCatCoreLogger/FileLoggerProvider.cs index 3c8bd05..969cbfb 100644 --- a/EonaCat.Logger/EonaCatCoreLogger/FileLoggerProvider.cs +++ b/EonaCat.Logger/EonaCatCoreLogger/FileLoggerProvider.cs @@ -165,7 +165,8 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider, IDisposable _ = PeriodicFlushAsync().ContinueWith(_ => Interlocked.Exchange(ref _isFlushing, 0)); } - internal override Task WriteMessagesAsync(IReadOnlyList messages, CancellationToken token) + internal override Task WriteMessagesAsync(IReadOnlyList messages, CancellationToken token +) { try { @@ -384,22 +385,43 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider, IDisposable private async Task CompressionWorkerAsync() { - while (!_disposed) + try { - await _queueSignal.WaitAsync(); - if (_compressionQueue.TryDequeue(out var filePath)) + while (!_disposed) { - await _compressionSemaphore.WaitAsync(); try { - await CompressOldLogFileAsync(filePath); + // Use a timeout to avoid hanging if disposed + if (!await _queueSignal.WaitAsync(TimeSpan.FromSeconds(1))) + { + if (_disposed) break; + continue; + } } - finally + catch { - _compressionSemaphore.Release(); + // Handle cancellation or disposal race condition + break; + } + + if (_compressionQueue.TryDequeue(out var filePath)) + { + await _compressionSemaphore.WaitAsync(); + try + { + await CompressOldLogFileAsync(filePath); + } + finally + { + _compressionSemaphore.Release(); + } } } } + catch (OperationCanceledException) + { + // Normal shutdown + } } @@ -777,10 +799,21 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider, IDisposable _files.Clear(); _messageQueues.Clear(); - // Wait for compression worker to finish remaining tasks - while (_compressionQueue.Count > 0) + // Signal compression worker to stop and wait for it to finish + _compressionSemaphore?.Dispose(); + _queueSignal?.Dispose(); + + // Wait for compression worker to finish remaining tasks with timeout + try { - await Task.Delay(100); + if (_compressionWorker != null && !_compressionWorker.IsCompleted) + { + await Task.WhenAny(_compressionWorker, Task.Delay(TimeSpan.FromSeconds(5))); + } + } + catch + { + // Do nothing } _aes?.Dispose(); diff --git a/EonaCat.Logger/EonaCatCoreLogger/HttpLogger.cs b/EonaCat.Logger/EonaCatCoreLogger/HttpLogger.cs index bf47fdd..1c9efac 100644 --- a/EonaCat.Logger/EonaCatCoreLogger/HttpLogger.cs +++ b/EonaCat.Logger/EonaCatCoreLogger/HttpLogger.cs @@ -117,14 +117,27 @@ namespace EonaCat.Logger.EonaCatCoreLogger public void Dispose() { + if (_processingTask == null || _processingTask.IsCompleted) + { + return; + } + _cts.Cancel(); _queue.CompleteAdding(); try { - _processingTask.Wait(); + // Use a timeout to avoid hanging + if (!_processingTask.Wait(TimeSpan.FromSeconds(5))) + { + // Task didn't complete in time, but we'll dispose anyway + } } - catch + catch (AggregateException ex) when (ex.InnerException is OperationCanceledException) + { + // Expected during cancellation + } + catch { // Do nothing } @@ -132,6 +145,8 @@ namespace EonaCat.Logger.EonaCatCoreLogger _queue.Dispose(); _cts.Dispose(); _client.Dispose(); + + GC.SuppressFinalize(this); } } } diff --git a/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs b/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs index 89acf7e..6b00745 100644 --- a/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs +++ b/EonaCat.Logger/EonaCatCoreLogger/Internal/BatchingLoggerProvider.cs @@ -128,7 +128,15 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable if (batch.Count == 0) { // Wait until a new log arrives or cancellation is requested - WaitHandle.WaitAny(new WaitHandle[] { _signal, _cts.Token.WaitHandle }); + try + { + WaitHandle.WaitAny(new WaitHandle[] { _signal, _cts.Token.WaitHandle }, TimeSpan.FromSeconds(1)); + } + catch + { + // Handle any WaitHandle disposal race condition + if (_disposed) break; + } continue; } @@ -172,11 +180,12 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable _disposed = true; _cts.Cancel(); - _worker.Join(); + _worker.Join(TimeSpan.FromSeconds(5)); OnShutdownFlushAsync().ConfigureAwait(false); _cts.Dispose(); + _signal.Dispose(); } protected virtual async Task OnShutdownFlushAsync() diff --git a/EonaCat.Logger/Managers/LogManager.cs b/EonaCat.Logger/Managers/LogManager.cs index 222d692..b68b239 100644 --- a/EonaCat.Logger/Managers/LogManager.cs +++ b/EonaCat.Logger/Managers/LogManager.cs @@ -298,6 +298,7 @@ namespace EonaCat.Logger.Managers await StopLoggingAsync().ConfigureAwait(false); + // Unsubscribe from events to prevent memory leaks LogHelper.OnException -= LogHelper_OnException; LogHelper.OnLogLevelDisabled -= LogHelper_OnLogLevelDisabled; diff --git a/EonaCat.Logger/Servers/Splunk/Splunk.cs b/EonaCat.Logger/Servers/Splunk/Splunk.cs index 89aab9e..d18310e 100644 --- a/EonaCat.Logger/Servers/Splunk/Splunk.cs +++ b/EonaCat.Logger/Servers/Splunk/Splunk.cs @@ -134,6 +134,10 @@ namespace EonaCat.Logger.Servers.Splunk return await _httpClient.SendAsync(request).ConfigureAwait(false); } + catch (ObjectDisposedException) + { + throw; + } catch (Exception ex) { OnException?.Invoke(this, ex); diff --git a/EonaCat.Logger/Servers/Tcp/Tcp.cs b/EonaCat.Logger/Servers/Tcp/Tcp.cs index aeac49e..197414c 100644 --- a/EonaCat.Logger/Servers/Tcp/Tcp.cs +++ b/EonaCat.Logger/Servers/Tcp/Tcp.cs @@ -177,8 +177,17 @@ namespace EonaCat.Logger.Servers.Tcp if (disposing) { DisposeTcp(); - _sendLock.Dispose(); + try + { + _sendLock.Dispose(); + } + catch + { + // Handle any potential disposal issues + } } + + GC.SuppressFinalize(this); } ~Tcp() diff --git a/EonaCat.Logger/Servers/Udp/Udp.cs b/EonaCat.Logger/Servers/Udp/Udp.cs index c82ce1d..6c24a8d 100644 --- a/EonaCat.Logger/Servers/Udp/Udp.cs +++ b/EonaCat.Logger/Servers/Udp/Udp.cs @@ -198,8 +198,17 @@ namespace EonaCat.Logger.Servers.Udp if (disposing) { DisposeUdp(); - _sendLock.Dispose(); + try + { + _sendLock.Dispose(); + } + catch + { + // Handle any potential disposal issues + } } + + GC.SuppressFinalize(this); } ~Udp()