From b58e3845c45c00422e482eae5f28e3ae278f6cef Mon Sep 17 00:00:00 2001 From: Dustin Chilson Date: Wed, 3 Mar 2021 07:08:38 -0500 Subject: [PATCH] Fix Exception handling (#198) --- .../NLogGraylogHttp.Example.NetFx/App.config | 2 +- .../NLog.Config | 2 +- .../GraylogHttpTarget.cs | 34 ++++++++++++++++--- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/examples/netFx/NLogGraylogHttp.Example.NetFx/App.config b/examples/netFx/NLogGraylogHttp.Example.NetFx/App.config index 7e4b38a..8cb01fa 100644 --- a/examples/netFx/NLogGraylogHttp.Example.NetFx/App.config +++ b/examples/netFx/NLogGraylogHttp.Example.NetFx/App.config @@ -6,7 +6,7 @@ - + diff --git a/examples/netcore/NLogGraylogHttp.Example.NetCore/NLog.Config b/examples/netcore/NLogGraylogHttp.Example.NetCore/NLog.Config index a7e618e..dcffb04 100644 --- a/examples/netcore/NLogGraylogHttp.Example.NetCore/NLog.Config +++ b/examples/netcore/NLogGraylogHttp.Example.NetCore/NLog.Config @@ -1,5 +1,5 @@  - + diff --git a/src/NLog.Targets.GraylogHttp/GraylogHttpTarget.cs b/src/NLog.Targets.GraylogHttp/GraylogHttpTarget.cs index 73025e5..dd8f945 100644 --- a/src/NLog.Targets.GraylogHttp/GraylogHttpTarget.cs +++ b/src/NLog.Targets.GraylogHttp/GraylogHttpTarget.cs @@ -7,6 +7,7 @@ using NLog.Config; using Polly; using Polly.CircuitBreaker; +using Polly.Wrap; namespace NLog.Targets.GraylogHttp { @@ -15,7 +16,7 @@ public class GraylogHttpTarget : TargetWithContext { private HttpClient _httpClient; private Uri _requestAddress; - private CircuitBreakerPolicy _policy; + private PolicyWrap _policy; public GraylogHttpTarget() { @@ -68,13 +69,27 @@ protected override void InitializeTarget() _httpClient.DefaultRequestHeaders.ExpectContinue = false; // Expect (100) Continue breaks the graylog server - _policy = Policy - .Handle() + var waitAndRetryPolicy = Policy + .Handle(e => !(e is BrokenCircuitException)) + .WaitAndRetry( + 1, + attempt => TimeSpan.FromMilliseconds(200), + (exception, calculatedWaitDuration) => + { + InternalLogger.Error(exception, "GraylogHttp(Name={0}): Graylog server error, the log messages were not sent to the server.", Name); + }); + + var circuitBreakerPolicy = Policy + .Handle(e => !(e is BrokenCircuitException)) .AdvancedCircuitBreaker( (double)FailureThreshold / 100, TimeSpan.FromSeconds(SamplingDurationSeconds), MinimumThroughput, - TimeSpan.FromSeconds(FailureCooldownSeconds)); + TimeSpan.FromSeconds(FailureCooldownSeconds), + (exception, span) => InternalLogger.Error(exception, "GraylogHttp(Name={0}): Circuit breaker Open", Name), + () => InternalLogger.Info("GraylogHttp(Name={0}): Circuit breaker Reset", Name)); + + _policy = Policy.Wrap(waitAndRetryPolicy, circuitBreakerPolicy); // Prefix the custom properties with underscore upfront, so we don't have to do it for each log-event foreach (TargetPropertyWithContext p in ContextProperties) @@ -137,7 +152,7 @@ protected override void Write(LogEventInfo logEvent) try { - _policy.Execute(() => + _policy.ExecuteAndCapture(() => { var content = new StringContent(messageBuilder.Render(logEvent.TimeStamp), Encoding.UTF8, "application/json"); return _httpClient.PostAsync(_requestAddress, content).Result.EnsureSuccessStatusCode(); @@ -149,6 +164,15 @@ protected override void Write(LogEventInfo logEvent) "GraylogHttp(Name={0}): The Graylog server seems to be inaccessible, the log messages were not sent to the server.", Name); } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception ex) +#pragma warning restore CA1031 // Do not catch general exception types + { + InternalLogger.Error( + ex, + "GraylogHttp(Name={0}): Graylog server error, the log messages were not sent to the server.", + Name); + } } ///