This commit is contained in:
Jeroen Saey
2026-02-13 08:56:32 +01:00
parent 8cdca1031f
commit 0cabcba1b8
7 changed files with 97 additions and 17 deletions

View File

@@ -165,7 +165,8 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider, IDisposable
_ = PeriodicFlushAsync().ContinueWith(_ => Interlocked.Exchange(ref _isFlushing, 0)); _ = PeriodicFlushAsync().ContinueWith(_ => Interlocked.Exchange(ref _isFlushing, 0));
} }
internal override Task WriteMessagesAsync(IReadOnlyList<LogMessage> messages, CancellationToken token) internal override Task WriteMessagesAsync(IReadOnlyList<LogMessage> messages, CancellationToken token
)
{ {
try try
{ {
@@ -384,22 +385,43 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider, IDisposable
private async Task CompressionWorkerAsync() private async Task CompressionWorkerAsync()
{ {
while (!_disposed) try
{ {
await _queueSignal.WaitAsync(); while (!_disposed)
if (_compressionQueue.TryDequeue(out var filePath))
{ {
await _compressionSemaphore.WaitAsync();
try 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(); _files.Clear();
_messageQueues.Clear(); _messageQueues.Clear();
// Wait for compression worker to finish remaining tasks // Signal compression worker to stop and wait for it to finish
while (_compressionQueue.Count > 0) _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(); _aes?.Dispose();

View File

@@ -117,12 +117,25 @@ namespace EonaCat.Logger.EonaCatCoreLogger
public void Dispose() public void Dispose()
{ {
if (_processingTask == null || _processingTask.IsCompleted)
{
return;
}
_cts.Cancel(); _cts.Cancel();
_queue.CompleteAdding(); _queue.CompleteAdding();
try 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 (AggregateException ex) when (ex.InnerException is OperationCanceledException)
{
// Expected during cancellation
} }
catch catch
{ {
@@ -132,6 +145,8 @@ namespace EonaCat.Logger.EonaCatCoreLogger
_queue.Dispose(); _queue.Dispose();
_cts.Dispose(); _cts.Dispose();
_client.Dispose(); _client.Dispose();
GC.SuppressFinalize(this);
} }
} }
} }

View File

@@ -128,7 +128,15 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
if (batch.Count == 0) if (batch.Count == 0)
{ {
// Wait until a new log arrives or cancellation is requested // 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; continue;
} }
@@ -172,11 +180,12 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
_disposed = true; _disposed = true;
_cts.Cancel(); _cts.Cancel();
_worker.Join(); _worker.Join(TimeSpan.FromSeconds(5));
OnShutdownFlushAsync().ConfigureAwait(false); OnShutdownFlushAsync().ConfigureAwait(false);
_cts.Dispose(); _cts.Dispose();
_signal.Dispose();
} }
protected virtual async Task OnShutdownFlushAsync() protected virtual async Task OnShutdownFlushAsync()

View File

@@ -298,6 +298,7 @@ namespace EonaCat.Logger.Managers
await StopLoggingAsync().ConfigureAwait(false); await StopLoggingAsync().ConfigureAwait(false);
// Unsubscribe from events to prevent memory leaks
LogHelper.OnException -= LogHelper_OnException; LogHelper.OnException -= LogHelper_OnException;
LogHelper.OnLogLevelDisabled -= LogHelper_OnLogLevelDisabled; LogHelper.OnLogLevelDisabled -= LogHelper_OnLogLevelDisabled;

View File

@@ -134,6 +134,10 @@ namespace EonaCat.Logger.Servers.Splunk
return await _httpClient.SendAsync(request).ConfigureAwait(false); return await _httpClient.SendAsync(request).ConfigureAwait(false);
} }
catch (ObjectDisposedException)
{
throw;
}
catch (Exception ex) catch (Exception ex)
{ {
OnException?.Invoke(this, ex); OnException?.Invoke(this, ex);

View File

@@ -177,8 +177,17 @@ namespace EonaCat.Logger.Servers.Tcp
if (disposing) if (disposing)
{ {
DisposeTcp(); DisposeTcp();
_sendLock.Dispose(); try
{
_sendLock.Dispose();
}
catch
{
// Handle any potential disposal issues
}
} }
GC.SuppressFinalize(this);
} }
~Tcp() ~Tcp()

View File

@@ -198,8 +198,17 @@ namespace EonaCat.Logger.Servers.Udp
if (disposing) if (disposing)
{ {
DisposeUdp(); DisposeUdp();
_sendLock.Dispose(); try
{
_sendLock.Dispose();
}
catch
{
// Handle any potential disposal issues
}
} }
GC.SuppressFinalize(this);
} }
~Udp() ~Udp()