Updated
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user