diff --git a/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs b/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs index 0fe6c4a63..a2e36a757 100644 --- a/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs +++ b/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs @@ -28,9 +28,11 @@ namespace NzbDrone.Core.Instrumentation public void Register() { - Rule = new LoggingRule("*", LogLevel.Info, this); + var target = new SlowRunningAsyncTargetWrapper(this) { TimeToSleepBetweenBatches = 500 }; - LogManager.Configuration.AddTarget("DbLogger", new AsyncTargetWrapper(this)); + Rule = new LoggingRule("*", LogLevel.Info, target); + + LogManager.Configuration.AddTarget("DbLogger", target); LogManager.Configuration.LoggingRules.Add(Rule); LogManager.ConfigurationReloaded += OnLogManagerOnConfigurationReloaded; LogManager.ReconfigExistingLoggers(); diff --git a/src/NzbDrone.Core/Instrumentation/SlowRunningAsyncTargetWrapper.cs b/src/NzbDrone.Core/Instrumentation/SlowRunningAsyncTargetWrapper.cs new file mode 100644 index 000000000..0998e0260 --- /dev/null +++ b/src/NzbDrone.Core/Instrumentation/SlowRunningAsyncTargetWrapper.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using NLog.Common; +using NLog.Targets; +using NLog.Targets.Wrappers; + +namespace NzbDrone.Core.Instrumentation +{ + [Target("SlowRunningAsyncTargetWrapper", IsWrapper = true)] + public class SlowRunningAsyncTargetWrapper : AsyncTargetWrapper + { + private int _state; // 0 = idle, 1 = timer active, 2 = timer active + possibly more work + + public SlowRunningAsyncTargetWrapper(Target wrappedTarget) + : base(wrappedTarget) + { + + } + + protected override void StopLazyWriterThread() + { + if (Interlocked.Exchange(ref _state, 0) > 0) + { + base.StopLazyWriterThread(); + } + } + + protected override void Write(AsyncLogEventInfo logEvent) + { + base.Write(logEvent); + + if (Interlocked.Exchange(ref _state, 2) <= 0) + { // Timer was idle. Starting. + base.StartLazyWriterTimer(); + } + } + + protected override void StartLazyWriterTimer() + { + // Is executed when the background task has finished processing the queue. (also executed by base.InitializeTarget once) + + if (Interlocked.Decrement(ref _state) == 1) + { // There might be more work. Restart timer. + base.StartLazyWriterTimer(); + } + } + } +} diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 6a783eda4..672a17623 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -641,6 +641,7 @@ +