From 1d3f6a7c46e7d402be4943f6617153664a82214c Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Thu, 20 Oct 2022 17:13:47 +0200 Subject: [PATCH 1/6] added opt-out for adding logs as breadcrumbs --- .../Resources/Sentry/SentryOptions.asset | 1 + .../ConfigurationWindow/EnrichmentTab.cs | 7 ++++ .../UnityLogHandlerIntegration.cs | 9 +++-- .../ScriptableSentryUnityOptions.cs | 1 + src/Sentry.Unity/SentryUnityOptions.cs | 5 +++ .../UnityLogHandlerIntegrationTests.cs | 34 +++++++++++++++++++ 6 files changed, 55 insertions(+), 2 deletions(-) diff --git a/samples/unity-of-bugs/Assets/Resources/Sentry/SentryOptions.asset b/samples/unity-of-bugs/Assets/Resources/Sentry/SentryOptions.asset index 5ff473987..2ea744359 100644 --- a/samples/unity-of-bugs/Assets/Resources/Sentry/SentryOptions.asset +++ b/samples/unity-of-bugs/Assets/Resources/Sentry/SentryOptions.asset @@ -25,6 +25,7 @@ MonoBehaviour: k__BackingField: 1 k__BackingField: 2 k__BackingField: 75 + k__BackingField: 1 k__BackingField: 100 k__BackingField: 1 k__BackingField: 0 diff --git a/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs b/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs index 6f3e0a7d0..40efa9b4a 100644 --- a/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs +++ b/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs @@ -63,6 +63,13 @@ internal static void Display(ScriptableSentryUnityOptions options) EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, 1), Color.gray); EditorGUILayout.Space(); + options.AddLogsAsBreadcrumbs = EditorGUILayout.Toggle( + new GUIContent("Add Logs as Breadcrumbs", "Whether to capture 'LogType.Log' and " + + "'LogType.Log' as breadcrumbs automatically.\n" + + "'LogType.Error' will get captured in any case and added as " + + "breadcrumb to subsequent events."), + options.AddLogsAsBreadcrumbs); + options.MaxBreadcrumbs = EditorGUILayout.IntField( new GUIContent("Max Breadcrumbs", "Maximum number of breadcrumbs that get captured." + "\nDefault: 100"), diff --git a/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs b/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs index 4a212d9ca..b2f1ad620 100644 --- a/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs +++ b/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs @@ -127,10 +127,15 @@ internal void CaptureLogFormat(LogType logType, UnityEngine.Object? context, str if (logType is LogType.Error or LogType.Assert) { _hub.CaptureMessage(logMessage, ToEventTagType(logType)); + // So the next event includes this as a breadcrumb + _hub.AddBreadcrumb(message: logMessage, category: "unity.logger", level: ToBreadcrumbLevel(logType)); + return; } - // So the next event includes this as a breadcrumb - _hub.AddBreadcrumb(message: logMessage, category: "unity.logger", level: ToBreadcrumbLevel(logType)); + if (_sentryOptions?.addLogsAsBreadcrumbs is true) + { + _hub.AddBreadcrumb(message: logMessage, category: "unity.logger", level: ToBreadcrumbLevel(logType)); + } } private void OnQuitting() diff --git a/src/Sentry.Unity/ScriptableSentryUnityOptions.cs b/src/Sentry.Unity/ScriptableSentryUnityOptions.cs index dbe50bba3..de4506f8d 100644 --- a/src/Sentry.Unity/ScriptableSentryUnityOptions.cs +++ b/src/Sentry.Unity/ScriptableSentryUnityOptions.cs @@ -43,6 +43,7 @@ public static string GetConfigPath(string? notDefaultConfigName = null) [field: SerializeField] public ScreenshotQuality ScreenshotQuality { get; set; } = ScreenshotQuality.High; [field: SerializeField] public int ScreenshotCompression { get; set; } = 75; + [field: SerializeField] public bool AddLogsAsBreadcrumbs { get; set; } = true; [field: SerializeField] public int MaxBreadcrumbs { get; set; } = Constants.DefaultMaxBreadcrumbs; [field: SerializeField] public ReportAssembliesMode ReportAssembliesMode { get; set; } = ReportAssembliesMode.Version; diff --git a/src/Sentry.Unity/SentryUnityOptions.cs b/src/Sentry.Unity/SentryUnityOptions.cs index c7cd6cb13..f2377e755 100644 --- a/src/Sentry.Unity/SentryUnityOptions.cs +++ b/src/Sentry.Unity/SentryUnityOptions.cs @@ -81,6 +81,11 @@ public sealed class SentryUnityOptions : SentryOptions /// public int ScreenshotCompression { get; set; } = 75; + /// + /// Whether the SDK should automatically add LogType.Debug and LogType.Warning messages as breadcrumbs + /// + public bool addLogsAsBreadcrumbs { get; set; } = true; + /// /// Whether the SDK should add native support for iOS /// diff --git a/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs b/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs index e0e76b459..831f13332 100644 --- a/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs +++ b/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs @@ -124,6 +124,40 @@ public void CaptureLogFormat_UnityNotErrorLogTypes_NotCaptured(LogType unityLogT Assert.AreEqual(breadcrumbLevel, breadcrumb.Level); } + [Test] + [TestCase(LogType.Log)] + [TestCase(LogType.Warning)] + public void CaptureLogFormat_AddLogsAsBreadcrumbsEnabled_AddedAsBreadcrumb(LogType logType) + { + _fixture.SentryOptions.addLogsAsBreadcrumbs = true; + var sut = _fixture.GetSut(); + var message = NUnit.Framework.TestContext.CurrentContext.Test.Name; + + sut.CaptureLogFormat(logType, null, "{0}", message); + + var scope = new Scope(_fixture.SentryOptions); + _fixture.Hub.ConfigureScopeCalls.Single().Invoke(scope); + var breadcrumb = scope.Breadcrumbs.Single(); + + Assert.AreEqual(message, breadcrumb.Message); + } + + [Test] + [TestCase(LogType.Log)] + [TestCase(LogType.Warning)] + public void CaptureLogFormat_AddLogsAsBreadcrumbsDisabled_NotAddedAsBreadcrumb(LogType logType) + { + _fixture.SentryOptions.addLogsAsBreadcrumbs = false; + var sut = _fixture.GetSut(); + var message = NUnit.Framework.TestContext.CurrentContext.Test.Name; + + sut.CaptureLogFormat(logType, null, "{0}", message); + + var scope = new Scope(_fixture.SentryOptions); + + Assert.IsFalse(_fixture.Hub.ConfigureScopeCalls.Count > 0); + } + [Test] public void CaptureException_ExceptionCapturedAndMechanismSet() { From 548b749e8270cf87da3c48a591cc7be674fcb7e9 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Fri, 21 Oct 2022 14:31:16 +0200 Subject: [PATCH 2/6] minimum breadcrumb level --- .../ConfigurationWindow/EnrichmentTab.cs | 9 ++--- .../UnityLogHandlerIntegration.cs | 32 ++++++++++++++--- .../ScriptableSentryUnityOptions.cs | 3 +- src/Sentry.Unity/SentryUnityOptions.cs | 5 +-- .../UnityLogHandlerIntegrationTests.cs | 35 +++++++++++++++---- 5 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs b/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs index 40efa9b4a..8880a5af2 100644 --- a/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs +++ b/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs @@ -63,12 +63,9 @@ internal static void Display(ScriptableSentryUnityOptions options) EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, 1), Color.gray); EditorGUILayout.Space(); - options.AddLogsAsBreadcrumbs = EditorGUILayout.Toggle( - new GUIContent("Add Logs as Breadcrumbs", "Whether to capture 'LogType.Log' and " + - "'LogType.Log' as breadcrumbs automatically.\n" + - "'LogType.Error' will get captured in any case and added as " + - "breadcrumb to subsequent events."), - options.AddLogsAsBreadcrumbs); + options.MinimumBreadcrumbLevel = (LogType)EditorGUILayout.EnumPopup( + new GUIContent("Minimum Log Breadcrumb Level", "Minimum log type the SDK adds as breadcrumb."), + options.MinimumBreadcrumbLevel); options.MaxBreadcrumbs = EditorGUILayout.IntField( new GUIContent("Max Breadcrumbs", "Maximum number of breadcrumbs that get captured." + diff --git a/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs b/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs index b2f1ad620..0a6e008e0 100644 --- a/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs +++ b/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs @@ -127,13 +127,11 @@ internal void CaptureLogFormat(LogType logType, UnityEngine.Object? context, str if (logType is LogType.Error or LogType.Assert) { _hub.CaptureMessage(logMessage, ToEventTagType(logType)); - // So the next event includes this as a breadcrumb - _hub.AddBreadcrumb(message: logMessage, category: "unity.logger", level: ToBreadcrumbLevel(logType)); - return; } - if (_sentryOptions?.addLogsAsBreadcrumbs is true) + if(_sentryOptions != null && PassesMinimumBreadcrumbLevel(_sentryOptions.MinimumBreadcrumbLevel, logType)) { + // So the next event includes this as a breadcrumb _hub.AddBreadcrumb(message: logMessage, category: "unity.logger", level: ToBreadcrumbLevel(logType)); } } @@ -154,6 +152,32 @@ private void OnQuitting() _hub?.FlushAsync(_sentryOptions?.ShutdownTimeout ?? TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); } + + internal static bool PassesMinimumBreadcrumbLevel(LogType minimumLogType, LogType logType) + { + switch (minimumLogType) + { + case LogType.Log when logType is LogType.Log or LogType.Warning or LogType.Error or LogType.Assert or LogType.Exception: + return true; + case LogType.Warning when logType is LogType.Warning or LogType.Error or LogType.Assert or LogType.Exception: + return true; + case LogType.Error: + case LogType.Assert: + { + if (logType is LogType.Error or LogType.Assert or LogType.Exception) + { + return true; + } + + break; + } + case LogType.Exception when logType is LogType.Exception: + return true; + } + + return false; + } + private static SentryLevel ToEventTagType(LogType logType) => logType switch { diff --git a/src/Sentry.Unity/ScriptableSentryUnityOptions.cs b/src/Sentry.Unity/ScriptableSentryUnityOptions.cs index de4506f8d..bbb8b9d56 100644 --- a/src/Sentry.Unity/ScriptableSentryUnityOptions.cs +++ b/src/Sentry.Unity/ScriptableSentryUnityOptions.cs @@ -43,7 +43,7 @@ public static string GetConfigPath(string? notDefaultConfigName = null) [field: SerializeField] public ScreenshotQuality ScreenshotQuality { get; set; } = ScreenshotQuality.High; [field: SerializeField] public int ScreenshotCompression { get; set; } = 75; - [field: SerializeField] public bool AddLogsAsBreadcrumbs { get; set; } = true; + [field: SerializeField] public LogType MinimumBreadcrumbLevel { get; set; } = LogType.Log; [field: SerializeField] public int MaxBreadcrumbs { get; set; } = Constants.DefaultMaxBreadcrumbs; [field: SerializeField] public ReportAssembliesMode ReportAssembliesMode { get; set; } = ReportAssembliesMode.Version; @@ -108,6 +108,7 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn AttachScreenshot = AttachScreenshot, ScreenshotQuality = ScreenshotQuality, ScreenshotCompression = ScreenshotCompression, + MinimumBreadcrumbLevel = MinimumBreadcrumbLevel, MaxBreadcrumbs = MaxBreadcrumbs, ReportAssembliesMode = ReportAssembliesMode, SendDefaultPii = SendDefaultPii, diff --git a/src/Sentry.Unity/SentryUnityOptions.cs b/src/Sentry.Unity/SentryUnityOptions.cs index f2377e755..ba724f3b5 100644 --- a/src/Sentry.Unity/SentryUnityOptions.cs +++ b/src/Sentry.Unity/SentryUnityOptions.cs @@ -3,6 +3,7 @@ using System.Text.RegularExpressions; using Sentry.Unity.Integrations; using Sentry.Extensibility; +using UnityEngine; using CompressionLevel = System.IO.Compression.CompressionLevel; namespace Sentry.Unity @@ -82,9 +83,9 @@ public sealed class SentryUnityOptions : SentryOptions public int ScreenshotCompression { get; set; } = 75; /// - /// Whether the SDK should automatically add LogType.Debug and LogType.Warning messages as breadcrumbs + /// The minimum level of logs the SDK should add as a breadcrumb /// - public bool addLogsAsBreadcrumbs { get; set; } = true; + public LogType MinimumBreadcrumbLevel { get; set; } = LogType.Log; /// /// Whether the SDK should add native support for iOS diff --git a/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs b/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs index 831f13332..e9ce6a3b7 100644 --- a/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs +++ b/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs @@ -124,12 +124,35 @@ public void CaptureLogFormat_UnityNotErrorLogTypes_NotCaptured(LogType unityLogT Assert.AreEqual(breadcrumbLevel, breadcrumb.Level); } + [Test] + [TestCase(LogType.Log, true, true, true, true, true)] + [TestCase(LogType.Warning, false, true, true, true, true)] + [TestCase(LogType.Error, false, false, true, true, true)] + [TestCase(LogType.Assert, false, false, true, true, true)] + [TestCase(LogType.Exception, false, false, false, false, true)] + public void PassesMinimumBreadcrumbLevel_ForEveryMinimumLevel_PassesCorrectly( + LogType minimumBreadcrumbLevel, + bool logExpected, + bool warningExpected, + bool errorExpected, + bool assertExpected, + bool exceptionExpected) + { + Assert.AreEqual(logExpected, UnityLogHandlerIntegration.PassesMinimumBreadcrumbLevel(minimumBreadcrumbLevel, LogType.Log)); + Assert.AreEqual(warningExpected, UnityLogHandlerIntegration.PassesMinimumBreadcrumbLevel(minimumBreadcrumbLevel, LogType.Warning)); + Assert.AreEqual(errorExpected, UnityLogHandlerIntegration.PassesMinimumBreadcrumbLevel(minimumBreadcrumbLevel, LogType.Error)); + Assert.AreEqual(assertExpected, UnityLogHandlerIntegration.PassesMinimumBreadcrumbLevel(minimumBreadcrumbLevel, LogType.Assert)); + Assert.AreEqual(exceptionExpected, UnityLogHandlerIntegration.PassesMinimumBreadcrumbLevel(minimumBreadcrumbLevel, LogType.Exception)); + } + [Test] [TestCase(LogType.Log)] [TestCase(LogType.Warning)] - public void CaptureLogFormat_AddLogsAsBreadcrumbsEnabled_AddedAsBreadcrumb(LogType logType) + [TestCase(LogType.Error)] + [TestCase(LogType.Assert)] + public void CaptureLogFormat_MinimumBreadcrumbLevelLog_AllLogsAsBreadcrumbAdded(LogType logType) { - _fixture.SentryOptions.addLogsAsBreadcrumbs = true; + _fixture.SentryOptions.MinimumBreadcrumbLevel = LogType.Log; var sut = _fixture.GetSut(); var message = NUnit.Framework.TestContext.CurrentContext.Test.Name; @@ -145,16 +168,16 @@ public void CaptureLogFormat_AddLogsAsBreadcrumbsEnabled_AddedAsBreadcrumb(LogTy [Test] [TestCase(LogType.Log)] [TestCase(LogType.Warning)] - public void CaptureLogFormat_AddLogsAsBreadcrumbsDisabled_NotAddedAsBreadcrumb(LogType logType) + [TestCase(LogType.Error)] + [TestCase(LogType.Assert)] + public void CaptureLogFormat_MinimumBreadcrumbLevelException_NoLogAddedAsBreadcrumb(LogType logType) { - _fixture.SentryOptions.addLogsAsBreadcrumbs = false; + _fixture.SentryOptions.MinimumBreadcrumbLevel = LogType.Exception; var sut = _fixture.GetSut(); var message = NUnit.Framework.TestContext.CurrentContext.Test.Name; sut.CaptureLogFormat(logType, null, "{0}", message); - var scope = new Scope(_fixture.SentryOptions); - Assert.IsFalse(_fixture.Hub.ConfigureScopeCalls.Count > 0); } From b8ac6f3259eb7c9c22c1668a0fa296e9ae22e373 Mon Sep 17 00:00:00 2001 From: Sentry Github Bot Date: Fri, 21 Oct 2022 12:33:28 +0000 Subject: [PATCH 3/6] Format code --- modules/sentry-native | 2 +- .../Integrations/UnityLogHandlerIntegration.cs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/sentry-native b/modules/sentry-native index 1a4c7c15f..28be51f5e 160000 --- a/modules/sentry-native +++ b/modules/sentry-native @@ -1 +1 @@ -Subproject commit 1a4c7c15f086644d1838c44209c8213a8cc3b497 +Subproject commit 28be51f5e3acb01327b1164206d3145464577670 diff --git a/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs b/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs index 0a6e008e0..0bd41ef95 100644 --- a/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs +++ b/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs @@ -129,7 +129,7 @@ internal void CaptureLogFormat(LogType logType, UnityEngine.Object? context, str _hub.CaptureMessage(logMessage, ToEventTagType(logType)); } - if(_sentryOptions != null && PassesMinimumBreadcrumbLevel(_sentryOptions.MinimumBreadcrumbLevel, logType)) + if (_sentryOptions != null && PassesMinimumBreadcrumbLevel(_sentryOptions.MinimumBreadcrumbLevel, logType)) { // So the next event includes this as a breadcrumb _hub.AddBreadcrumb(message: logMessage, category: "unity.logger", level: ToBreadcrumbLevel(logType)); @@ -163,14 +163,14 @@ internal static bool PassesMinimumBreadcrumbLevel(LogType minimumLogType, LogTyp return true; case LogType.Error: case LogType.Assert: - { - if (logType is LogType.Error or LogType.Assert or LogType.Exception) { - return true; - } + if (logType is LogType.Error or LogType.Assert or LogType.Exception) + { + return true; + } - break; - } + break; + } case LogType.Exception when logType is LogType.Exception: return true; } From 3398d2973260bb663d68de8524f8c4d4bbf9a318 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Fri, 21 Oct 2022 14:37:17 +0200 Subject: [PATCH 4/6] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dca83bf6b..ec259b630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ ### Features +- Added minimum breadcrumb level to the options ([#1030](https://github.com/getsentry/sentry-unity/pull/1030)) - The Cocoa SDK is now bundled as `.xcframework` ([#1002](https://github.com/getsentry/sentry-unity/pull/1002)) - Automated Performance Instrumentation for Runtime Initialization ([#991](https://github.com/getsentry/sentry-unity/pull/991)) - Automated Performance Instrumentation for Scene Loading ([#768](https://github.com/getsentry/sentry-unity/pull/768)) From a45b834143013fd7d36cda217efb464135ecb99c Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Mon, 24 Oct 2022 16:15:37 +0200 Subject: [PATCH 5/6] changed to individual checkboxes for capturing logs instead --- .../Resources/Sentry/SentryOptions.asset | 6 +- .../ConfigurationWindow/EnrichmentTab.cs | 25 +++++++- .../UnityLogHandlerIntegration.cs | 35 ++---------- .../ScriptableSentryUnityOptions.cs | 14 ++++- src/Sentry.Unity/SentryUnityOptions.cs | 13 ++++- .../UnityLogHandlerIntegrationTests.cs | 57 +++++++++++-------- 6 files changed, 88 insertions(+), 62 deletions(-) diff --git a/samples/unity-of-bugs/Assets/Resources/Sentry/SentryOptions.asset b/samples/unity-of-bugs/Assets/Resources/Sentry/SentryOptions.asset index 2ea744359..8807d47fe 100644 --- a/samples/unity-of-bugs/Assets/Resources/Sentry/SentryOptions.asset +++ b/samples/unity-of-bugs/Assets/Resources/Sentry/SentryOptions.asset @@ -25,7 +25,11 @@ MonoBehaviour: k__BackingField: 1 k__BackingField: 2 k__BackingField: 75 - k__BackingField: 1 + k__BackingField: 1 + k__BackingField: 1 + k__BackingField: 1 + k__BackingField: 1 + k__BackingField: 1 k__BackingField: 100 k__BackingField: 1 k__BackingField: 0 diff --git a/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs b/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs index 8880a5af2..8c544644d 100644 --- a/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs +++ b/src/Sentry.Unity.Editor/ConfigurationWindow/EnrichmentTab.cs @@ -1,6 +1,7 @@ using System; using UnityEditor; using UnityEngine; +using UnityEngine.Assertions; namespace Sentry.Unity.Editor.ConfigurationWindow { @@ -63,9 +64,27 @@ internal static void Display(ScriptableSentryUnityOptions options) EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, 1), Color.gray); EditorGUILayout.Space(); - options.MinimumBreadcrumbLevel = (LogType)EditorGUILayout.EnumPopup( - new GUIContent("Minimum Log Breadcrumb Level", "Minimum log type the SDK adds as breadcrumb."), - options.MinimumBreadcrumbLevel); + GUILayout.Label("Breadcrumbs automatically added for LogType:", EditorStyles.boldLabel); + + options.BreadcrumbsForLogs = EditorGUILayout.Toggle( + new GUIContent("Log", "Whether the SDK automatically adds breadcrumbs 'Debug.Log'."), + options.BreadcrumbsForLogs); + options.BreadcrumbsForWarnings = EditorGUILayout.Toggle( + new GUIContent("Warning", "Whether the SDK automatically adds breadcrumbs for 'Debug.LogWarning'."), + options.BreadcrumbsForWarnings); + options.BreadcrumbsForAsserts = EditorGUILayout.Toggle( + new GUIContent("Assert", "Whether the SDK automatically adds breadcrumbs for 'Debug.Assert'."), + options.BreadcrumbsForAsserts); + options.BreadcrumbsForErrors = EditorGUILayout.Toggle( + new GUIContent("Error", "Whether the SDK automatically adds breadcrumbs for 'Debug.LogError'."), + options.BreadcrumbsForLogs); + options.BreadcrumbsForExceptions = EditorGUILayout.Toggle( + new GUIContent("Exception", "Whether the SDK automatically adds breadcrumbs for exceptions and 'Debug.LogException'."), + options.BreadcrumbsForExceptions); + + EditorGUILayout.Space(); + EditorGUI.DrawRect(EditorGUILayout.GetControlRect(false, 1), Color.gray); + EditorGUILayout.Space(); options.MaxBreadcrumbs = EditorGUILayout.IntField( new GUIContent("Max Breadcrumbs", "Maximum number of breadcrumbs that get captured." + diff --git a/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs b/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs index 0bd41ef95..5384827ce 100644 --- a/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs +++ b/src/Sentry.Unity/Integrations/UnityLogHandlerIntegration.cs @@ -64,8 +64,11 @@ internal void CaptureException(Exception exception, UnityEngine.Object? context) exception.Data[Mechanism.MechanismKey] = "Unity.LogException"; _ = _hub.CaptureException(exception); - // So the next event includes this error as a breadcrumb - _hub.AddBreadcrumb(message: $"{exception.GetType()}: {exception.Message}", category: "unity.logger", level: BreadcrumbLevel.Error); + if (_sentryOptions?.AddBreadcrumbsForLogType[LogType.Exception] is true) + { + // So the next event includes this error as a breadcrumb + _hub.AddBreadcrumb(message: $"{exception.GetType()}: {exception.Message}", category: "unity.logger", level: BreadcrumbLevel.Error); + } } public void LogFormat(LogType logType, UnityEngine.Object? context, string format, params object[] args) @@ -129,7 +132,7 @@ internal void CaptureLogFormat(LogType logType, UnityEngine.Object? context, str _hub.CaptureMessage(logMessage, ToEventTagType(logType)); } - if (_sentryOptions != null && PassesMinimumBreadcrumbLevel(_sentryOptions.MinimumBreadcrumbLevel, logType)) + if (_sentryOptions?.AddBreadcrumbsForLogType[logType] is true) { // So the next event includes this as a breadcrumb _hub.AddBreadcrumb(message: logMessage, category: "unity.logger", level: ToBreadcrumbLevel(logType)); @@ -152,32 +155,6 @@ private void OnQuitting() _hub?.FlushAsync(_sentryOptions?.ShutdownTimeout ?? TimeSpan.FromSeconds(1)).GetAwaiter().GetResult(); } - - internal static bool PassesMinimumBreadcrumbLevel(LogType minimumLogType, LogType logType) - { - switch (minimumLogType) - { - case LogType.Log when logType is LogType.Log or LogType.Warning or LogType.Error or LogType.Assert or LogType.Exception: - return true; - case LogType.Warning when logType is LogType.Warning or LogType.Error or LogType.Assert or LogType.Exception: - return true; - case LogType.Error: - case LogType.Assert: - { - if (logType is LogType.Error or LogType.Assert or LogType.Exception) - { - return true; - } - - break; - } - case LogType.Exception when logType is LogType.Exception: - return true; - } - - return false; - } - private static SentryLevel ToEventTagType(LogType logType) => logType switch { diff --git a/src/Sentry.Unity/ScriptableSentryUnityOptions.cs b/src/Sentry.Unity/ScriptableSentryUnityOptions.cs index bbb8b9d56..061fb121c 100644 --- a/src/Sentry.Unity/ScriptableSentryUnityOptions.cs +++ b/src/Sentry.Unity/ScriptableSentryUnityOptions.cs @@ -43,7 +43,12 @@ public static string GetConfigPath(string? notDefaultConfigName = null) [field: SerializeField] public ScreenshotQuality ScreenshotQuality { get; set; } = ScreenshotQuality.High; [field: SerializeField] public int ScreenshotCompression { get; set; } = 75; - [field: SerializeField] public LogType MinimumBreadcrumbLevel { get; set; } = LogType.Log; + [field: SerializeField] public bool BreadcrumbsForLogs { get; set; } = true; + [field: SerializeField] public bool BreadcrumbsForWarnings { get; set; } = true; + [field: SerializeField] public bool BreadcrumbsForAsserts { get; set; } = true; + [field: SerializeField] public bool BreadcrumbsForErrors { get; set; } = true; + [field: SerializeField] public bool BreadcrumbsForExceptions { get; set; } = true; + [field: SerializeField] public int MaxBreadcrumbs { get; set; } = Constants.DefaultMaxBreadcrumbs; [field: SerializeField] public ReportAssembliesMode ReportAssembliesMode { get; set; } = ReportAssembliesMode.Version; @@ -108,7 +113,6 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn AttachScreenshot = AttachScreenshot, ScreenshotQuality = ScreenshotQuality, ScreenshotCompression = ScreenshotCompression, - MinimumBreadcrumbLevel = MinimumBreadcrumbLevel, MaxBreadcrumbs = MaxBreadcrumbs, ReportAssembliesMode = ReportAssembliesMode, SendDefaultPii = SendDefaultPii, @@ -140,6 +144,12 @@ internal SentryUnityOptions ToSentryUnityOptions(bool isBuilding, ISentryUnityIn options.Environment = EnvironmentOverride; } + options.AddBreadcrumbsForLogType[LogType.Log] = BreadcrumbsForLogs; + options.AddBreadcrumbsForLogType[LogType.Warning] = BreadcrumbsForWarnings; + options.AddBreadcrumbsForLogType[LogType.Assert] = BreadcrumbsForAsserts; + options.AddBreadcrumbsForLogType[LogType.Error] = BreadcrumbsForErrors; + options.AddBreadcrumbsForLogType[LogType.Exception] = BreadcrumbsForExceptions; + options.SetupLogging(); if (IsKnownPlatform(application)) diff --git a/src/Sentry.Unity/SentryUnityOptions.cs b/src/Sentry.Unity/SentryUnityOptions.cs index ba724f3b5..6c18edb38 100644 --- a/src/Sentry.Unity/SentryUnityOptions.cs +++ b/src/Sentry.Unity/SentryUnityOptions.cs @@ -83,9 +83,9 @@ public sealed class SentryUnityOptions : SentryOptions public int ScreenshotCompression { get; set; } = 75; /// - /// The minimum level of logs the SDK should add as a breadcrumb + /// Whether the SDK should automatically add breadcrumbs per LogType /// - public LogType MinimumBreadcrumbLevel { get; set; } = LogType.Log; + public Dictionary AddBreadcrumbsForLogType { get; set; } /// /// Whether the SDK should add native support for iOS @@ -204,6 +204,15 @@ internal SentryUnityOptions(SentryMonoBehaviour behaviour, IApplication applicat Environment = application.IsEditor && !isBuilding ? "editor" : "production"; + + AddBreadcrumbsForLogType = new Dictionary + { + { LogType.Log, true}, + { LogType.Warning, true}, + { LogType.Assert, true}, + { LogType.Error, true}, + { LogType.Exception, true}, + }; } public override string ToString() diff --git a/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs b/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs index e9ce6a3b7..8f1dce453 100644 --- a/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs +++ b/test/Sentry.Unity.Tests/UnityLogHandlerIntegrationTests.cs @@ -124,35 +124,14 @@ public void CaptureLogFormat_UnityNotErrorLogTypes_NotCaptured(LogType unityLogT Assert.AreEqual(breadcrumbLevel, breadcrumb.Level); } - [Test] - [TestCase(LogType.Log, true, true, true, true, true)] - [TestCase(LogType.Warning, false, true, true, true, true)] - [TestCase(LogType.Error, false, false, true, true, true)] - [TestCase(LogType.Assert, false, false, true, true, true)] - [TestCase(LogType.Exception, false, false, false, false, true)] - public void PassesMinimumBreadcrumbLevel_ForEveryMinimumLevel_PassesCorrectly( - LogType minimumBreadcrumbLevel, - bool logExpected, - bool warningExpected, - bool errorExpected, - bool assertExpected, - bool exceptionExpected) - { - Assert.AreEqual(logExpected, UnityLogHandlerIntegration.PassesMinimumBreadcrumbLevel(minimumBreadcrumbLevel, LogType.Log)); - Assert.AreEqual(warningExpected, UnityLogHandlerIntegration.PassesMinimumBreadcrumbLevel(minimumBreadcrumbLevel, LogType.Warning)); - Assert.AreEqual(errorExpected, UnityLogHandlerIntegration.PassesMinimumBreadcrumbLevel(minimumBreadcrumbLevel, LogType.Error)); - Assert.AreEqual(assertExpected, UnityLogHandlerIntegration.PassesMinimumBreadcrumbLevel(minimumBreadcrumbLevel, LogType.Assert)); - Assert.AreEqual(exceptionExpected, UnityLogHandlerIntegration.PassesMinimumBreadcrumbLevel(minimumBreadcrumbLevel, LogType.Exception)); - } - [Test] [TestCase(LogType.Log)] [TestCase(LogType.Warning)] [TestCase(LogType.Error)] [TestCase(LogType.Assert)] - public void CaptureLogFormat_MinimumBreadcrumbLevelLog_AllLogsAsBreadcrumbAdded(LogType logType) + public void CaptureLogFormat_AddAsBreadcrumbEnabled_AddedAsBreadcrumb(LogType logType) { - _fixture.SentryOptions.MinimumBreadcrumbLevel = LogType.Log; + _fixture.SentryOptions.AddBreadcrumbsForLogType[logType] = true; var sut = _fixture.GetSut(); var message = NUnit.Framework.TestContext.CurrentContext.Test.Name; @@ -165,14 +144,30 @@ public void CaptureLogFormat_MinimumBreadcrumbLevelLog_AllLogsAsBreadcrumbAdded( Assert.AreEqual(message, breadcrumb.Message); } + [Test] + public void CaptureException_AddAsBreadcrumbEnabled_AddedAsBreadcrumb() + { + _fixture.SentryOptions.AddBreadcrumbsForLogType[LogType.Exception] = true; + var sut = _fixture.GetSut(); + var message = NUnit.Framework.TestContext.CurrentContext.Test.Name; + + sut.CaptureException(new Exception(message), null); + + var scope = new Scope(_fixture.SentryOptions); + _fixture.Hub.ConfigureScopeCalls.Single().Invoke(scope); + var breadcrumb = scope.Breadcrumbs.Single(); + + StringAssert.Contains(message, breadcrumb.Message); + } + [Test] [TestCase(LogType.Log)] [TestCase(LogType.Warning)] [TestCase(LogType.Error)] [TestCase(LogType.Assert)] - public void CaptureLogFormat_MinimumBreadcrumbLevelException_NoLogAddedAsBreadcrumb(LogType logType) + public void CaptureLogFormat_AddAsBreadcrumbDisabled_NotAddedAsBreadcrumb(LogType logType) { - _fixture.SentryOptions.MinimumBreadcrumbLevel = LogType.Exception; + _fixture.SentryOptions.AddBreadcrumbsForLogType[logType] = false; var sut = _fixture.GetSut(); var message = NUnit.Framework.TestContext.CurrentContext.Test.Name; @@ -181,6 +176,18 @@ public void CaptureLogFormat_MinimumBreadcrumbLevelException_NoLogAddedAsBreadcr Assert.IsFalse(_fixture.Hub.ConfigureScopeCalls.Count > 0); } + [Test] + public void CaptureException_AddAsBreadcrumbEnabled_NotAddedAsBreadcrumb() + { + _fixture.SentryOptions.AddBreadcrumbsForLogType[LogType.Exception] = false; + var sut = _fixture.GetSut(); + var message = NUnit.Framework.TestContext.CurrentContext.Test.Name; + + sut.CaptureException(new Exception("Test Exception"), null); + + Assert.IsFalse(_fixture.Hub.ConfigureScopeCalls.Count > 0); + } + [Test] public void CaptureException_ExceptionCapturedAndMechanismSet() { From cd1dee8896ef8937f2e2d4156e96dac35f236bb0 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Mon, 24 Oct 2022 16:19:50 +0200 Subject: [PATCH 6/6] Updated CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cbaad34f..1561d0cb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ ### Features -- Added minimum breadcrumb level to the options ([#1030](https://github.com/getsentry/sentry-unity/pull/1030)) +- Added flags per LogType for automatically adding breadcrumbs ([#1030](https://github.com/getsentry/sentry-unity/pull/1030)) - The Cocoa SDK is now bundled as `.xcframework` ([#1002](https://github.com/getsentry/sentry-unity/pull/1002)) - Automated Performance Instrumentation for Runtime Initialization ([#991](https://github.com/getsentry/sentry-unity/pull/991)) - Automated Performance Instrumentation for Scene Loading ([#768](https://github.com/getsentry/sentry-unity/pull/768))