From fb78999eb9f465aaf551ed729152fd28a5570fab Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Mon, 29 Jul 2024 13:22:09 +0200 Subject: [PATCH 1/8] Log for Swift --- Sentry.xcodeproj/project.pbxproj | 36 ++++--- SentryTestUtils/ClearTestState.swift | 2 +- SentryTestUtils/SentryLogExtensions.swift | 1 + Sources/Sentry/SentryLevelHelper.m | 13 +-- Sources/Sentry/SentryLevelMapper.m | 44 +-------- Sources/Sentry/SentryLog.m | 99 ------------------- Sources/Sentry/SentryLogC.m | 29 ++++++ Sources/Sentry/SentryLogOutput.m | 14 --- Sources/Sentry/include/SentryLevelHelper.h | 8 +- Sources/Sentry/include/SentryLevelMapper.h | 7 -- Sources/Sentry/include/SentryLog.h | 20 ---- Sources/Sentry/include/SentryLogC.h | 4 + Sources/Sentry/include/SentryLogOutput.h | 11 --- Sources/Sentry/include/SentryPrivate.h | 1 + Sources/Swift/Helper/Log/SentryLevel.swift | 29 ++++++ .../RRWeb/SentryRRWebBreadcrumbEvent.swift | 2 +- .../SentrySRDefaultBreadcrumbConverter.swift | 3 +- Sources/Swift/Tools/SentryLog.swift | 48 +++++++++ Sources/Swift/Tools/SentryLogOutput.swift | 8 ++ .../Helper/SentryFileManagerTests.swift | 10 +- Tests/SentryTests/Helper/SentryLog+TestInit.h | 24 ----- Tests/SentryTests/Helper/SentryLog.swift | 24 +++++ Tests/SentryTests/Helper/SentryLogTests.swift | 42 ++++---- ...ntryAppStartTrackingIntegrationTests.swift | 2 +- .../SentryPerformanceTrackerTests.swift | 2 +- .../SentryBaseIntegrationTests.swift | 8 +- .../SentrySpotlightTransportTests.swift | 4 +- Tests/SentryTests/SentryLevelTests.swift | 22 +++++ .../SentryTests/SentryTests-Bridging-Header.h | 2 - Tests/SentryTests/SentryTests.m | 20 ---- Tests/SentryTests/TestLogOutput.swift | 1 + .../TestConncurrentModifications.swift | 2 +- 32 files changed, 233 insertions(+), 309 deletions(-) delete mode 100644 Sources/Sentry/SentryLog.m create mode 100644 Sources/Sentry/SentryLogC.m delete mode 100644 Sources/Sentry/SentryLogOutput.m create mode 100644 Sources/Sentry/include/SentryLogC.h delete mode 100644 Sources/Sentry/include/SentryLogOutput.h create mode 100644 Sources/Swift/Tools/SentryLog.swift create mode 100644 Sources/Swift/Tools/SentryLogOutput.swift delete mode 100644 Tests/SentryTests/Helper/SentryLog+TestInit.h create mode 100644 Tests/SentryTests/Helper/SentryLog.swift create mode 100644 Tests/SentryTests/SentryLevelTests.swift diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 61b33b538ba..bd0cece9cdf 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -186,7 +186,7 @@ 63AA75EF1EB8B3C400D153DE /* SentryClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 63AA75ED1EB8B3C400D153DE /* SentryClient.m */; }; 63AA766A1EB8CB2F00D153DE /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63AA759B1EB8AEF500D153DE /* Sentry.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 63AA76701EB8CB4B00D153DE /* SentryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63AA75951EB8AEDB00D153DE /* SentryTests.m */; }; - 63AA767A1EB8D20500D153DE /* SentryLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 63AA76781EB8D20500D153DE /* SentryLog.m */; }; + 63AA767A1EB8D20500D153DE /* SentryLogC.m in Sources */ = {isa = PBXBuildFile; fileRef = 63AA76781EB8D20500D153DE /* SentryLogC.m */; }; 63AA76981EB9C1C200D153DE /* SentryClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 63AA76941EB9C1C200D153DE /* SentryClient.h */; settings = {ATTRIBUTES = (Public, ); }; }; 63AA76991EB9C1C200D153DE /* SentryDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 63AA76951EB9C1C200D153DE /* SentryDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; 63AA769A1EB9C1C200D153DE /* SentryLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 63AA76961EB9C1C200D153DE /* SentryLog.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -482,8 +482,6 @@ 7BA61CCA247D128B00C130A8 /* SentryThreadInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BA61CC9247D128B00C130A8 /* SentryThreadInspector.m */; }; 7BA61CCC247D14E600C130A8 /* SentryThreadInspectorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA61CCB247D14E600C130A8 /* SentryThreadInspectorTests.swift */; }; 7BA61CCF247EB59500C130A8 /* SentryCrashUUIDConversionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA61CCE247EB59500C130A8 /* SentryCrashUUIDConversionTests.swift */; }; - 7BA61E8A25F21A3A0008CAA2 /* SentryLogOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BA61E8925F21A3A0008CAA2 /* SentryLogOutput.h */; }; - 7BA61E9225F21AF80008CAA2 /* SentryLogOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BA61E9125F21AF80008CAA2 /* SentryLogOutput.m */; }; 7BA61EA625F21E660008CAA2 /* SentryLogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA61EA525F21E660008CAA2 /* SentryLogTests.swift */; }; 7BA840A024A1EC6E00B718AA /* SentrySDKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA8409F24A1EC6E00B718AA /* SentrySDKTests.swift */; }; 7BAF3DB5243C743E008A5414 /* SentryClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF3DB4243C743E008A5414 /* SentryClientTests.swift */; }; @@ -869,6 +867,10 @@ D8ACE3CD2762187D00F5A213 /* SentryNSDataSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = D8ACE3CA2762187D00F5A213 /* SentryNSDataSwizzling.h */; }; D8ACE3CE2762187D00F5A213 /* SentryNSDataTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = D8ACE3CB2762187D00F5A213 /* SentryNSDataTracker.h */; }; D8ACE3CF2762187D00F5A213 /* SentryFileIOTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = D8ACE3CC2762187D00F5A213 /* SentryFileIOTrackingIntegration.h */; }; + D8AE48AE2C577EAB0092A2A6 /* SentryLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AE48AD2C577EAB0092A2A6 /* SentryLog.swift */; }; + D8AE48B02C5782EC0092A2A6 /* SentryLogOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AE48AF2C5782EC0092A2A6 /* SentryLogOutput.swift */; }; + D8AE48BF2C578D540092A2A6 /* SentryLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AE48BE2C578D540092A2A6 /* SentryLog.swift */; }; + D8AE48C12C57B1550092A2A6 /* SentryLevelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AE48C02C57B1550092A2A6 /* SentryLevelTests.swift */; }; D8AFC0012BD252B900118BE1 /* SentryOnDemandReplayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AFC0002BD252B900118BE1 /* SentryOnDemandReplayTests.swift */; }; D8AFC01A2BD7A20B00118BE1 /* SentryViewScreenshotProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AFC0192BD7A20B00118BE1 /* SentryViewScreenshotProvider.swift */; }; D8AFC03D2BDA79BF00118BE1 /* SentryReplayVideoMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8AFC03C2BDA79BF00118BE1 /* SentryReplayVideoMaker.swift */; }; @@ -1171,7 +1173,7 @@ 63AA75C71EB8B06100D153DE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../Resources/Info.plist; sourceTree = ""; }; 63AA75ED1EB8B3C400D153DE /* SentryClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SentryClient.m; sourceTree = ""; }; 63AA76651EB8CB2F00D153DE /* SentryTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SentryTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 63AA76781EB8D20500D153DE /* SentryLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SentryLog.m; sourceTree = ""; }; + 63AA76781EB8D20500D153DE /* SentryLogC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SentryLogC.m; sourceTree = ""; }; 63AA76931EB9C1C200D153DE /* Sentry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Sentry.h; path = Public/Sentry.h; sourceTree = ""; }; 63AA76941EB9C1C200D153DE /* SentryClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryClient.h; path = Public/SentryClient.h; sourceTree = ""; }; 63AA76951EB9C1C200D153DE /* SentryDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryDefines.h; path = Public/SentryDefines.h; sourceTree = ""; }; @@ -1489,10 +1491,7 @@ 7BA61CC9247D128B00C130A8 /* SentryThreadInspector.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryThreadInspector.m; sourceTree = ""; }; 7BA61CCB247D14E600C130A8 /* SentryThreadInspectorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryThreadInspectorTests.swift; sourceTree = ""; }; 7BA61CCE247EB59500C130A8 /* SentryCrashUUIDConversionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryCrashUUIDConversionTests.swift; sourceTree = ""; }; - 7BA61E8925F21A3A0008CAA2 /* SentryLogOutput.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryLogOutput.h; path = include/SentryLogOutput.h; sourceTree = ""; }; - 7BA61E9125F21AF80008CAA2 /* SentryLogOutput.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryLogOutput.m; sourceTree = ""; }; 7BA61EA525F21E660008CAA2 /* SentryLogTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogTests.swift; sourceTree = ""; }; - 7BA61EAB25F2206E0008CAA2 /* SentryLog+TestInit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryLog+TestInit.h"; sourceTree = ""; }; 7BA8409F24A1EC6E00B718AA /* SentrySDKTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySDKTests.swift; sourceTree = ""; }; 7BAF3DB4243C743E008A5414 /* SentryClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryClientTests.swift; sourceTree = ""; }; 7BAF3DB8243C9777008A5414 /* SentryTransport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryTransport.h; path = include/SentryTransport.h; sourceTree = ""; }; @@ -1929,6 +1928,11 @@ D8ACE3CA2762187D00F5A213 /* SentryNSDataSwizzling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryNSDataSwizzling.h; path = include/SentryNSDataSwizzling.h; sourceTree = ""; }; D8ACE3CB2762187D00F5A213 /* SentryNSDataTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryNSDataTracker.h; path = include/SentryNSDataTracker.h; sourceTree = ""; }; D8ACE3CC2762187D00F5A213 /* SentryFileIOTrackingIntegration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryFileIOTrackingIntegration.h; path = include/SentryFileIOTrackingIntegration.h; sourceTree = ""; }; + D8AE48AD2C577EAB0092A2A6 /* SentryLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLog.swift; sourceTree = ""; }; + D8AE48AF2C5782EC0092A2A6 /* SentryLogOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogOutput.swift; sourceTree = ""; }; + D8AE48B12C5786AA0092A2A6 /* SentryLogC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryLogC.h; path = include/SentryLogC.h; sourceTree = ""; }; + D8AE48BE2C578D540092A2A6 /* SentryLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLog.swift; sourceTree = ""; }; + D8AE48C02C57B1550092A2A6 /* SentryLevelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLevelTests.swift; sourceTree = ""; }; D8AFC0002BD252B900118BE1 /* SentryOnDemandReplayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryOnDemandReplayTests.swift; sourceTree = ""; }; D8AFC0192BD7A20B00118BE1 /* SentryViewScreenshotProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryViewScreenshotProvider.swift; sourceTree = ""; }; D8AFC03C2BDA79BF00118BE1 /* SentryReplayVideoMaker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryReplayVideoMaker.swift; sourceTree = ""; }; @@ -2399,14 +2403,13 @@ 7B42C48127E08F4B009B58C2 /* SentryDependencyContainer.m */, 7BC8522E24581096005A70F0 /* SentryFileContents.h */, 7BC85230245812EC005A70F0 /* SentryFileContents.m */, - 7BA61E8925F21A3A0008CAA2 /* SentryLogOutput.h */, - 7BA61E9125F21AF80008CAA2 /* SentryLogOutput.m */, 636085111ED47BE600E8599E /* SentryFileManager.h */, 636085121ED47BE600E8599E /* SentryFileManager.m */, 7BC3936725B1AB3E004F03D3 /* SentryLevelMapper.h */, 7BC3936D25B1AB72004F03D3 /* SentryLevelMapper.m */, 63AA76961EB9C1C200D153DE /* SentryLog.h */, - 63AA76781EB8D20500D153DE /* SentryLog.m */, + D8AE48B12C5786AA0092A2A6 /* SentryLogC.h */, + 63AA76781EB8D20500D153DE /* SentryLogC.m */, 63FE700920DA4C1000CDBAE8 /* SentryAsyncSafeLog.c */, 63FE702520DA4C1000CDBAE8 /* SentryAsyncSafeLog.h */, 7BE1E33124F7E3B6009D3AD0 /* SentryMigrateSessionInit.h */, @@ -2514,6 +2517,7 @@ 8E70B10025CB8695002B3155 /* SentrySpanIdTests.swift */, 8ED3D305264DFE700049393B /* SwiftDescriptorTests.swift */, 0A1B497228E597DD00D7BFA3 /* TestLogOutput.swift */, + D8AE48C02C57B1550092A2A6 /* SentryLevelTests.swift */, 7B6438AD26A710E6000D0F65 /* Categories */, D8BC28D32C00C6A60054DA4D /* Extensions */, 7BD7299B24654CD500EA3610 /* Helper */, @@ -3020,12 +3024,12 @@ 7BD7299B24654CD500EA3610 /* Helper */ = { isa = PBXGroup; children = ( + D8AE48BE2C578D540092A2A6 /* SentryLog.swift */, 849AC3FF29E0C1FF00889C16 /* SentryFormatterTests.swift */, 7B88F30324BC8E6500ADF90A /* SentrySerializationTests.swift */, 62F4DDA02C04CB9700588890 /* SentryBaggageSerializationTests.swift */, 15E0A8EF240F638200F044E3 /* SentrySerializationNilTests.m */, 7BA61EA525F21E660008CAA2 /* SentryLogTests.swift */, - 7BA61EAB25F2206E0008CAA2 /* SentryLog+TestInit.h */, 62F05D292C0DB1C800916E3F /* SentryLogTestHelper.h */, 62F05D2A2C0DB1F100916E3F /* SentryLogTestHelper.m */, 7BBD18BA24530D2600427C76 /* SentryFileManagerTests.swift */, @@ -3691,6 +3695,8 @@ D8AFC0562BDA895400118BE1 /* UIRedactBuilder.swift */, D8F67AED2BE0D19200C9197B /* UIImageHelper.swift */, 51B15F7D2BE88A7C0026A2F2 /* URLSessionTaskHelper.swift */, + D8AE48AD2C577EAB0092A2A6 /* SentryLog.swift */, + D8AE48AF2C5782EC0092A2A6 /* SentryLogOutput.swift */, ); path = Tools; sourceTree = ""; @@ -4131,7 +4137,6 @@ 7B127B0D27CF6F2300A71ED2 /* SentryANRTrackingIntegration.h in Headers */, 15360CD92432835400112302 /* SentryAutoSessionTrackingIntegration.h in Headers */, 8E564AF0267AF24400FE117D /* SentryNetworkTrackingIntegration.h in Headers */, - 7BA61E8A25F21A3A0008CAA2 /* SentryLogOutput.h in Headers */, D867063E27C3BC2400048851 /* SentryCoreDataSwizzling.h in Headers */, 7BBD1889244841EC00427C76 /* SentryHttpDateParser.h in Headers */, 7D9B07A023D1E89900C5FC8E /* SentryMeta.h in Headers */, @@ -4500,6 +4505,7 @@ 7B08A3472924CF9C0059603A /* SentryMetricKitIntegration.m in Sources */, 62262B8B2BA1C4C1004DA3DD /* EncodeMetrics.swift in Sources */, 7B63459B280EB9E200CFA05A /* SentryUIEventTrackingIntegration.m in Sources */, + D8AE48AE2C577EAB0092A2A6 /* SentryLog.swift in Sources */, 15E0A8ED240F2CB000F044E3 /* SentrySerialization.m in Sources */, 7BC85235245880AE005A70F0 /* SentryDataCategoryMapper.m in Sources */, 7B7A30C824B48389005A4C6E /* SentryCrashWrapper.m in Sources */, @@ -4616,7 +4622,7 @@ 62E146D02BAAE47600ED34FD /* LocalMetricsAggregator.swift in Sources */, D8ACE3C72762187200F5A213 /* SentryNSDataSwizzling.m in Sources */, 638DC9A11EBC6B6400A66E41 /* SentryRequestOperation.m in Sources */, - 63AA767A1EB8D20500D153DE /* SentryLog.m in Sources */, + 63AA767A1EB8D20500D153DE /* SentryLogC.m in Sources */, 6344DDBA1EC3115C00D9160D /* SentryCrashReportConverter.m in Sources */, D8739CF32BECF70F007D2F66 /* SentryLevel.swift in Sources */, 63FE70FD20DA4C1000CDBAE8 /* SentryCrashCachedData.c in Sources */, @@ -4688,7 +4694,6 @@ 7B4E23C2251A2C2B00060D68 /* SentrySessionCrashedHandler.m in Sources */, 9286059729A5098900F96038 /* SentryGeo.m in Sources */, 7B42C48227E08F4B009B58C2 /* SentryDependencyContainer.m in Sources */, - 7BA61E9225F21AF80008CAA2 /* SentryLogOutput.m in Sources */, 639FCFAD1EBC811400778193 /* SentryUser.m in Sources */, 7DAC589123D8B2E0001CF26B /* SentryGlobalEventProcessor.m in Sources */, 7BBD189E244EC8D200427C76 /* SentryRetryAfterHeaderParser.m in Sources */, @@ -4711,6 +4716,7 @@ D8F67B1B2BE9728600C9197B /* SentrySRDefaultBreadcrumbConverter.swift in Sources */, 8EBF870926140D37001A6853 /* SentryPerformanceTracker.m in Sources */, D80CD8D02B75143F002F710B /* UrlSanitized.swift in Sources */, + D8AE48B02C5782EC0092A2A6 /* SentryLogOutput.swift in Sources */, D8F016B32B9622D6007B9AFB /* SentryId.swift in Sources */, D865893029D6ECA7000BE151 /* SentryCrashBinaryImageCache.c in Sources */, 7BC9A20428F4166D001E7C4C /* SentryMeasurementValue.m in Sources */, @@ -4877,6 +4883,7 @@ 63FE721B20DA66EC00CDBAE8 /* Container+DeepSearch_Tests.m in Sources */, 8EA05EED267C2AB200C82B30 /* SentryNetworkTrackerTests.swift in Sources */, 7BA840A024A1EC6E00B718AA /* SentrySDKTests.swift in Sources */, + D8AE48BF2C578D540092A2A6 /* SentryLog.swift in Sources */, D8F6A24E288553A800320515 /* SentryPredicateDescriptorTests.swift in Sources */, 7B18DE4A28DA0C8B004845C6 /* SentryNSNotificationCenterWrapperTests.swift in Sources */, 7B0002322477F0520035FEF1 /* SentrySessionTests.m in Sources */, @@ -4956,6 +4963,7 @@ 7BBD188F2448469A00427C76 /* HttpDateFormatter.swift in Sources */, 63FE720C20DA66EC00CDBAE8 /* SentryCrashMonitor_Tests.m in Sources */, D855B3EA27D652C700BCED76 /* TestCoreDataStack.swift in Sources */, + D8AE48C12C57B1550092A2A6 /* SentryLevelTests.swift in Sources */, 63FE721820DA66EC00CDBAE8 /* TestThread.m in Sources */, 7B4D308A26FC616B00C94DE9 /* SentryHttpTransportTests.swift in Sources */, 7B4E23B6251A07BD00060D68 /* SentryDispatchQueueWrapperTests.swift in Sources */, diff --git a/SentryTestUtils/ClearTestState.swift b/SentryTestUtils/ClearTestState.swift index b058b93da0b..5f324cc5591 100644 --- a/SentryTestUtils/ClearTestState.swift +++ b/SentryTestUtils/ClearTestState.swift @@ -1,5 +1,5 @@ import Foundation -import Sentry +@testable import Sentry public func clearTestState() { TestCleanup.clearTestState() diff --git a/SentryTestUtils/SentryLogExtensions.swift b/SentryTestUtils/SentryLogExtensions.swift index 7cc969c4661..928512568f8 100644 --- a/SentryTestUtils/SentryLogExtensions.swift +++ b/SentryTestUtils/SentryLogExtensions.swift @@ -1,4 +1,5 @@ import Foundation +@testable import Sentry extension SentryLog { public static func setTestDefaultLogLevel() { diff --git a/Sources/Sentry/SentryLevelHelper.m b/Sources/Sentry/SentryLevelHelper.m index a2acd95b580..104092d5d15 100644 --- a/Sources/Sentry/SentryLevelHelper.m +++ b/Sources/Sentry/SentryLevelHelper.m @@ -1,17 +1,8 @@ #import "SentryLevelHelper.h" #import "SentryBreadcrumb+Private.h" -#import "SentryLevelMapper.h" -@implementation SentryLevelHelper - -+ (NSUInteger)breadcrumbLevel:(SentryBreadcrumb *)breadcrumb +NSUInteger +sentry_breadcrumbLevel(SentryBreadcrumb *breadcrumb) { return breadcrumb.level; } - -+ (NSString *_Nonnull)getNameFor:(NSUInteger)level -{ - return nameForSentryLevel(level); -} - -@end diff --git a/Sources/Sentry/SentryLevelMapper.m b/Sources/Sentry/SentryLevelMapper.m index ef2fbc72d09..f9cf7ead754 100644 --- a/Sources/Sentry/SentryLevelMapper.m +++ b/Sources/Sentry/SentryLevelMapper.m @@ -2,56 +2,16 @@ #import "SentrySwift.h" NS_ASSUME_NONNULL_BEGIN -NSString *const kSentryLevelNameNone = @"none"; -NSString *const kSentryLevelNameDebug = @"debug"; -NSString *const kSentryLevelNameInfo = @"info"; -NSString *const kSentryLevelNameWarning = @"warning"; -NSString *const kSentryLevelNameError = @"error"; -NSString *const kSentryLevelNameFatal = @"fatal"; - SentryLevel sentryLevelForString(NSString *string) { - if ([string isEqualToString:kSentryLevelNameNone]) { - return kSentryLevelNone; - } - if ([string isEqualToString:kSentryLevelNameDebug]) { - return kSentryLevelDebug; - } - if ([string isEqualToString:kSentryLevelNameInfo]) { - return kSentryLevelInfo; - } - if ([string isEqualToString:kSentryLevelNameWarning]) { - return kSentryLevelWarning; - } - if ([string isEqualToString:kSentryLevelNameError]) { - return kSentryLevelError; - } - if ([string isEqualToString:kSentryLevelNameFatal]) { - return kSentryLevelFatal; - } - - // Default is error, see https://develop.sentry.dev/sdk/event-payloads/#optional-attributes - return kSentryLevelError; + return [SentryLevelHelper levelForName:string]; } NSString * nameForSentryLevel(SentryLevel level) { - switch (level) { - case kSentryLevelNone: - return kSentryLevelNameNone; - case kSentryLevelDebug: - return kSentryLevelNameDebug; - case kSentryLevelInfo: - return kSentryLevelNameInfo; - case kSentryLevelWarning: - return kSentryLevelNameWarning; - case kSentryLevelError: - return kSentryLevelNameError; - case kSentryLevelFatal: - return kSentryLevelNameFatal; - } + return [SentryLevelHelper nameForLevel:level]; } NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryLog.m b/Sources/Sentry/SentryLog.m deleted file mode 100644 index 9350cb2df21..00000000000 --- a/Sources/Sentry/SentryLog.m +++ /dev/null @@ -1,99 +0,0 @@ -#import "SentryLog.h" -#import "SentryAsyncSafeLog.h" -#import "SentryFileManager.h" -#import "SentryInternalCDefines.h" -#import "SentryLevelMapper.h" -#import "SentryLogOutput.h" - -NS_ASSUME_NONNULL_BEGIN - -@implementation SentryLog - -/** - * Enable per default to log initialization errors. - */ -static BOOL isDebug = YES; -static SentryLevel diagnosticLevel = kSentryLevelError; -static SentryLogOutput *logOutput; -static NSObject *logConfigureLock; - -void -_sentry_initializeAsyncLogFile(void) -{ - const char *asyncLogPath = - [[sentryApplicationSupportPath() stringByAppendingPathComponent:@"async.log"] UTF8String]; - - NSError *error; - if (!createDirectoryIfNotExists(sentryApplicationSupportPath(), &error)) { - SENTRY_LOG_ERROR(@"Failed to initialize directory for async log file: %@", error); - return; - } - - if (SENTRY_LOG_ERRNO( - sentry_asyncLogSetFileName(asyncLogPath, true /* overwrite existing log */)) - != 0) { - SENTRY_LOG_ERROR( - @"Could not open a handle to specified path for async logging %s", asyncLogPath); - }; -} - -+ (void)configure:(BOOL)debug diagnosticLevel:(SentryLevel)level -{ - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ logConfigureLock = [[NSObject alloc] init]; }); - @synchronized(logConfigureLock) { - isDebug = debug; - diagnosticLevel = level; - } - - _sentry_initializeAsyncLogFile(); -} - -+ (void)logWithMessage:(NSString *)message andLevel:(SentryLevel)level -{ - if (nil == logOutput) { - logOutput = [[SentryLogOutput alloc] init]; - } - - if ([self willLogAtLevel:level]) { - [logOutput log:[NSString stringWithFormat:@"[Sentry] [%@] %@", nameForSentryLevel(level), - message]]; - } -} - -+ (BOOL)willLogAtLevel:(SentryLevel)level - SENTRY_DISABLE_THREAD_SANITIZER( - "The SDK usually configures the log level and isDebug once when it starts. For tests, we " - "accept a data race causing some log messages of the wrong level over using a synchronized " - "block for this method, as it's called frequently in production.") -{ - return isDebug && level != kSentryLevelNone && level >= diagnosticLevel; -} - -// Internal and only needed for testing. -+ (void)setLogOutput:(SentryLogOutput *)output -{ - logOutput = output; -} - -// Internal and only needed for testing. -+ (SentryLogOutput *)logOutput -{ - return logOutput; -} - -// Internal and only needed for testing. -+ (BOOL)isDebug -{ - return isDebug; -} - -// Internal and only needed for testing. -+ (SentryLevel)diagnosticLevel -{ - return diagnosticLevel; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryLogC.m b/Sources/Sentry/SentryLogC.m new file mode 100644 index 00000000000..994ebdacbe3 --- /dev/null +++ b/Sources/Sentry/SentryLogC.m @@ -0,0 +1,29 @@ +#import "SentryAsyncSafeLog.h" +#import "SentryFileManager.h" +#import "SentryInternalCDefines.h" +#import "SentryLevelMapper.h" +#import "SentryLog.h" + +NS_ASSUME_NONNULL_BEGIN + +void +sentry_initializeAsyncLogFile(void) +{ + const char *asyncLogPath = + [[sentryApplicationSupportPath() stringByAppendingPathComponent:@"async.log"] UTF8String]; + + NSError *error; + if (!createDirectoryIfNotExists(sentryApplicationSupportPath(), &error)) { + SENTRY_LOG_ERROR(@"Failed to initialize directory for async log file: %@", error); + return; + } + + if (SENTRY_LOG_ERRNO( + sentry_asyncLogSetFileName(asyncLogPath, true /* overwrite existing log */)) + != 0) { + SENTRY_LOG_ERROR( + @"Could not open a handle to specified path for async logging %s", asyncLogPath); + }; +} + +NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryLogOutput.m b/Sources/Sentry/SentryLogOutput.m deleted file mode 100644 index 5a5985b4ecb..00000000000 --- a/Sources/Sentry/SentryLogOutput.m +++ /dev/null @@ -1,14 +0,0 @@ -#import "SentryLogOutput.h" - -NS_ASSUME_NONNULL_BEGIN - -@implementation SentryLogOutput - -- (void)log:(NSString *)message -{ - NSLog(@"%@", message); -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/include/SentryLevelHelper.h b/Sources/Sentry/include/SentryLevelHelper.h index b617d8b6ad5..1211dd6486b 100644 --- a/Sources/Sentry/include/SentryLevelHelper.h +++ b/Sources/Sentry/include/SentryLevelHelper.h @@ -7,12 +7,6 @@ NS_ASSUME_NONNULL_BEGIN /** * This is a workaround to access SentryLevel value from swift */ -@interface SentryLevelHelper : NSObject - -+ (NSUInteger)breadcrumbLevel:(SentryBreadcrumb *)breadcrumb; - -+ (NSString *_Nonnull)getNameFor:(NSUInteger)level; - -@end +NSUInteger sentry_breadcrumbLevel(SentryBreadcrumb *breadcrumb); NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/include/SentryLevelMapper.h b/Sources/Sentry/include/SentryLevelMapper.h index 5304f38491d..fd67041b237 100644 --- a/Sources/Sentry/include/SentryLevelMapper.h +++ b/Sources/Sentry/include/SentryLevelMapper.h @@ -2,13 +2,6 @@ NS_ASSUME_NONNULL_BEGIN -FOUNDATION_EXPORT NSString *const kSentryLevelNameNone; -FOUNDATION_EXPORT NSString *const kSentryLevelNameDebug; -FOUNDATION_EXPORT NSString *const kSentryLevelNameInfo; -FOUNDATION_EXPORT NSString *const kSentryLevelNameWarning; -FOUNDATION_EXPORT NSString *const kSentryLevelNameError; -FOUNDATION_EXPORT NSString *const kSentryLevelNameFatal; - /** * Maps a string to a SentryLevel. If the passed string doesn't match any level this defaults to * the 'error' level. See https://develop.sentry.dev/sdk/event-payloads/#optional-attributes diff --git a/Sources/Sentry/include/SentryLog.h b/Sources/Sentry/include/SentryLog.h index 21dce69d0a3..7ea9367475c 100644 --- a/Sources/Sentry/include/SentryLog.h +++ b/Sources/Sentry/include/SentryLog.h @@ -1,26 +1,6 @@ #import "SentryDefines.h" #import "SentrySwift.h" -@class SentryLogOutput; - -NS_ASSUME_NONNULL_BEGIN - -@interface SentryLog : NSObject -SENTRY_NO_INIT - -+ (void)configure:(BOOL)debug diagnosticLevel:(SentryLevel)level; - -+ (void)logWithMessage:(NSString *)message andLevel:(SentryLevel)level; - -/** - * @return @c YES if the current logging configuration will log statements at the current level, - * @c NO if not. - */ -+ (BOOL)willLogAtLevel:(SentryLevel)level; - -@end - -NS_ASSUME_NONNULL_END #define SENTRY_LOG(_SENTRY_LOG_LEVEL, ...) \ if ([SentryLog willLogAtLevel:_SENTRY_LOG_LEVEL]) { \ [SentryLog logWithMessage:[NSString stringWithFormat:@"[%@:%d] %@", \ diff --git a/Sources/Sentry/include/SentryLogC.h b/Sources/Sentry/include/SentryLogC.h new file mode 100644 index 00000000000..a6d2057c11a --- /dev/null +++ b/Sources/Sentry/include/SentryLogC.h @@ -0,0 +1,4 @@ +#ifndef SentryLogC_h +#define SentryLogC_h +void sentry_initializeAsyncLogFile(void); +#endif diff --git a/Sources/Sentry/include/SentryLogOutput.h b/Sources/Sentry/include/SentryLogOutput.h deleted file mode 100644 index c16710675b8..00000000000 --- a/Sources/Sentry/include/SentryLogOutput.h +++ /dev/null @@ -1,11 +0,0 @@ -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface SentryLogOutput : NSObject - -- (void)log:(NSString *)message; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/include/SentryPrivate.h b/Sources/Sentry/include/SentryPrivate.h index dab99b891dd..41222128995 100644 --- a/Sources/Sentry/include/SentryPrivate.h +++ b/Sources/Sentry/include/SentryPrivate.h @@ -11,6 +11,7 @@ #import "SentryDateUtil.h" #import "SentryDisplayLinkWrapper.h" #import "SentryLevelHelper.h" +#import "SentryLogC.h" #import "SentryRandom.h" #import "SentrySdkInfo.h" #import "SentrySession.h" diff --git a/Sources/Swift/Helper/Log/SentryLevel.swift b/Sources/Swift/Helper/Log/SentryLevel.swift index 24bf025f73e..80ed88a7190 100644 --- a/Sources/Swift/Helper/Log/SentryLevel.swift +++ b/Sources/Swift/Helper/Log/SentryLevel.swift @@ -1,7 +1,10 @@ +@_implementationOnly import _SentryPrivate import Foundation @objc public enum SentryLevel: UInt { + static let levelNames = ["none", "debug", "info", "warning", "error", "fatal"] + @objc(kSentryLevelNone) case none = 0 @@ -21,3 +24,29 @@ public enum SentryLevel: UInt { @objc(kSentryLevelFatal) case fatal = 5 } + +extension SentryLevel: CustomStringConvertible { + public var description: String { + return SentryLevel.levelNames[Int(self.rawValue)] + } + + static func fromName(_ name: String) -> SentryLevel { + guard let index = SentryLevel.levelNames.firstIndex(of: name) else { return .error } + return SentryLevel(rawValue: UInt(index)) ?? .error + } +} + +@objcMembers +class SentryLevelHelper: NSObject { + static func nameForLevel(_ level: SentryLevel) -> String { + return level.description + } + + static func levelForName(_ name: String) -> SentryLevel { + .fromName(name) + } + + static func breadcrumbLevel(_ breadcrumb: Breadcrumb) -> SentryLevel? { + SentryLevel(rawValue: sentry_breadcrumbLevel(breadcrumb)) + } +} diff --git a/Sources/Swift/Integrations/SessionReplay/RRWeb/SentryRRWebBreadcrumbEvent.swift b/Sources/Swift/Integrations/SessionReplay/RRWeb/SentryRRWebBreadcrumbEvent.swift index d68f5717b3f..f731c156851 100644 --- a/Sources/Swift/Integrations/SessionReplay/RRWeb/SentryRRWebBreadcrumbEvent.swift +++ b/Sources/Swift/Integrations/SessionReplay/RRWeb/SentryRRWebBreadcrumbEvent.swift @@ -4,7 +4,7 @@ import Foundation class SentryRRWebBreadcrumbEvent: SentryRRWebCustomEvent { init(timestamp: Date, category: String, message: String? = nil, level: SentryLevel = .none, data: [String: Any]? = nil) { - var payload: [String: Any] = ["type": "default", "category": category, "level": SentryLevelHelper.getNameFor(level.rawValue), "timestamp": timestamp.timeIntervalSince1970 ] + var payload: [String: Any] = ["type": "default", "category": category, "level": level.description, "timestamp": timestamp.timeIntervalSince1970 ] if let message = message { payload["message"] = message diff --git a/Sources/Swift/Integrations/SessionReplay/SentrySRDefaultBreadcrumbConverter.swift b/Sources/Swift/Integrations/SessionReplay/SentrySRDefaultBreadcrumbConverter.swift index 5a1324f27d1..0d3208c44b7 100644 --- a/Sources/Swift/Integrations/SessionReplay/SentrySRDefaultBreadcrumbConverter.swift +++ b/Sources/Swift/Integrations/SessionReplay/SentrySRDefaultBreadcrumbConverter.swift @@ -1,4 +1,3 @@ -@_implementationOnly import _SentryPrivate import Foundation @objc @@ -84,6 +83,6 @@ class SentrySRDefaultBreadcrumbConverter: NSObject, SentryReplayBreadcrumbConver } private func getLevel(breadcrumb: Breadcrumb) -> SentryLevel { - return SentryLevel(rawValue: SentryLevelHelper.breadcrumbLevel(breadcrumb)) ?? .none + return SentryLevelHelper.breadcrumbLevel(breadcrumb) ?? .none } } diff --git a/Sources/Swift/Tools/SentryLog.swift b/Sources/Swift/Tools/SentryLog.swift new file mode 100644 index 00000000000..49d3cae6dd2 --- /dev/null +++ b/Sources/Swift/Tools/SentryLog.swift @@ -0,0 +1,48 @@ +@_implementationOnly import _SentryPrivate +import Foundation + +@objc +class SentryLog: NSObject { + + static private(set) var isDebug = true + static private(set) var diagnosticLevel = SentryLevel.error + private static var logOutput = SentryLogOutput() + private static var logConfigureLock = NSLock() + + @objc + static func configure(_ isDebug: Bool, diagnosticLevel: SentryLevel) { + logConfigureLock.synchronized { + self.isDebug = isDebug + self.diagnosticLevel = diagnosticLevel + } + sentry_initializeAsyncLogFile() + } + + @objc + static func log(message: String, andLevel level: SentryLevel) { + guard willLog(atLevel: level) else { return } + logOutput.log("[Sentry] [\(level)] \(message)") + } + + /** + * @return @c YES if the current logging configuration will log statements at the current level, + * @c NO if not. + */ + @objc + static func willLog(atLevel level: SentryLevel) -> Bool { + return isDebug && level != .none && level.rawValue >= diagnosticLevel.rawValue + } + + #if TEST + + @objc + static func setOutput(_ output: SentryLogOutput) { + logOutput = output + } + + static func getOutput() -> SentryLogOutput { + return logOutput + } + + #endif +} diff --git a/Sources/Swift/Tools/SentryLogOutput.swift b/Sources/Swift/Tools/SentryLogOutput.swift new file mode 100644 index 00000000000..3d704d06845 --- /dev/null +++ b/Sources/Swift/Tools/SentryLogOutput.swift @@ -0,0 +1,8 @@ +import Foundation + +@objcMembers +class SentryLogOutput: NSObject { + func log(_ message: String) { + print(message) + } +} diff --git a/Tests/SentryTests/Helper/SentryFileManagerTests.swift b/Tests/SentryTests/Helper/SentryFileManagerTests.swift index fc673a69e14..2008f71945e 100644 --- a/Tests/SentryTests/Helper/SentryFileManagerTests.swift +++ b/Tests/SentryTests/Helper/SentryFileManagerTests.swift @@ -1,4 +1,4 @@ -import Sentry +@testable import Sentry import SentryTestUtils import XCTest @@ -147,7 +147,7 @@ class SentryFileManagerTests: XCTestCase { func testDeleteOldEnvelopes_LogsIgnoreDSStoreFiles() throws { let logOutput = TestLogOutput() SentryLog.setLogOutput(logOutput) - SentryLog.configure(true, diagnosticLevel: .debug) + SentryLog.configureLog(true, diagnosticLevel: .debug) let dsStoreFile = "\(sut.basePath)/.DS_Store" @@ -168,7 +168,7 @@ class SentryFileManagerTests: XCTestCase { func testDeleteOldEnvelopes_LogsDebugForTextFiles() throws { let logOutput = TestLogOutput() SentryLog.setLogOutput(logOutput) - SentryLog.configure(true, diagnosticLevel: .debug) + SentryLog.configureLog(true, diagnosticLevel: .debug) let sut = fixture.getSut() @@ -191,7 +191,7 @@ class SentryFileManagerTests: XCTestCase { func testGetEnvelopesPath_ForNonExistentPath_LogsWarning() throws { let logOutput = TestLogOutput() SentryLog.setLogOutput(logOutput) - SentryLog.configure(true, diagnosticLevel: .debug) + SentryLog.configureLog(true, diagnosticLevel: .debug) let sut = fixture.getSut() @@ -539,7 +539,7 @@ class SentryFileManagerTests: XCTestCase { func testGetAllEnvelopesWhenNoEnvelopesPath_LogsInfoMessage() { let logOutput = TestLogOutput() SentryLog.setLogOutput(logOutput) - SentryLog.configure(true, diagnosticLevel: .debug) + SentryLog.configureLog(true, diagnosticLevel: .debug) sut.deleteAllFolders() sut.getAllEnvelopes() diff --git a/Tests/SentryTests/Helper/SentryLog+TestInit.h b/Tests/SentryTests/Helper/SentryLog+TestInit.h deleted file mode 100644 index ea6e3c9a6de..00000000000 --- a/Tests/SentryTests/Helper/SentryLog+TestInit.h +++ /dev/null @@ -1,24 +0,0 @@ -#import "SentryLog.h" - -NS_ASSUME_NONNULL_BEGIN - -@class SentryLogOutput; - -@interface -SentryLog (TestInit) - -/** Internal and only needed for testing. */ -+ (void)setLogOutput:(nullable SentryLogOutput *)output; - -/** Internal and only needed for testing. */ -+ (SentryLogOutput *)logOutput; - -/** Internal and only needed for testing. */ -+ (BOOL)isDebug; - -/** Internal and only needed for testing. */ -+ (SentryLevel)diagnosticLevel; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Tests/SentryTests/Helper/SentryLog.swift b/Tests/SentryTests/Helper/SentryLog.swift new file mode 100644 index 00000000000..7acb1bca7d1 --- /dev/null +++ b/Tests/SentryTests/Helper/SentryLog.swift @@ -0,0 +1,24 @@ +@testable import Sentry + +typealias SentryLog = Sentry.SentryLog + +//Exposing internal/test functions from SentryLog +extension Sentry.SentryLog { + static func configureLog(_ isDebug: Bool, diagnosticLevel: SentryLevel) { + SentryLog.configure(isDebug, diagnosticLevel: diagnosticLevel) + } + + static func setLogOutput(_ output: SentryLogOutput) { + #if TEST + SentryLog.setOutput(output) + #endif + } + + static func getLogOutput() -> SentryLogOutput { + #if TEST + return SentryLog.getOutput() + #else + SentryLogOutput() + #endif + } +} diff --git a/Tests/SentryTests/Helper/SentryLogTests.swift b/Tests/SentryTests/Helper/SentryLogTests.swift index adf85e971e9..13bf81fc1d9 100644 --- a/Tests/SentryTests/Helper/SentryLogTests.swift +++ b/Tests/SentryTests/Helper/SentryLogTests.swift @@ -1,3 +1,4 @@ +@testable import Sentry import SentryTestUtils import XCTest @@ -8,9 +9,9 @@ class SentryLogTests: XCTestCase { override func setUp() { super.setUp() - oldDebug = SentryLog.isDebug() - oldLevel = SentryLog.diagnosticLevel() - oldOutput = SentryLog.logOutput() + oldDebug = SentryLog.isDebug + oldLevel = SentryLog.diagnosticLevel + oldOutput = SentryLog.getLogOutput() } override func tearDown() { @@ -24,16 +25,16 @@ class SentryLogTests: XCTestCase { SentryLog.setLogOutput(logOutput) SentryLog.configure(true, diagnosticLevel: .error) - SentryLog.log(withMessage: "0", andLevel: SentryLevel.fatal) - SentryLog.log(withMessage: "1", andLevel: SentryLevel.error) - SentryLog.log(withMessage: "2", andLevel: SentryLevel.warning) - SentryLog.log(withMessage: "3", andLevel: SentryLevel.none) + SentryLog.log(message: "0", andLevel: SentryLevel.fatal) + SentryLog.log(message: "1", andLevel: SentryLevel.error) + SentryLog.log(message: "2", andLevel: SentryLevel.warning) + SentryLog.log(message: "3", andLevel: SentryLevel.none) XCTAssertEqual(["[Sentry] [fatal] 0", "[Sentry] [error] 1"], logOutput.loggedMessages) } func testDefaultInitOfLogoutPut() { - SentryLog.log(withMessage: "0", andLevel: SentryLevel.error) + SentryLog.log(message: "0", andLevel: SentryLevel.error) } func testConfigureWithoutDebug_PrintsNothing() { @@ -41,12 +42,12 @@ class SentryLogTests: XCTestCase { SentryLog.setLogOutput(logOutput) SentryLog.configure(false, diagnosticLevel: SentryLevel.none) - SentryLog.log(withMessage: "0", andLevel: SentryLevel.fatal) - SentryLog.log(withMessage: "0", andLevel: SentryLevel.error) - SentryLog.log(withMessage: "0", andLevel: SentryLevel.warning) - SentryLog.log(withMessage: "0", andLevel: SentryLevel.info) - SentryLog.log(withMessage: "0", andLevel: SentryLevel.debug) - SentryLog.log(withMessage: "0", andLevel: SentryLevel.none) + SentryLog.log(message: "0", andLevel: SentryLevel.fatal) + SentryLog.log(message: "0", andLevel: SentryLevel.error) + SentryLog.log(message: "0", andLevel: SentryLevel.warning) + SentryLog.log(message: "0", andLevel: SentryLevel.info) + SentryLog.log(message: "0", andLevel: SentryLevel.debug) + SentryLog.log(message: "0", andLevel: SentryLevel.none) XCTAssertEqual(0, logOutput.loggedMessages.count) } @@ -56,12 +57,12 @@ class SentryLogTests: XCTestCase { SentryLog.setLogOutput(logOutput) SentryLog.configure(true, diagnosticLevel: SentryLevel.none) - SentryLog.log(withMessage: "0", andLevel: SentryLevel.fatal) - SentryLog.log(withMessage: "1", andLevel: SentryLevel.error) - SentryLog.log(withMessage: "2", andLevel: SentryLevel.warning) - SentryLog.log(withMessage: "3", andLevel: SentryLevel.info) - SentryLog.log(withMessage: "4", andLevel: SentryLevel.debug) - SentryLog.log(withMessage: "5", andLevel: SentryLevel.none) + SentryLog.log(message: "0", andLevel: SentryLevel.fatal) + SentryLog.log(message: "1", andLevel: SentryLevel.error) + SentryLog.log(message: "2", andLevel: SentryLevel.warning) + SentryLog.log(message: "3", andLevel: SentryLevel.info) + SentryLog.log(message: "4", andLevel: SentryLevel.debug) + SentryLog.log(message: "5", andLevel: SentryLevel.none) XCTAssertEqual(["[Sentry] [fatal] 0", "[Sentry] [error] 1", @@ -89,4 +90,5 @@ class SentryLogTests: XCTestCase { XCTAssertTrue(logOutput.loggedMessages.isEmpty) } + } diff --git a/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackingIntegrationTests.swift b/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackingIntegrationTests.swift index e364acdd47b..64ee2b63ab0 100644 --- a/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackingIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackingIntegrationTests.swift @@ -23,7 +23,7 @@ class SentryAppStartTrackingIntegrationTests: NotificationCenterTestCase { override class func setUp() { super.setUp() - SentryLog.configure(true, diagnosticLevel: .debug) + SentryLog.configureLog(true, diagnosticLevel: .debug) clearTestState() } diff --git a/Tests/SentryTests/Integrations/Performance/SentryPerformanceTrackerTests.swift b/Tests/SentryTests/Integrations/Performance/SentryPerformanceTrackerTests.swift index 6d50361f6f3..b1853bac97c 100644 --- a/Tests/SentryTests/Integrations/Performance/SentryPerformanceTrackerTests.swift +++ b/Tests/SentryTests/Integrations/Performance/SentryPerformanceTrackerTests.swift @@ -282,7 +282,7 @@ class SentryPerformanceTrackerTests: XCTestCase { func testStartSpanAsync() { // To not spam the test logs - SentryLog.configure(true, diagnosticLevel: .error) + SentryLog.configureLog(true, diagnosticLevel: .error) let sut = fixture.getSut() let spanId = startSpan(tracker: sut) diff --git a/Tests/SentryTests/Integrations/SentryBaseIntegrationTests.swift b/Tests/SentryTests/Integrations/SentryBaseIntegrationTests.swift index b052f3e0be5..1773d2b8905 100644 --- a/Tests/SentryTests/Integrations/SentryBaseIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/SentryBaseIntegrationTests.swift @@ -1,4 +1,4 @@ -import Sentry +@testable import Sentry import XCTest class MyTestIntegration: SentryBaseIntegration { @@ -15,10 +15,10 @@ class SentryBaseIntegrationTests: XCTestCase { override func setUp() { super.setUp() - oldDebug = SentryLog.isDebug() - oldLevel = SentryLog.diagnosticLevel() - oldOutput = SentryLog.logOutput() + oldDebug = SentryLog.isDebug + oldLevel = SentryLog.diagnosticLevel SentryLog.configure(true, diagnosticLevel: SentryLevel.debug) + oldOutput = SentryLog.getOutput() logOutput = TestLogOutput() SentryLog.setLogOutput(logOutput) } diff --git a/Tests/SentryTests/Networking/SentrySpotlightTransportTests.swift b/Tests/SentryTests/Networking/SentrySpotlightTransportTests.swift index 5effa04068c..9117b169388 100644 --- a/Tests/SentryTests/Networking/SentrySpotlightTransportTests.swift +++ b/Tests/SentryTests/Networking/SentrySpotlightTransportTests.swift @@ -1,4 +1,4 @@ -import Sentry +@testable import Sentry import SentryTestUtils import XCTest @@ -124,7 +124,7 @@ final class SentrySpotlightTransportTests: XCTestCase { func testShouldLogError_WhenRequestManagerCompletesWithError() throws { let logOutput = TestLogOutput() SentryLog.setLogOutput(logOutput) - SentryLog.configure(true, diagnosticLevel: .debug) + SentryLog.configureLog(true, diagnosticLevel: .debug) let eventEnvelope = try givenEventEnvelope() requestManager.nextError = NSError(domain: "error", code: 47) diff --git a/Tests/SentryTests/SentryLevelTests.swift b/Tests/SentryTests/SentryLevelTests.swift new file mode 100644 index 00000000000..59d596029f1 --- /dev/null +++ b/Tests/SentryTests/SentryLevelTests.swift @@ -0,0 +1,22 @@ +import Foundation +@testable import Sentry +import XCTest + +class SentryLevelTests: XCTestCase { + + func testNames() { + XCTAssertEqual(SentryLevel.none, SentryLevel.fromName("none")) + XCTAssertEqual(SentryLevel.debug, SentryLevel.fromName("debug")) + XCTAssertEqual(SentryLevel.error, SentryLevel.fromName("error")) + XCTAssertEqual(SentryLevel.info, SentryLevel.fromName("info")) + XCTAssertEqual(SentryLevel.fatal, SentryLevel.fromName("fatal")) + XCTAssertEqual(SentryLevel.warning, SentryLevel.fromName("warning")) + + XCTAssertEqual(SentryLevel.none.description, "none") + XCTAssertEqual(SentryLevel.debug.description, "debug") + XCTAssertEqual(SentryLevel.error.description, "error") + XCTAssertEqual(SentryLevel.info.description, "info") + XCTAssertEqual(SentryLevel.fatal.description, "fatal") + XCTAssertEqual(SentryLevel.warning.description, "warning") + } +} diff --git a/Tests/SentryTests/SentryTests-Bridging-Header.h b/Tests/SentryTests/SentryTests-Bridging-Header.h index b187a747604..34dfc07d15b 100644 --- a/Tests/SentryTests/SentryTests-Bridging-Header.h +++ b/Tests/SentryTests/SentryTests-Bridging-Header.h @@ -134,9 +134,7 @@ #import "SentryInstallation.h" #import "SentryInternalNotificationNames.h" #import "SentryLevelMapper.h" -#import "SentryLog+TestInit.h" #import "SentryLog.h" -#import "SentryLogOutput.h" #import "SentryLogTestHelper.h" #import "SentryMeasurementValue.h" #import "SentryMechanism.h" diff --git a/Tests/SentryTests/SentryTests.m b/Tests/SentryTests/SentryTests.m index 2417ed83bf3..391d443c74b 100644 --- a/Tests/SentryTests/SentryTests.m +++ b/Tests/SentryTests/SentryTests.m @@ -112,26 +112,6 @@ - (void)testSDKCaptureError [SentrySDK captureError:error]; } -- (void)testLevelNames -{ - XCTAssertEqual(kSentryLevelNone, sentryLevelForString(kSentryLevelNameNone)); - XCTAssertEqual(kSentryLevelDebug, sentryLevelForString(kSentryLevelNameDebug)); - XCTAssertEqual(kSentryLevelInfo, sentryLevelForString(kSentryLevelNameInfo)); - XCTAssertEqual(kSentryLevelWarning, sentryLevelForString(kSentryLevelNameWarning)); - XCTAssertEqual(kSentryLevelError, sentryLevelForString(kSentryLevelNameError)); - XCTAssertEqual(kSentryLevelFatal, sentryLevelForString(kSentryLevelNameFatal)); - - XCTAssertEqual(kSentryLevelError, sentryLevelForString(@"fdjsafdsa"), - @"Failed to map an unexpected string value to the default case."); - - XCTAssertEqualObjects(kSentryLevelNameNone, nameForSentryLevel(kSentryLevelNone)); - XCTAssertEqualObjects(kSentryLevelNameDebug, nameForSentryLevel(kSentryLevelDebug)); - XCTAssertEqualObjects(kSentryLevelNameInfo, nameForSentryLevel(kSentryLevelInfo)); - XCTAssertEqualObjects(kSentryLevelNameWarning, nameForSentryLevel(kSentryLevelWarning)); - XCTAssertEqualObjects(kSentryLevelNameError, nameForSentryLevel(kSentryLevelError)); - XCTAssertEqualObjects(kSentryLevelNameFatal, nameForSentryLevel(kSentryLevelFatal)); -} - - (void)testLevelOrder { XCTAssertGreaterThan(kSentryLevelFatal, kSentryLevelError); diff --git a/Tests/SentryTests/TestLogOutput.swift b/Tests/SentryTests/TestLogOutput.swift index 76e02125569..8de26905eef 100644 --- a/Tests/SentryTests/TestLogOutput.swift +++ b/Tests/SentryTests/TestLogOutput.swift @@ -1,4 +1,5 @@ import Foundation +@testable import Sentry import XCTest class TestLogOutput: SentryLogOutput { diff --git a/Tests/SentryTests/TestUtils/TestConncurrentModifications.swift b/Tests/SentryTests/TestUtils/TestConncurrentModifications.swift index 98e50be7511..5c6fb6ae5fd 100644 --- a/Tests/SentryTests/TestUtils/TestConncurrentModifications.swift +++ b/Tests/SentryTests/TestUtils/TestConncurrentModifications.swift @@ -3,7 +3,7 @@ import SentryTestUtils func testConcurrentModifications(asyncWorkItems: Int = 5, writeLoopCount: Int = 1_000, writeWork: @escaping (Int) -> Void, readWork: @escaping () -> Void = {}) { // To not spam the test logs - SentryLog.configure(true, diagnosticLevel: .error) + SentryLog.configureLog(true, diagnosticLevel: .error) let queue = DispatchQueue(label: "testConcurrentModifications", qos: .userInteractive, attributes: [.concurrent, .initiallyInactive]) let group = DispatchGroup() From a4d5d7cf6e5c7b19b1e1c0939d71d9717c94a5fb Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Mon, 29 Jul 2024 13:34:27 +0200 Subject: [PATCH 2/8] Conveniente Log Function --- Sources/Swift/Tools/SentryLog.swift | 28 +++++++++++++++++++ Tests/SentryTests/Helper/SentryLogTests.swift | 9 ++++++ 2 files changed, 37 insertions(+) diff --git a/Sources/Swift/Tools/SentryLog.swift b/Sources/Swift/Tools/SentryLog.swift index 49d3cae6dd2..d78fce189d0 100644 --- a/Sources/Swift/Tools/SentryLog.swift +++ b/Sources/Swift/Tools/SentryLog.swift @@ -46,3 +46,31 @@ class SentryLog: NSObject { #endif } + +extension SentryLog { + private static func log(level: SentryLevel, message: String, file: String, line: Int) { + let path = file as NSString + let fileName = (path.lastPathComponent as NSString).deletingPathExtension + log(message: "[\(fileName):\(line)] \(message)", andLevel: level) + } + + static func debug(_ message : String, file: String = #file, line: Int = #line) { + log(level: .debug, message: message, file: file, line: line) + } + + static func info(_ message : String, file: String = #file, line: Int = #line) { + log(level: .info, message: message, file: file, line: line) + } + + static func warning(_ message : String, file: String = #file, line: Int = #line) { + log(level: .warning, message: message, file: file, line: line) + } + + static func error(_ message : String, file: String = #file, line: Int = #line) { + log(level: .error, message: message, file: file, line: line) + } + + static func fatal(_ message : String, file: String = #file, line: Int = #line) { + log(level: .fatal, message: message, file: file, line: line) + } +} diff --git a/Tests/SentryTests/Helper/SentryLogTests.swift b/Tests/SentryTests/Helper/SentryLogTests.swift index 13bf81fc1d9..e3e8b10ad53 100644 --- a/Tests/SentryTests/Helper/SentryLogTests.swift +++ b/Tests/SentryTests/Helper/SentryLogTests.swift @@ -91,4 +91,13 @@ class SentryLogTests: XCTestCase { XCTAssertTrue(logOutput.loggedMessages.isEmpty) } + func testConvenientLogFunction() { + let logOutput = TestLogOutput() + SentryLog.setLogOutput(logOutput) + SentryLog.configure(true, diagnosticLevel: SentryLevel.debug) + let line = #line + 1 + SentryLog.debug("Debug Log") + XCTAssertEqual(["[Sentry] [debug] [SentryLogTests:\(line)] Debug Log"], logOutput.loggedMessages) + } + } From c8998fb87911f348bee93b3042e235c4963653d8 Mon Sep 17 00:00:00 2001 From: Sentry Github Bot Date: Mon, 29 Jul 2024 11:35:32 +0000 Subject: [PATCH 3/8] Format code --- Sources/Swift/Tools/SentryLog.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/Swift/Tools/SentryLog.swift b/Sources/Swift/Tools/SentryLog.swift index d78fce189d0..c2ccfd6b71b 100644 --- a/Sources/Swift/Tools/SentryLog.swift +++ b/Sources/Swift/Tools/SentryLog.swift @@ -54,23 +54,23 @@ extension SentryLog { log(message: "[\(fileName):\(line)] \(message)", andLevel: level) } - static func debug(_ message : String, file: String = #file, line: Int = #line) { + static func debug(_ message: String, file: String = #file, line: Int = #line) { log(level: .debug, message: message, file: file, line: line) } - static func info(_ message : String, file: String = #file, line: Int = #line) { + static func info(_ message: String, file: String = #file, line: Int = #line) { log(level: .info, message: message, file: file, line: line) } - static func warning(_ message : String, file: String = #file, line: Int = #line) { + static func warning(_ message: String, file: String = #file, line: Int = #line) { log(level: .warning, message: message, file: file, line: line) } - static func error(_ message : String, file: String = #file, line: Int = #line) { + static func error(_ message: String, file: String = #file, line: Int = #line) { log(level: .error, message: message, file: file, line: line) } - static func fatal(_ message : String, file: String = #file, line: Int = #line) { + static func fatal(_ message: String, file: String = #file, line: Int = #line) { log(level: .fatal, message: message, file: file, line: line) } } From 72a681b996eadb431d85908976e90b2e7864ed1f Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Mon, 29 Jul 2024 13:50:39 +0200 Subject: [PATCH 4/8] Delete SentryBreadcrumbReplayConverter.swift --- .../SentryBreadcrumbReplayConverter.swift | 83 ------------------- 1 file changed, 83 deletions(-) delete mode 100644 Sources/Swift/Integrations/SessionReplay/SentryBreadcrumbReplayConverter.swift diff --git a/Sources/Swift/Integrations/SessionReplay/SentryBreadcrumbReplayConverter.swift b/Sources/Swift/Integrations/SessionReplay/SentryBreadcrumbReplayConverter.swift deleted file mode 100644 index 150be51bf12..00000000000 --- a/Sources/Swift/Integrations/SessionReplay/SentryBreadcrumbReplayConverter.swift +++ /dev/null @@ -1,83 +0,0 @@ -@_implementationOnly import _SentryPrivate -import Foundation - -@objcMembers -class SentryBreadcrumbReplayConverter: NSObject { - - private let supportedNetworkData = Set([ - "status_code", - "method", - "response_content_length", - "request_content_length", - "http.query", - "http.fragment"] - ) - - func replayBreadcrumbs(from breadcrumbs: [Breadcrumb]) -> [SentryRRWebEvent] { - breadcrumbs.compactMap { replayBreadcrumb(from: $0) } - } - - //Convert breadcrumb information into something - //replay front understands - private func replayBreadcrumb(from breadcrumb: Breadcrumb) -> SentryRRWebEvent? { - guard let timestamp = breadcrumb.timestamp else { return nil } - if breadcrumb.category == "http" { - return networkSpan(breadcrumb) - } else if breadcrumb.type == "navigation" { - return navigationBreadcrumb(breadcrumb) - } else if breadcrumb.category == "touch" { - return SentryRRWebBreadcrumbEvent(timestamp: timestamp, category: "ui.tap", message: breadcrumb.message) - } else if breadcrumb.type == "connectivity" && breadcrumb.category == "device.connectivity" { - guard let networkType = breadcrumb.data?["connectivity"] as? String, !networkType.isEmpty else { return nil } - return SentryRRWebBreadcrumbEvent(timestamp: timestamp, category: "device.connectivity", data: ["state": networkType]) - } else if let action = breadcrumb.data?["action"] as? String, action == "BATTERY_STATE_CHANGE" { - var data = breadcrumb.data?.filter({ item in item.key == "level" || item.key == "plugged" }) ?? [:] - - data["charging"] = data["plugged"] - data["plugged"] = nil - - return SentryRRWebBreadcrumbEvent(timestamp: timestamp, - category: "device.battery", - data: data) - } - - let level = getLevel(breadcrumb: breadcrumb) - return SentryRRWebBreadcrumbEvent(timestamp: timestamp, category: breadcrumb.category, message: breadcrumb.message, level: level, data: breadcrumb.data) - } - - private func navigationBreadcrumb(_ breadcrumb: Breadcrumb) -> SentryRRWebBreadcrumbEvent? { - guard let timestamp = breadcrumb.timestamp else { return nil } - - if breadcrumb.category == "app.lifecycle" { - guard let state = breadcrumb.data?["state"] else { return nil } - return SentryRRWebBreadcrumbEvent(timestamp: timestamp, category: "app.\(state)") - } else if let position = breadcrumb.data?["position"] as? String, breadcrumb.category == "device.orientation" && (position == "landscape" || position == "portrait") { - return SentryRRWebBreadcrumbEvent(timestamp: timestamp, category: "device.orientation", data: ["position": position]) - } else { - if let to = breadcrumb.data?["screen"] as? String { - return SentryRRWebBreadcrumbEvent(timestamp: timestamp, category: "navigation", message: to, data: ["to": to]) - } else { - return nil - } - } - } - - private func networkSpan(_ breadcrumb: Breadcrumb) -> SentryRRWebSpanEvent? { - guard let timestamp = breadcrumb.timestamp, let description = breadcrumb.data?["url"] as? String else { return nil } - var data = [String: Any]() - - breadcrumb.data?.forEach({ - guard supportedNetworkData.contains($0.key) else { return } - let newKey = $0.key == "response_body_size" ? "bodySize" : $0.key.replacingOccurrences(of: "http.", with: "") - data[newKey.snakeToCamelCase()] = $0.value - }) - - //We dont have end of the request in the breadcrumb. - return SentryRRWebSpanEvent(timestamp: timestamp, endTimestamp: timestamp, operation: "resource.http", description: description, data: data) - } - - private func getLevel(breadcrumb: Breadcrumb) -> SentryLevel { - return SentryLevel(rawValue: SentryLevelHelper.breadcrumbLevel(breadcrumb)) ?? .none - - } -} From 260b82e60f7503ed92005e05d66fba1015d09dd7 Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Mon, 29 Jul 2024 14:00:56 +0200 Subject: [PATCH 5/8] ci --- Sources/Swift/Tools/SentryLog.swift | 2 +- Tests/SentryTests/Helper/SentryLog.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/Swift/Tools/SentryLog.swift b/Sources/Swift/Tools/SentryLog.swift index c2ccfd6b71b..9b3fe66099f 100644 --- a/Sources/Swift/Tools/SentryLog.swift +++ b/Sources/Swift/Tools/SentryLog.swift @@ -33,7 +33,7 @@ class SentryLog: NSObject { return isDebug && level != .none && level.rawValue >= diagnosticLevel.rawValue } - #if TEST + #if TEST || TESTCI @objc static func setOutput(_ output: SentryLogOutput) { diff --git a/Tests/SentryTests/Helper/SentryLog.swift b/Tests/SentryTests/Helper/SentryLog.swift index 7acb1bca7d1..4e9853476c2 100644 --- a/Tests/SentryTests/Helper/SentryLog.swift +++ b/Tests/SentryTests/Helper/SentryLog.swift @@ -9,13 +9,13 @@ extension Sentry.SentryLog { } static func setLogOutput(_ output: SentryLogOutput) { - #if TEST + #if TEST || TESTCI SentryLog.setOutput(output) #endif } static func getLogOutput() -> SentryLogOutput { - #if TEST + #if TEST || TESTCI return SentryLog.getOutput() #else SentryLogOutput() From 4670a6736515b8f94308a004a5c6c3d6fab393f4 Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Mon, 29 Jul 2024 14:16:43 +0200 Subject: [PATCH 6/8] Update Sources/Swift/Tools/SentryLog.swift --- Sources/Swift/Tools/SentryLog.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/Swift/Tools/SentryLog.swift b/Sources/Swift/Tools/SentryLog.swift index 9b3fe66099f..ab54b195496 100644 --- a/Sources/Swift/Tools/SentryLog.swift +++ b/Sources/Swift/Tools/SentryLog.swift @@ -35,7 +35,6 @@ class SentryLog: NSObject { #if TEST || TESTCI - @objc static func setOutput(_ output: SentryLogOutput) { logOutput = output } From f9e6472f8d5246768fec22fc42cf524eead36ef0 Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Tue, 30 Jul 2024 11:18:50 +0200 Subject: [PATCH 7/8] Apply suggestions from code review Co-authored-by: Philipp Hofmann --- Sources/Swift/Tools/SentryLog.swift | 1 + Sources/Swift/Tools/SentryLogOutput.swift | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Swift/Tools/SentryLog.swift b/Sources/Swift/Tools/SentryLog.swift index ab54b195496..85bb4a75994 100644 --- a/Sources/Swift/Tools/SentryLog.swift +++ b/Sources/Swift/Tools/SentryLog.swift @@ -48,6 +48,7 @@ class SentryLog: NSObject { extension SentryLog { private static func log(level: SentryLevel, message: String, file: String, line: Int) { + guard willLog(atLevel: level) else { return } let path = file as NSString let fileName = (path.lastPathComponent as NSString).deletingPathExtension log(message: "[\(fileName):\(line)] \(message)", andLevel: level) diff --git a/Sources/Swift/Tools/SentryLogOutput.swift b/Sources/Swift/Tools/SentryLogOutput.swift index 3d704d06845..0b574dff32b 100644 --- a/Sources/Swift/Tools/SentryLogOutput.swift +++ b/Sources/Swift/Tools/SentryLogOutput.swift @@ -1,7 +1,6 @@ import Foundation -@objcMembers -class SentryLogOutput: NSObject { +class SentryLogOutput { func log(_ message: String) { print(message) } From 4a630a245f44bf086ac8201d3ef5a9134f34599c Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Tue, 30 Jul 2024 11:21:32 +0200 Subject: [PATCH 8/8] Update SentryLevelTests.swift --- Tests/SentryTests/SentryLevelTests.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/SentryTests/SentryLevelTests.swift b/Tests/SentryTests/SentryLevelTests.swift index 59d596029f1..d30a864189a 100644 --- a/Tests/SentryTests/SentryLevelTests.swift +++ b/Tests/SentryTests/SentryLevelTests.swift @@ -11,6 +11,7 @@ class SentryLevelTests: XCTestCase { XCTAssertEqual(SentryLevel.info, SentryLevel.fromName("info")) XCTAssertEqual(SentryLevel.fatal, SentryLevel.fromName("fatal")) XCTAssertEqual(SentryLevel.warning, SentryLevel.fromName("warning")) + XCTAssertEqual(SentryLevel.error, SentryLevel.fromName("invalid")) XCTAssertEqual(SentryLevel.none.description, "none") XCTAssertEqual(SentryLevel.debug.description, "debug")