diff --git a/CHANGELOG.md b/CHANGELOG.md index 803a14f9d..af809736d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Sentry UnityLogger aligned to Unity Debug API ([#163](https://github.com/getsentry/sentry-unity/pull/163)) + ### Fixes - SDK version format correction (#120) diff --git a/src/Sentry.Unity/SentryInitialization.cs b/src/Sentry.Unity/SentryInitialization.cs index bbee53b46..dc9ba7eb9 100644 --- a/src/Sentry.Unity/SentryInitialization.cs +++ b/src/Sentry.Unity/SentryInitialization.cs @@ -13,7 +13,7 @@ public static void Init() { if (!File.Exists(SentryUnityOptions.GetConfigPath())) { - Debug.LogWarning("Couldn't find the configuration file SentryOptions.json. Did you already configure Sentry?\nYou can do that through the editor: Tools -> Sentry"); + new UnityLogger(SentryLevel.Warning).Log(SentryLevel.Warning, "Couldn't find the configuration file SentryOptions.json. Did you already configure Sentry?\nYou can do that through the editor: Tools -> Sentry"); return; } diff --git a/src/Sentry.Unity/UnityLogger.cs b/src/Sentry.Unity/UnityLogger.cs index f60c8b153..52f5fce24 100644 --- a/src/Sentry.Unity/UnityLogger.cs +++ b/src/Sentry.Unity/UnityLogger.cs @@ -1,24 +1,61 @@ -using Sentry; -using Sentry.Extensibility; +using Sentry.Extensibility; using System; using UnityEngine; using static System.String; -internal class UnityLogger : IDiagnosticLogger +namespace Sentry.Unity { - private readonly SentryLevel _minimalLevel; - public bool IsEnabled(SentryLevel level) => level >= _minimalLevel; - public UnityLogger(SentryLevel minimalLevel) => _minimalLevel = minimalLevel; + internal interface IUnityLoggerInterceptor + { + void Intercept(string logMessage); + } - public void Log(SentryLevel logLevel, string? message, Exception? exception = null, params object?[] args) + internal class UnityLogger : IDiagnosticLogger { - if (IsEnabled(logLevel)) + private readonly SentryLevel _minimalLevel; + private readonly IUnityLoggerInterceptor? _interceptor; + + public bool IsEnabled(SentryLevel level) => level >= _minimalLevel; + + public UnityLogger(SentryLevel minimalLevel, IUnityLoggerInterceptor? interceptor = null) { - Debug.Log($@"Sentry: {logLevel} + _minimalLevel = minimalLevel; + _interceptor = interceptor; + } + + public void Log(SentryLevel logLevel, string? message, Exception? exception = null, params object?[] args) + { + if (!IsEnabled(logLevel)) + { + return; + } + + switch (logLevel) + { + case SentryLevel.Debug or SentryLevel.Info: + Debug.Log(GetLog()); + break; + case SentryLevel.Warning: + Debug.LogWarning(GetLog()); + break; + case SentryLevel.Error or SentryLevel.Fatal: + Debug.LogError(GetLog()); + break; + default: + Debug.Log(GetLog()); + break; + } + + string GetLog() + { + var log = $@"Sentry: {logLevel} {Format(message, args)} -{exception}"); +{exception}"; + _interceptor?.Intercept(log); + return log; + } } - } - public override string ToString() => nameof(UnityLogger); + public override string ToString() => nameof(UnityLogger); + } } diff --git a/test/Sentry.Unity.Tests/UnityLoggerTests.cs b/test/Sentry.Unity.Tests/UnityLoggerTests.cs new file mode 100644 index 000000000..0737d1146 --- /dev/null +++ b/test/Sentry.Unity.Tests/UnityLoggerTests.cs @@ -0,0 +1,54 @@ +using NUnit.Framework; +using UnityEngine.TestTools; + +namespace Sentry.Unity.Tests +{ + public sealed class UnityLoggerTests + { + [Test] + public void Log_DebugLevels_Correspond([Values] SentryLevel sentryLevel) + { + LogAssert.ignoreFailingMessages = true; + + var interceptor = new TestUnityLoggerInterceptor(); + var logger = new UnityLogger(sentryLevel, interceptor); + + const string expectedLog = "Some log"; + logger.Log(sentryLevel, expectedLog); + + Assert.True(logger.IsEnabled(sentryLevel)); + Assert.True(interceptor.LogMessage.Contains("Sentry")); + Assert.True(interceptor.LogMessage.Contains(expectedLog)); + Assert.True(interceptor.LogMessage.Contains(sentryLevel.ToString())); + } + + [TestCaseSource(nameof(SentryLevels))] + public void Log_LowerLevelThanInitializationLevel_DisablesLogger(SentryLevel initializationLevel, SentryLevel lowerLevel) + { + var interceptor = new TestUnityLoggerInterceptor(); + var logger = new UnityLogger(initializationLevel, interceptor); + + const string expectedLog = "Some log"; + + logger.Log(lowerLevel, expectedLog); + + Assert.False(logger.IsEnabled(lowerLevel)); + Assert.False(interceptor.LogMessage.Contains(expectedLog)); + } + + private static object[] SentryLevels = + { + new object[] { SentryLevel.Info, SentryLevel.Debug }, + new object[] { SentryLevel.Warning, SentryLevel.Info }, + new object[] { SentryLevel.Error, SentryLevel.Warning }, + new object[] { SentryLevel.Fatal, SentryLevel.Error } + }; + + private sealed class TestUnityLoggerInterceptor : IUnityLoggerInterceptor + { + public string LogMessage { get; private set; } = string.Empty; + + public void Intercept(string logMessage) => LogMessage = logMessage; + } + } +}