diff --git a/EonaCat.LogStack.LogClient/EonaCat.LogStack.LogClient.csproj b/EonaCat.LogStack.LogClient/EonaCat.LogStack.LogClient.csproj index bdd2cb0..98c43e2 100644 --- a/EonaCat.LogStack.LogClient/EonaCat.LogStack.LogClient.csproj +++ b/EonaCat.LogStack.LogClient/EonaCat.LogStack.LogClient.csproj @@ -25,7 +25,7 @@ - + diff --git a/EonaCat.LogStack.OpenTelemetryFlow/EonaCat.LogStack.OpenTelemetryFlow.csproj b/EonaCat.LogStack.OpenTelemetryFlow/EonaCat.LogStack.OpenTelemetryFlow.csproj index 0aab903..8fb1fe5 100644 --- a/EonaCat.LogStack.OpenTelemetryFlow/EonaCat.LogStack.OpenTelemetryFlow.csproj +++ b/EonaCat.LogStack.OpenTelemetryFlow/EonaCat.LogStack.OpenTelemetryFlow.csproj @@ -32,10 +32,10 @@ - - - - + + + + diff --git a/EonaCat.LogStack.Status/EonaCat.LogStack.Status.csproj b/EonaCat.LogStack.Status/EonaCat.LogStack.Status.csproj index 6f1e2f9..93b6d5f 100644 --- a/EonaCat.LogStack.Status/EonaCat.LogStack.Status.csproj +++ b/EonaCat.LogStack.Status/EonaCat.LogStack.Status.csproj @@ -7,8 +7,8 @@ False - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/EonaCat.LogStack.WindowsEventLogFlow/EonaCat.LogStack.Flows.WindowsEventLog.csproj b/EonaCat.LogStack.WindowsEventLogFlow/EonaCat.LogStack.Flows.WindowsEventLog.csproj index 834016f..83f6769 100644 --- a/EonaCat.LogStack.WindowsEventLogFlow/EonaCat.LogStack.Flows.WindowsEventLog.csproj +++ b/EonaCat.LogStack.WindowsEventLogFlow/EonaCat.LogStack.Flows.WindowsEventLog.csproj @@ -35,8 +35,8 @@ - - + + diff --git a/EonaCat.LogStack/EonaCat.LogStack.csproj b/EonaCat.LogStack/EonaCat.LogStack.csproj index 36440f3..c2b34c2 100644 --- a/EonaCat.LogStack/EonaCat.LogStack.csproj +++ b/EonaCat.LogStack/EonaCat.LogStack.csproj @@ -14,7 +14,7 @@ It features a rich fluent API for routing log events to dozens of destinations f EonaCat (Jeroen Saey) EonaCat;Logger;EonaCatLogStack;Log;Writer;Flows;LogStack;Memory;Speed;Jeroen;Saey - 0.1.7 + 0.1.8 README.md True LICENSE @@ -25,7 +25,7 @@ It features a rich fluent API for routing log events to dozens of destinations f - 0.1.7+{chash:10}.{c:ymd} + 0.1.8+{chash:10}.{c:ymd} true true v[0-9]* @@ -36,7 +36,7 @@ It features a rich fluent API for routing log events to dozens of destinations f - 0.1.7 + 0.1.8 EonaCat.LogStack EonaCat.LogStack https://git.saey.me/EonaCat/EonaCat.LogStack @@ -85,19 +85,19 @@ It features a rich fluent API for routing log events to dozens of destinations f - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + - + diff --git a/EonaCat.LogStack/EonaCatLogger.cs b/EonaCat.LogStack/EonaCatLogger.cs index 011a5c9..0f4139d 100644 --- a/EonaCat.LogStack/EonaCatLogger.cs +++ b/EonaCat.LogStack/EonaCatLogger.cs @@ -716,27 +716,55 @@ namespace EonaCat.LogStack } // Drain and stop the async channel pipeline if active - if (_asyncChannel != null) - { - _asyncChannel.Writer.TryComplete(); - - if (_asyncConsumer != null) - { - try - { - await _asyncConsumer.ConfigureAwait(false); - } - catch (Exception ex) - { - System.Diagnostics.Debug.WriteLine(ex); - } - } + if (_asyncChannel != null) + { + // Flush all logs from flows first to ensure they're written to disk + await FlushAsync().ConfigureAwait(false); + + // Complete the channel - no more writes allowed + _asyncChannel.Writer.TryComplete(); + + if (_asyncConsumer != null) + { + try + { + // Wait for the consumer task to finish draining the channel + // Use a generous timeout (30 seconds) since we're dealing with legitimate I/O + // but prevent infinite hangs if something is truly deadlocked + using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30))) + { + try + { + await _asyncConsumer.ConfigureAwait(false); + } + catch (OperationCanceledException) + { + // Do nothing + } + } + } + catch (Exception ex) + { + // Do nothing + } + } + } + else + { + // If using synchronous mode, just flush + await FlushAsync().ConfigureAwait(false); } - await FlushAsync().ConfigureAwait(false); - - var disposeTasks = _concurrentFlows.Select(f => f.DisposeAsync().AsTask()); - await Task.WhenAll(disposeTasks).ConfigureAwait(false); + // Dispose flows - they should already be flushed above + var disposeTasks = _concurrentFlows.Select(f => f.DisposeAsync().AsTask()).ToArray(); + try + { + await Task.WhenAll(disposeTasks).ConfigureAwait(false); + } + catch (Exception ex) + { + // Do nothing + } _asyncCts?.Dispose(); GC.SuppressFinalize(this); diff --git a/EonaCat.LogStack/EonaCatLoggerCore/Memory/MemoryOptimizations.cs b/EonaCat.LogStack/EonaCatLoggerCore/Memory/MemoryOptimizations.cs index 4f52bfc..00188c9 100644 --- a/EonaCat.LogStack/EonaCatLoggerCore/Memory/MemoryOptimizations.cs +++ b/EonaCat.LogStack/EonaCatLoggerCore/Memory/MemoryOptimizations.cs @@ -70,7 +70,6 @@ public static class MemoryOptimizations public static void TryCompact() { GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized, false); - GC.WaitForPendingFinalizers(); } /// diff --git a/Testers/EonaCat.LogStack.Test.Web/EonaCat.LogStack.Test.Web.csproj b/Testers/EonaCat.LogStack.Test.Web/EonaCat.LogStack.Test.Web.csproj index c71e25a..c53e494 100644 --- a/Testers/EonaCat.LogStack.Test.Web/EonaCat.LogStack.Test.Web.csproj +++ b/Testers/EonaCat.LogStack.Test.Web/EonaCat.LogStack.Test.Web.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive