Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
be66378
Flush logs when app terminates or resigns active
denrase Nov 25, 2025
fd55fdf
Merge branch 'main' into feat/flush-logs-on-app-state-change
denrase Nov 25, 2025
115a625
fix deadlock issue
denrase Nov 25, 2025
71f478e
Merge branch 'main' into feat/flush-logs-on-app-state-change
denrase Nov 26, 2025
162273e
rename group name
denrase Nov 26, 2025
3f4813d
move into existing confitional block
denrase Nov 26, 2025
aa1fbc9
Use dispatch_queue_set_specific/dispatch_get_specific to get corrrect…
denrase Nov 26, 2025
6cdd1b0
cleanup queu specific key
denrase Nov 26, 2025
8e36044
check client for nil
denrase Nov 26, 2025
d502009
Merge branch 'main' into feat/flush-logs-on-app-state-change
denrase Dec 1, 2025
d22d16e
Listen to notifications directly in integration
denrase Dec 1, 2025
539d652
move integration to swift class
denrase Dec 1, 2025
e214d5e
use dedicated queue for log batcher
denrase Dec 1, 2025
b493f18
Merge branch 'main' into feat/flush-logs-on-app-state-change
denrase Dec 1, 2025
13de622
update
denrase Dec 1, 2025
e270fa1
cleanup
denrase Dec 1, 2025
19df878
cleanup
denrase Dec 1, 2025
0f74c74
Merge branch 'main' into feat/flush-logs-on-app-state-change
denrase Dec 1, 2025
6daca9e
Merge branch 'main' into feat/flush-logs-on-app-state-change
denrase Dec 3, 2025
e3f2df8
update cl
denrase Dec 3, 2025
dd00065
fix build issue :facepalm
denrase Dec 3, 2025
f2e5b8b
update changelog
denrase Dec 3, 2025
f9a7ed8
Merge branch 'main' into feat/flush-logs-on-app-state-change
philprime Dec 3, 2025
d828f69
remove kIntegrationOptionEnableLogs
denrase Dec 3, 2025
3b22387
use dsnForTestCase
denrase Dec 3, 2025
0682b5b
update test setup
denrase Dec 3, 2025
fda13c2
Call with QOS_CLASS_DEFAULT instead of DISPATCH_QUEUE_PRIORITY_DEFAULT
denrase Dec 3, 2025
2edc82f
Merge branch 'main' into feat/flush-logs-on-app-state-change
denrase Dec 4, 2025
7a57e7a
fix incorrect import of NSApplication in macCatalyst environments
denrase Dec 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -711,11 +711,15 @@
92235CAC2E15369900865983 /* SentryLogBatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92235CAB2E15369900865983 /* SentryLogBatcher.swift */; };
92235CAE2E15549C00865983 /* SentryLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92235CAD2E15549C00865983 /* SentryLogger.swift */; };
92235CB02E155B2600865983 /* SentryLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92235CAF2E155B2600865983 /* SentryLoggerTests.swift */; };
9246A2322ED5CDA7002FA318 /* SentryLogFlushIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 9246A2312ED5CDA7002FA318 /* SentryLogFlushIntegration.h */; settings = {ATTRIBUTES = (Private, ); }; };
9246A2342ED5CDB5002FA318 /* SentryLogFlushIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 9246A2332ED5CDB5002FA318 /* SentryLogFlushIntegration.m */; };
9246A2372ED5D008002FA318 /* SentryAppStateListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9246A2362ED5D008002FA318 /* SentryAppStateListener.swift */; };
925824C22CB5897700C9B20B /* SentrySessionReplayIntegration-Hybrid.h in Headers */ = {isa = PBXBuildFile; fileRef = D80382BE2C09C6FD0090E048 /* SentrySessionReplayIntegration-Hybrid.h */; settings = {ATTRIBUTES = (Private, ); }; };
9264E1EB2E2E385E00B077CF /* SentryLogMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9264E1EA2E2E385B00B077CF /* SentryLogMessage.swift */; };
9264E1ED2E2E397C00B077CF /* SentryLogMessageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9264E1EC2E2E397400B077CF /* SentryLogMessageTests.swift */; };
92672BB629C9A2A9006B021C /* SentryBreadcrumb+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 92672BB529C9A2A9006B021C /* SentryBreadcrumb+Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
927A5CC42DD7626B00B82404 /* SentryEnvelopeItemHeaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 927A5CC32DD7626400B82404 /* SentryEnvelopeItemHeaderTests.swift */; };
927D21FB2ED5DE8A00916D31 /* SentryLogFlushIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 927D21FA2ED5DE7F00916D31 /* SentryLogFlushIntegrationTests.swift */; };
928207C42E251B8F009285A4 /* SentryScope+PrivateSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 928207C32E251B8F009285A4 /* SentryScope+PrivateSwift.h */; };
9286059529A5096600F96038 /* SentryGeo.h in Headers */ = {isa = PBXBuildFile; fileRef = 9286059429A5096600F96038 /* SentryGeo.h */; settings = {ATTRIBUTES = (Public, ); }; };
9286059729A5098900F96038 /* SentryGeo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9286059629A5098900F96038 /* SentryGeo.m */; };
Expand Down Expand Up @@ -2074,10 +2078,14 @@
92235CAB2E15369900865983 /* SentryLogBatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogBatcher.swift; sourceTree = "<group>"; };
92235CAD2E15549C00865983 /* SentryLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogger.swift; sourceTree = "<group>"; };
92235CAF2E155B2600865983 /* SentryLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLoggerTests.swift; sourceTree = "<group>"; };
9246A2312ED5CDA7002FA318 /* SentryLogFlushIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryLogFlushIntegration.h; path = include/SentryLogFlushIntegration.h; sourceTree = "<group>"; };
9246A2332ED5CDB5002FA318 /* SentryLogFlushIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryLogFlushIntegration.m; sourceTree = "<group>"; };
9246A2362ED5D008002FA318 /* SentryAppStateListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAppStateListener.swift; sourceTree = "<group>"; };
9264E1EA2E2E385B00B077CF /* SentryLogMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogMessage.swift; sourceTree = "<group>"; };
9264E1EC2E2E397400B077CF /* SentryLogMessageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogMessageTests.swift; sourceTree = "<group>"; };
92672BB529C9A2A9006B021C /* SentryBreadcrumb+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SentryBreadcrumb+Private.h"; path = "include/HybridPublic/SentryBreadcrumb+Private.h"; sourceTree = "<group>"; };
927A5CC32DD7626400B82404 /* SentryEnvelopeItemHeaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryEnvelopeItemHeaderTests.swift; sourceTree = "<group>"; };
927D21FA2ED5DE7F00916D31 /* SentryLogFlushIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogFlushIntegrationTests.swift; sourceTree = "<group>"; };
928207C32E251B8F009285A4 /* SentryScope+PrivateSwift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryScope+PrivateSwift.h"; path = "include/SentryScope+PrivateSwift.h"; sourceTree = "<group>"; };
9286059429A5096600F96038 /* SentryGeo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryGeo.h; path = Public/SentryGeo.h; sourceTree = "<group>"; };
9286059629A5098900F96038 /* SentryGeo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SentryGeo.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2939,6 +2947,7 @@
D85596EF280580BE0041FF8B /* Screenshot */,
0A9BF4E028A114690068D266 /* ViewHierarchy */,
D80CD8D52B752FD9002F710B /* SessionReplay */,
9246A22E2ED5CD59002FA318 /* Log */,
FA034AC72DD3DB4900FE3107 /* SentryIntegrationProtocol.h */,
7BA235622600B61200E12865 /* SentryInternalNotificationNames.h */,
0A2D8D5C289815EB008720F6 /* SentryBaseIntegration.h */,
Expand Down Expand Up @@ -3516,6 +3525,7 @@
7B944FA924697E9700A10721 /* Integrations */ = {
isa = PBXGroup;
children = (
927D21F42ED5DE7800916D31 /* Log */,
843FB3422D156B9900558F18 /* Feedback */,
7BF6505D292B77D100BBA5A8 /* MetricKit */,
D808FB85281AB2EF009A2A33 /* UIEvents */,
Expand Down Expand Up @@ -4196,6 +4206,33 @@
name = Transaction;
sourceTree = "<group>";
};
9246A22E2ED5CD59002FA318 /* Log */ = {
isa = PBXGroup;
children = (
9246A2312ED5CDA7002FA318 /* SentryLogFlushIntegration.h */,
9246A2332ED5CDB5002FA318 /* SentryLogFlushIntegration.m */,
);
name = Log;
sourceTree = "<group>";
};
9246A2352ED5CFDC002FA318 /* AppState */ = {
isa = PBXGroup;
children = (
FA4C32972DF7513F001D7B01 /* SentryAppState.swift */,
9246A2362ED5D008002FA318 /* SentryAppStateListener.swift */,
FA560F5A2E8C876A00F2AF7F /* SentryAppStateManager.swift */,
);
path = AppState;
sourceTree = "<group>";
};
927D21F42ED5DE7800916D31 /* Log */ = {
isa = PBXGroup;
children = (
927D21FA2ED5DE7F00916D31 /* SentryLogFlushIntegrationTests.swift */,
);
path = Log;
sourceTree = "<group>";
};
D4009EA02D77196F0007AF30 /* ViewCapture */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -4464,9 +4501,9 @@
D800942328F82E8D005D3943 /* Swift */ = {
isa = PBXGroup;
children = (
9246A2352ED5CFDC002FA318 /* AppState */,
FAAB95CC2EA18B260030A2DB /* SentryDependencyContainer.swift */,
FAAB95B92EA1633E0030A2DB /* State */,
FA560F5A2E8C876A00F2AF7F /* SentryAppStateManager.swift */,
F429D37E2E8532A300DBF387 /* Networking */,
F4FE9E062E6248BB0014FED5 /* SentryCrash */,
FABB48B22E59310D0071397E /* Transaction */,
Expand All @@ -4479,7 +4516,6 @@
D856272A2A374A6800FB8062 /* Tools */,
D8B665BB2B95F5A100BD0E7B /* module.modulemap */,
FA4C32962DF7513F001D7B00 /* SentryExperimentalOptions.swift */,
FA4C32972DF7513F001D7B01 /* SentryAppState.swift */,
FA6251FE2EB52DD700BFC967 /* SentryHub.swift */,
FA6252052EB5489B00BFC967 /* SentryClient.swift */,
FA27EC152EB9236000F2ECF7 /* Options.swift */,
Expand Down Expand Up @@ -5299,6 +5335,7 @@
7BD86EC5264A63F6005439DB /* SentrySysctlObjC.h in Headers */,
63BE85701ECEC6DE00DC44F5 /* SentryDateUtils.h in Headers */,
63FE709520DA4C1000CDBAE8 /* SentryCrashReportFilterBasic.h in Headers */,
9246A2322ED5CDA7002FA318 /* SentryLogFlushIntegration.h in Headers */,
D8B088B629C9E3FF00213258 /* SentryTracerConfiguration.h in Headers */,
7B63459D280EBA6300CFA05A /* SentryUIEventTracker.h in Headers */,
7B7D873424864C6600D2ECFF /* SentryCrashDefaultMachineContextWrapper.h in Headers */,
Expand Down Expand Up @@ -5959,6 +5996,7 @@
FA67DD042DDBD4EA00896B02 /* SwiftDescriptor.swift in Sources */,
FA67DD052DDBD4EA00896B02 /* SentrySDKLog.swift in Sources */,
FA67DD062DDBD4EA00896B02 /* SentryRedactOptions.swift in Sources */,
9246A2372ED5D008002FA318 /* SentryAppStateListener.swift in Sources */,
FA67DD072DDBD4EA00896B02 /* SentryLevel.swift in Sources */,
FA67DD082DDBD4EA00896B02 /* SentryDefaultViewRenderer.swift in Sources */,
FA67DD092DDBD4EA00896B02 /* URLSessionTaskHelper.swift in Sources */,
Expand Down Expand Up @@ -6109,6 +6147,7 @@
621F61F12BEA073A005E654F /* SentryEnabledFeaturesBuilder.swift in Sources */,
FAB007362E9EF8D3001C806A /* SentryUIViewControllerPerformanceTracker.swift in Sources */,
D88817D826D7149100BF2251 /* SentryTraceContext.m in Sources */,
9246A2342ED5CDB5002FA318 /* SentryLogFlushIntegration.m in Sources */,
D8F67B1B2BE9728600C9197B /* SentrySRDefaultBreadcrumbConverter.swift in Sources */,
8EBF870926140D37001A6853 /* SentryPerformanceTracker.m in Sources */,
D865893029D6ECA7000BE151 /* SentryCrashBinaryImageCache.c in Sources */,
Expand Down Expand Up @@ -6324,6 +6363,7 @@
7B26BBFB24C0A66D00A79CCC /* SentrySdkInfoNilTests.m in Sources */,
D4E3F35D2D4A864600F79E2B /* SentryNSDictionarySanitizeTests.swift in Sources */,
7B984A9F28E572AF001F4BEE /* CrashReport.swift in Sources */,
927D21FB2ED5DE8A00916D31 /* SentryLogFlushIntegrationTests.swift in Sources */,
D4AF00252D2E93C400F5F3D7 /* SentryNSFileManagerSwizzlingTests.m in Sources */,
D46712622DCD059900D4074A /* SentryRedactDefaultOptionsTests.swift in Sources */,
D480F9DB2DE47AF2009A0594 /* SentryScopePersistentStoreTests.swift in Sources */,
Expand Down
5 changes: 5 additions & 0 deletions SentryTestUtils/Sources/TestClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,9 @@ public class TestClient: SentryClientInternal {
captureLogInvocations.record((castLog, scope))
}
}

public var flushLogsInvocations = Invocations<Void>()
public override func flushLogs() {
flushLogsInvocations.record(())
}
}
5 changes: 5 additions & 0 deletions Sources/Sentry/SentryBaseIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ - (BOOL)shouldBeEnabledWithOptions:(SentryOptions *)options
#endif // SENTRY_HAS_UIKIT
}

if ((integrationOptions & kIntegrationOptionEnableLogs) && !options.enableLogs) {
[self logWithOptionName:@"enableLogs"];
return NO;
}

return YES;
}

Expand Down
5 changes: 5 additions & 0 deletions Sources/Sentry/SentryClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,11 @@ - (void)_swiftCaptureLog:(NSObject *)log withScope:(SentryScope *)scope
}
}

- (void)flushLogs
{
[self.logBatcher captureLogs];
}

- (void)captureLogsData:(NSData *)data with:(NSNumber *)itemCount
{
SentryEnvelopeItem *envelopeItem =
Expand Down
55 changes: 55 additions & 0 deletions Sources/Sentry/SentryLogFlushIntegration.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#import "SentryLogFlushIntegration.h"
#import "SentryClient+Private.h"
#import "SentryHub.h"
#import "SentryLogC.h"
#import "SentrySDK+Private.h"
#import "SentrySwift.h"

#if SENTRY_HAS_UIKIT

NS_ASSUME_NONNULL_BEGIN

@interface SentryLogFlushIntegration () <SentryAppStateListener>

@end

@implementation SentryLogFlushIntegration

- (BOOL)installWithOptions:(SentryOptions *)options
{
if (![super installWithOptions:options]) {
return NO;
}

[[[SentryDependencyContainer sharedInstance] appStateManager] addListener:self];

return YES;
}

- (SentryIntegrationOption)integrationOptions
{
return kIntegrationOptionEnableLogs;
}

- (void)uninstall
{
[[[SentryDependencyContainer sharedInstance] appStateManager] removeListener:self];
}

# pragma mark - SentryAppStateListener

- (void)appStateManagerWillResignActive
{
[[SentrySDKInternal.currentHub getClient] flushLogs];
}

- (void)appStateManagerWillTerminate
{
[[SentrySDKInternal.currentHub getClient] flushLogs];
}

@end

NS_ASSUME_NONNULL_END

#endif // SENTRY_HAS_UIKIT
3 changes: 2 additions & 1 deletion Sources/Sentry/SentrySDKInternal.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#if SENTRY_HAS_UIKIT
# import "SentryAppStartTrackingIntegration.h"
# import "SentryFramesTrackingIntegration.h"
# import "SentryLogFlushIntegration.h"
# import "SentryPerformanceTrackingIntegration.h"
# import "SentryScreenshotIntegration.h"
# import "SentryUIEventTrackingIntegration.h"
Expand Down Expand Up @@ -525,7 +526,7 @@ + (void)endSession
[SentryAppStartTrackingIntegration class], [SentryFramesTrackingIntegration class],
[SentryPerformanceTrackingIntegration class], [SentryUIEventTrackingIntegration class],
[SentryViewHierarchyIntegration class],
[SentryWatchdogTerminationTrackingIntegration class],
[SentryWatchdogTerminationTrackingIntegration class], [SentryLogFlushIntegration class],
#endif // SENTRY_HAS_UIKIT
#if SENTRY_TARGET_REPLAY_SUPPORTED
[SentryScreenshotIntegration class],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ typedef NS_OPTIONS(NSUInteger, SentryIntegrationOption) {
kIntegrationOptionEnableMetricKit = 1 << 17,
kIntegrationOptionEnableReplay = 1 << 18,
kIntegrationOptionStartFramesTracker = 1 << 19,
kIntegrationOptionEnableLogs = 1 << 20,
};

@class SentryOptions;
Expand Down
2 changes: 2 additions & 0 deletions Sources/Sentry/include/SentryClient+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ NS_ASSUME_NONNULL_BEGIN

- (void)_swiftCaptureLog:(NSObject *)log withScope:(SentryScope *)scope;

- (void)flushLogs;

@end

NS_ASSUME_NONNULL_END
10 changes: 10 additions & 0 deletions Sources/Sentry/include/SentryLogFlushIntegration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#import "SentryBaseIntegration.h"
#import "SentryDefines.h"

NS_ASSUME_NONNULL_BEGIN

@interface SentryLogFlushIntegration : SentryBaseIntegration

@end

NS_ASSUME_NONNULL_END
7 changes: 7 additions & 0 deletions Sources/Swift/AppState/SentryAppStateListener.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@_implementationOnly import _SentryPrivate
import Foundation

@_spi(Private) @objc public protocol SentryAppStateListener: NSObjectProtocol {
@objc optional func appStateManagerWillResignActive()
@objc optional func appStateManagerWillTerminate()
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import UIKit
#if (os(iOS) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT
private let _updateAppState: (@escaping (SentryAppState) -> Void) -> Void
private let _buildCurrentAppState: () -> SentryAppState
private let helper: SentryDefaultAppStateManager
private var helper: SentryDefaultAppStateManager?
private let listeners = NSHashTable<SentryAppStateListener>.weakObjects()
private let listenersLock = NSRecursiveLock()
#endif

init(releaseName: String?, crashWrapper: SentryCrashWrapper, fileManager: SentryFileManager?, sysctlWrapper: SentrySysctl) {
Expand Down Expand Up @@ -41,31 +43,38 @@ import UIKit
}
}
_updateAppState = updateAppState
helper = SentryDefaultAppStateManager(storeCurrent: {
super.init()

let helper = SentryDefaultAppStateManager(storeCurrent: {
fileManager?.store(buildCurrentAppState())
}, updateTerminated: {
}, updateTerminated: { [weak self] in
updateAppState { $0.wasTerminated = true }
self?.notifyListeners { $0.appStateManagerWillTerminate?() }
}, updateSDKNotRunning: {
updateAppState { $0.isSDKRunning = false }
}, updateActive: { active in
}, updateActive: { [weak self] active in
updateAppState { $0.isActive = active }
if !active {
self?.notifyListeners { $0.appStateManagerWillResignActive?() }
}
})
self.helper = helper
#endif
}

#if (os(iOS) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT
var startCount: Int {
helper.startCount
helper?.startCount ?? 0
}

@objc public func start() {
helper.start()
helper?.start()
}
@objc public func stop() {
helper.stop()
helper?.stop()
}
@objc public func stop(withForce force: Bool) {
helper.stop(withForce: force)
helper?.stop(withForce: force)
}

/**
Expand All @@ -90,5 +99,23 @@ import UIKit
@objc public func updateAppState(_ block: @escaping (SentryAppState) -> Void) {
_updateAppState(block)
}

@objc public func addListener(_ listener: SentryAppStateListener) {
listenersLock.synchronized {
listeners.add(listener)
}
}

@objc public func removeListener(_ listener: SentryAppStateListener) {
listenersLock.synchronized {
listeners.remove(listener)
}
}

@objc private func notifyListeners(_ block: @escaping (SentryAppStateListener) -> Void) {
listenersLock.synchronized {
listeners.allObjects.forEach(block)
}
}
#endif
}
13 changes: 11 additions & 2 deletions Sources/Swift/Tools/SentryLogBatcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,17 @@ import Foundation
@discardableResult
@_spi(Private) @objc public func captureLogs() -> TimeInterval {
let startTimeNs = SentryDefaultCurrentDateProvider.getAbsoluteTime()
dispatchQueue.dispatchSync { [weak self] in
self?.performCaptureLogs()

// Guard against sync call deadlock when we are already on the dispatchQueue queue.
let currentQueueLabel = String(validatingUTF8: __dispatch_queue_get_label(nil)) ?? ""
let targetQueueLabel = dispatchQueue.queue.label

if currentQueueLabel == targetQueueLabel {
performCaptureLogs()
} else {
dispatchQueue.dispatchSync { [weak self] in
self?.performCaptureLogs()
}
}
let endTimeNs = SentryDefaultCurrentDateProvider.getAbsoluteTime()
return TimeInterval(endTimeNs - startTimeNs) / 1_000_000_000.0 // Convert nanoseconds to seconds
Expand Down
Loading
Loading