diff --git a/src/NzbDrone.Common.Test/InstrumentationTests/SentryTargetFixture.cs b/src/NzbDrone.Common.Test/InstrumentationTests/SentryTargetFixture.cs
new file mode 100644
index 000000000..3a3098a23
--- /dev/null
+++ b/src/NzbDrone.Common.Test/InstrumentationTests/SentryTargetFixture.cs
@@ -0,0 +1,87 @@
+using NUnit.Framework;
+using NzbDrone.Common.Instrumentation;
+using FluentAssertions;
+using NzbDrone.Common.Instrumentation.Sentry;
+using System;
+using NLog;
+using NzbDrone.Test.Common;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace NzbDrone.Common.Test.InstrumentationTests
+{
+ [TestFixture]
+ public class SentryTargetFixture : TestBase
+ {
+ private SentryTarget Subject;
+
+ private static LogLevel[] AllLevels = LogLevel.AllLevels.ToArray();
+ private static LogLevel[] SentryLevels = LogLevel.AllLevels.Where(x => x >= LogLevel.Error).ToArray();
+ private static LogLevel[] OtherLevels = AllLevels.Except(SentryLevels).ToArray();
+
+ private static Exception[] FilteredExceptions = new Exception[] {
+ new UnauthorizedAccessException(),
+ new TinyIoC.TinyIoCResolutionException(typeof(string))
+ };
+
+ [SetUp]
+ public void Setup()
+ {
+ Subject = new SentryTarget("https://aaaaaaaaaaaaaaaaaaaaaaaaaa@sentry.io/111111");
+ }
+
+ private LogEventInfo GivenLogEvent(LogLevel level, Exception ex, string message)
+ {
+ return LogEventInfo.Create(level, "SentryTest", ex, CultureInfo.InvariantCulture, message);
+ }
+
+ [Test, TestCaseSource("AllLevels")]
+ public void log_without_error_is_not_sentry_event(LogLevel level)
+ {
+ Subject.IsSentryMessage(GivenLogEvent(level, null, "test")).Should().BeFalse();
+ }
+
+ [Test, TestCaseSource("SentryLevels")]
+ public void error_or_worse_with_exception_is_sentry_event(LogLevel level)
+ {
+ Subject.IsSentryMessage(GivenLogEvent(level, new Exception(), "test")).Should().BeTrue();
+ }
+
+ [Test, TestCaseSource("OtherLevels")]
+ public void less_than_error_with_exception_is_not_sentry_event(LogLevel level)
+ {
+ Subject.IsSentryMessage(GivenLogEvent(level, new Exception(), "test")).Should().BeFalse();
+ }
+
+ [Test, TestCaseSource("FilteredExceptions")]
+ public void should_filter_event_for_filtered_exception_types(Exception ex)
+ {
+ var log = GivenLogEvent(LogLevel.Error, ex, "test");
+ Subject.IsSentryMessage(log).Should().BeFalse();
+ }
+
+ [Test, TestCaseSource("FilteredExceptions")]
+ public void should_not_filter_event_for_filtered_exception_types_if_filtering_disabled(Exception ex)
+ {
+ Subject.FilterEvents = false;
+ var log = GivenLogEvent(LogLevel.Error, ex, "test");
+ Subject.IsSentryMessage(log).Should().BeTrue();
+ }
+
+ [Test, TestCaseSource(typeof(SentryTarget), "FilteredExceptionMessages")]
+ public void should_filter_event_for_filtered_exception_messages(string message)
+ {
+ var log = GivenLogEvent(LogLevel.Error, new Exception("aaaaaaa" + message + "bbbbbbb"), "test");
+ Subject.IsSentryMessage(log).Should().BeFalse();
+ }
+
+ [TestCase("A message that isn't filtered")]
+ [TestCase("Error")]
+ public void should_not_filter_event_for_exception_messages_that_are_not_filtered(string message)
+ {
+ var log = GivenLogEvent(LogLevel.Error, new Exception(message), "test");
+ Subject.IsSentryMessage(log).Should().BeTrue();
+ }
+ }
+}
diff --git a/src/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj b/src/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj
index 69459d7b1..412384a51 100644
--- a/src/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj
+++ b/src/NzbDrone.Common.Test/NzbDrone.Common.Test.csproj
@@ -93,6 +93,7 @@
+
@@ -166,4 +167,4 @@
-->
-
\ No newline at end of file
+
diff --git a/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs b/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs
index 4d5e736ab..02d226ad7 100644
--- a/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs
+++ b/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs
@@ -40,10 +40,10 @@ namespace NzbDrone.Common.Instrumentation.Sentry
// Filter out people stuck in boot loops
"CorruptDatabaseException",
// This also filters some people in boot loops
- "TinyIoC.TinyIoCResolutionException"
+ "TinyIoCResolutionException"
};
- private static readonly List FilteredExceptionMessages = new List {
+ public static readonly List FilteredExceptionMessages = new List {
// Swallow the many, many exceptions flowing through from Jackett
"Jackett.Common.IndexerException",
// Fix openflixr being stupid with permissions
@@ -115,6 +115,11 @@ namespace NzbDrone.Common.Instrumentation.Sentry
});
_debounce = new SentryDebounce();
+
+ // initialize to true and reconfigure later
+ // Otherwise it will default to false and any errors occuring
+ // before config file gets read will not be filtered
+ FilterEvents = true;
}
private void OnError(Exception ex)
@@ -168,7 +173,7 @@ namespace NzbDrone.Common.Instrumentation.Sentry
return fingerPrint;
}
- private bool IsSentryMessage(LogEventInfo logEvent)
+ public bool IsSentryMessage(LogEventInfo logEvent)
{
if (logEvent.Properties.ContainsKey("Sentry"))
{