Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

- Add SentryDistribution as Swift Package Manager target (#6149)
- Add option `enablePropagateTraceparent` to support OTel/W3C trace propagation (#6356)
- Structured Logs: Add `captureLog` to `Hub` and `Client` (#6518)

### Fixes

Expand Down
12 changes: 8 additions & 4 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@
92235CAE2E15549C00865983 /* SentryLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92235CAD2E15549C00865983 /* SentryLogger.swift */; };
92235CB02E155B2600865983 /* SentryLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92235CAF2E155B2600865983 /* SentryLoggerTests.swift */; };
925824C22CB5897700C9B20B /* SentrySessionReplayIntegration-Hybrid.h in Headers */ = {isa = PBXBuildFile; fileRef = D80382BE2C09C6FD0090E048 /* SentrySessionReplayIntegration-Hybrid.h */; settings = {ATTRIBUTES = (Private, ); }; };
92622E092EABB71000ABE7FF /* SentryLogSPMTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92622E082EABB71000ABE7FF /* SentryLogSPMTests.swift */; };
92622E142EABBDA900ABE7FF /* SentryLog+SPM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92622E132EABBDA900ABE7FF /* SentryLog+SPM.swift */; };
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, ); }; };
Expand All @@ -734,7 +736,6 @@
92D957732E05A44600E20E66 /* SentryAsyncLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 92D957722E05A44600E20E66 /* SentryAsyncLog.m */; };
92D957772E05A4F300E20E66 /* SentryAsyncLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 92D957762E05A4F300E20E66 /* SentryAsyncLog.h */; };
92E5F3D62CDBB3BF00B7AD98 /* SentrySampling.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E8C57A525EEFC42001CEEFA /* SentrySampling.h */; };
92EC54CE2E1EB54B00A10AC2 /* SentryClient+Logs.h in Headers */ = {isa = PBXBuildFile; fileRef = 92EC54CD2E1EB54B00A10AC2 /* SentryClient+Logs.h */; };
92ECD7202E05A7DF0063EC10 /* SentryLogC.h in Headers */ = {isa = PBXBuildFile; fileRef = D8AE48B12C5786AA0092A2A6 /* SentryLogC.h */; settings = {ATTRIBUTES = (Private, ); }; };
92ECD73C2E05ACE00063EC10 /* SentryLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92ECD73B2E05ACDE0063EC10 /* SentryLog.swift */; };
92ECD73E2E05AD320063EC10 /* SentryLogLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92ECD73D2E05AD2B0063EC10 /* SentryLogLevel.swift */; };
Expand Down Expand Up @@ -2082,6 +2083,8 @@
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>"; };
92622E082EABB71000ABE7FF /* SentryLogSPMTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogSPMTests.swift; sourceTree = "<group>"; };
92622E132EABBDA900ABE7FF /* SentryLog+SPM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SentryLog+SPM.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>"; };
Expand All @@ -2095,7 +2098,6 @@
92B6BDAC2E05B9F700D538B3 /* SentryLogTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogTests.swift; sourceTree = "<group>"; };
92D957722E05A44600E20E66 /* SentryAsyncLog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryAsyncLog.m; sourceTree = "<group>"; };
92D957762E05A4F300E20E66 /* SentryAsyncLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryAsyncLog.h; path = include/SentryAsyncLog.h; sourceTree = "<group>"; };
92EC54CD2E1EB54B00A10AC2 /* SentryClient+Logs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryClient+Logs.h"; path = "include/SentryClient+Logs.h"; sourceTree = "<group>"; };
92ECD73B2E05ACDE0063EC10 /* SentryLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLog.swift; sourceTree = "<group>"; };
92ECD73D2E05AD2B0063EC10 /* SentryLogLevel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogLevel.swift; sourceTree = "<group>"; };
92ECD73F2E05AD500063EC10 /* SentryLogAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryLogAttribute.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2689,6 +2691,7 @@
84B0E0062CD963F9007FB332 /* SentryIconography.swift */,
621F61F02BEA073A005E654F /* SentryEnabledFeaturesBuilder.swift */,
F4FE9DFB2E622CD70014FED5 /* SentryDefaultObjCRuntimeWrapper.swift */,
92622E132EABBDA900ABE7FF /* SentryLog+SPM.swift */,
F4FE9DFC2E622CD70014FED5 /* SentryObjCRuntimeWrapper.swift */,
);
path = Helper;
Expand Down Expand Up @@ -3117,7 +3120,6 @@
63AA76941EB9C1C200D153DE /* SentryClient.h */,
63AA75ED1EB8B3C400D153DE /* SentryClient.m */,
7B85DC1C24EFAFCD007D01D2 /* SentryClient+Private.h */,
92EC54CD2E1EB54B00A10AC2 /* SentryClient+Logs.h */,
7B610D5E2512390E00B0B5D9 /* SentrySDK+Private.h */,
FA6555132E30181B009917BC /* SentrySDKInternal.h */,
FA6555152E30182B009917BC /* SentrySDKInternal.m */,
Expand Down Expand Up @@ -3612,6 +3614,7 @@
F4A930242E661856006DA6EF /* SentryMobileProvisionParserTests.swift */,
D4F7BD7C2E4373BB004A2D77 /* SentryLevelMapperTests.swift */,
D8AE48BE2C578D540092A2A6 /* SentrySDKLog.swift */,
92622E082EABB71000ABE7FF /* SentryLogSPMTests.swift */,
849AC3FF29E0C1FF00889C16 /* SentryFormatterTests.swift */,
7B88F30324BC8E6500ADF90A /* SentrySerializationTests.swift */,
62F4DDA02C04CB9700588890 /* SentryBaggageSerializationTests.swift */,
Expand Down Expand Up @@ -5153,7 +5156,6 @@
8E7C98312693E1CC00E6336C /* SentryTraceHeader.h in Headers */,
62C316812B1F2E93000D7031 /* SentryDelayedFramesTracker.h in Headers */,
92D957772E05A4F300E20E66 /* SentryAsyncLog.h in Headers */,
92EC54CE2E1EB54B00A10AC2 /* SentryClient+Logs.h in Headers */,
7B8713AE26415ADF006D6004 /* SentryAppStartTrackingIntegration.h in Headers */,
7B7D873224864BB900D2ECFF /* SentryCrashMachineContextWrapper.h in Headers */,
861265F92404EC1500C4AFDE /* SentryArray.h in Headers */,
Expand Down Expand Up @@ -6033,6 +6035,7 @@
7B14089824878F950035403D /* SentryCrashStackEntryMapper.m in Sources */,
D8BC28C82BFF5EBB0054DA4D /* SentryTouchTracker.swift in Sources */,
63FE711720DA4C1000CDBAE8 /* SentryCrashStackCursor_Backtrace.c in Sources */,
92622E142EABBDA900ABE7FF /* SentryLog+SPM.swift in Sources */,
FA3A42722E1C5F9B00A08C39 /* SentryNSNotificationCenterWrapper.swift in Sources */,
63FE70CB20DA4C1000CDBAE8 /* SentryCrashReportFixer.c in Sources */,
F4A930232E65FDBF006DA6EF /* SentryMobileProvisionParser.swift in Sources */,
Expand Down Expand Up @@ -6141,6 +6144,7 @@
7BE3C78724472E9800A38442 /* TestRequestManager.swift in Sources */,
63FE722220DA66EC00CDBAE8 /* SentryCrashJSONCodec_Tests.m in Sources */,
7B0A5452252311CE00A71716 /* SentryBreadcrumbTests.swift in Sources */,
92622E092EABB71000ABE7FF /* SentryLogSPMTests.swift in Sources */,
7BE3C7752445C82300A38442 /* SentryCurrentDateTests.swift in Sources */,
7B3398672459C4AE00BD9C96 /* SentryEnvelopeRateLimitTests.swift in Sources */,
8EA9AF492665AC48002771B4 /* SentryPerformanceTrackerTests.swift in Sources */,
Expand Down
6 changes: 3 additions & 3 deletions SentryTestUtils/TestClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ public class TestClient: SentryClient {
flushInvocations.record(timeout)
}

public var captureLogsDataInvocations = Invocations<(data: Data, count: NSNumber)>()
public override func captureLogsData(_ data: Data, with count: NSNumber) {
captureLogsDataInvocations.record((data, count))
public var captureLogInvocations = Invocations<(log: SentryLog, scope: Scope)>()
public override func capture(log: SentryLog, scope: Scope) {
captureLogInvocations.record((log, scope))
}
}
9 changes: 9 additions & 0 deletions Sources/Sentry/Public/SentryClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
@class SentryOptions;
@class SentryScope;
@class SentryTransaction;
@class SentryLog;

NS_ASSUME_NONNULL_BEGIN

Expand Down Expand Up @@ -101,6 +102,14 @@ SENTRY_NO_INIT
- (void)captureFeedback:(SentryFeedback *)feedback
withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(feedback:scope:));

/**
* Captures a log entry and sends it to Sentry.
* @param log The log entry to send to Sentry.
* @param scope The current scope from which to gather contextual information.
*/
- (void)captureLog:(SentryLog *)log
withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(log:scope:));

/**
* Waits synchronously for the SDK to flush out all queued and cached items for up to the specified
* timeout in seconds. If there is no internet connection, the function returns immediately. The SDK
Expand Down
15 changes: 15 additions & 0 deletions Sources/Sentry/Public/SentryHub.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
@class SentryScope;
@class SentryTransactionContext;
@class SentryUser;
@class SentryLog;

NS_ASSUME_NONNULL_BEGIN
@interface SentryHub : NSObject
Expand Down Expand Up @@ -175,6 +176,20 @@ SENTRY_NO_INIT
*/
- (void)captureFeedback:(SentryFeedback *)feedback;

/**
* Captures a log entry and sends it to Sentry.
* @param log The log entry to send to Sentry.
*/
- (void)captureLog:(SentryLog *)log NS_SWIFT_NAME(capture(log:));
Comment on lines +179 to +183
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h: The hub should offer the same methods as the static API see https://github.com/getsentry/sentry-docs/pull/15281/files


/**
* Captures a log entry and sends it to Sentry.
* @param log The log entry to send to Sentry.
* @param scope The scope containing event metadata.
*/
- (void)captureLog:(SentryLog *)log
withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(log:scope:));

/**
* Use this method to modify the Scope of the Hub. The SDK uses the Scope to attach
* contextual data to events.
Expand Down
20 changes: 17 additions & 3 deletions Sources/Sentry/SentryClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@

NS_ASSUME_NONNULL_BEGIN

@interface SentryClient ()
@interface SentryClient () <SentryLogBatcherDelegate>

@property (nonatomic, strong) SentryTransportAdapter *transportAdapter;
@property (nonatomic, strong) SentryDebugImageProvider *debugImageProvider;
@property (nonatomic, strong) id<SentryRandomProtocol> random;
@property (nonatomic, strong) NSLocale *locale;
@property (nonatomic, strong) NSTimeZone *timezone;
@property (nonatomic, strong) SentryLogBatcher *logBatcher;

@end

Expand Down Expand Up @@ -149,6 +150,10 @@ - (instancetype)initWithOptions:(SentryOptions *)options
self.locale = locale;
self.timezone = timezone;
self.attachmentProcessors = [[NSMutableArray alloc] init];
self.logBatcher = [[SentryLogBatcher alloc]
initWithOptions:options
dispatchQueue:SentryDependencyContainer.sharedInstance.dispatchQueueWrapper];
self.logBatcher.delegate = self;

// The SDK stores the installationID in a file. The first call requires file IO. To avoid
// executing this on the main thread, we cache the installationID async here.
Expand Down Expand Up @@ -654,7 +659,11 @@ - (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event

- (void)flush:(NSTimeInterval)timeout
{
[self.transportAdapter flush:timeout];
NSTimeInterval captureLogsDuration = [self.logBatcher captureLogs];
// Capturing batched logs should never take long, but we need to fall back to a sane value.
// This is a workaround for experimental logs, until we'll write batched logs to disk,
// to avoid data loss due to crashes. This is a trade-off until then.
Comment on lines +664 to +665
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: Logs aren't experimental anymore with V9. We're close to merging the develop docs PR for logs for crashes getsentry/sentry-docs#15274. Maybe we could link this PR already or create an issue for logs for crashes and link it here.

[self.transportAdapter flush:fmax(timeout / 2, timeout - captureLogsDuration)];
}

- (void)close
Expand Down Expand Up @@ -1111,7 +1120,12 @@ - (void)removeAttachmentProcessor:(id<SentryClientAttachmentProcessor>)attachmen
return processedAttachments;
}

- (void)captureLogsData:(NSData *)data with:(NSNumber *)itemCount;
- (void)captureLog:(SentryLog *)log withScope:(SentryScope *)scope
{
[self.logBatcher addLog:log scope:scope];
}

- (void)captureLogsData:(NSData *)data with:(NSNumber *)itemCount
{
SentryEnvelopeItemHeader *header =
[[SentryEnvelopeItemHeader alloc] initWithType:SentryEnvelopeItemTypes.log
Expand Down
14 changes: 14 additions & 0 deletions Sources/Sentry/SentryHub.m
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,20 @@ - (void)captureFeedback:(SentryFeedback *)feedback
}
}

- (void)captureLog:(SentryLog *)log NS_SWIFT_NAME(capture(log:))
{
[self captureLog:log withScope:self.scope];
}

- (void)captureLog:(SentryLog *)log
withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(log:scope:))
Comment on lines +534 to +540
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: I don't think we need NS_SWIFT_NAME in the .m files. Header files should be sufficient.

Suggested change
- (void)captureLog:(SentryLog *)log NS_SWIFT_NAME(capture(log:))
{
[self captureLog:log withScope:self.scope];
}
- (void)captureLog:(SentryLog *)log
withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(log:scope:))
- (void)captureLog:(SentryLog *)log
{
[self captureLog:log withScope:self.scope];
}
- (void)captureLog:(SentryLog *)log
withScope:(SentryScope *)scope

{
SentryClient *client = self.client;
if (client != nil) {
[client captureLog:log withScope:self.scope];
}
}

- (void)captureSerializedFeedback:(NSDictionary *)serializedFeedback
withEventId:(NSString *)feedbackEventId
attachments:(NSArray<SentryAttachment *> *)feedbackAttachments
Expand Down
14 changes: 0 additions & 14 deletions Sources/Sentry/include/SentryClient+Logs.h

This file was deleted.

1 change: 0 additions & 1 deletion Sources/Sentry/include/SentryPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#import "SentryANRTrackerV1.h"
#import "SentryANRTrackerV2.h"
#import "SentryAsyncLog.h"
#import "SentryClient+Logs.h"
#import "SentryContinuousProfiler.h"
#import "SentryCrash.h"
#import "SentryCrashDebug.h"
Expand Down
79 changes: 79 additions & 0 deletions Sources/Swift/Helper/SentryLog+SPM.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
@_implementationOnly import _SentryPrivate
import Foundation

// Swift extensions to provide properly typed log-related APIs for SPM builds.
// In SPM builds, SentryLog is only forward declared in the Objective-C headers,
// causing Swift-to-Objective-C bridging issues. These extensions work around that
// by providing Swift-native methods and properties that use dynamic dispatch internally.

@objc
protocol HubSelectors {
func captureLog(_ log: SentryLog)
func captureLog(_ log: SentryLog, withScope: Scope)
}

@objc
protocol ClientSelectors {
func captureLog(_ log: SentryLog, withScope: Scope)
}

#if SWIFT_PACKAGE

/**
* Use this callback to drop or modify a log before the SDK sends it to Sentry. Return `nil` to
* drop the log.
*/
public typealias SentryBeforeSendLogCallback = (SentryLog) -> SentryLog?

@objc
public extension Options {
/**
* Use this callback to drop or modify a log before the SDK sends it to Sentry. Return `nil` to
* drop the log.
*/
@objc
var beforeSendLog: SentryBeforeSendLogCallback? {
get { return value(forKey: "beforeSendLogDynamic") as? SentryBeforeSendLogCallback }
set { setValue(newValue, forKey: "beforeSendLogDynamic") }
}
}

@objc
public extension SentryHub {
/// Captures a log entry and sends it to Sentry.
/// - Parameter log: The log entry to send to Sentry.
///
/// This method is provided for SPM builds where the Objective-C `captureLog:` method
/// may not be properly bridged due to `SentryLog` being defined in Swift.
func capture(log: SentryLog) {
// Use dynamic dispatch to work around bridging limitations
perform(#selector(HubSelectors.captureLog(_:)), with: log)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we end up removing captureLog from the Hub or Client, this will break at runtime, not build time right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the compiler won't notify us. I'll add an additional check if the target responds to the selector, so we don't call it in this case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I introduced an internal helper called CaptureLogDispatch. It checks if the target responds to the selector and logs an error. Also we can tests this better.

}

/// Captures a log entry and sends it to Sentry with a specific scope.
/// - Parameters:
/// - log: The log entry to send to Sentry.
/// - scope: The scope containing event metadata.
///
/// This method is provided for SPM builds where the Objective-C `captureLog:withScope:` method
/// may not be properly bridged due to `SentryLog` being defined in Swift.
func capture(log: SentryLog, scope: Scope) {
// Use dynamic dispatch to work around bridging limitations
perform(#selector(HubSelectors.captureLog(_:withScope:)), with: log, with: scope)
}
}

/// Extension to provide log capture methods for SPM builds.
@objc
public extension SentryClient {
/// Captures a log entry and sends it to Sentry.
/// - Parameters:
/// - log: The log entry to send to Sentry.
/// - scope: The scope containing event metadata.
func captureLog(_ log: SentryLog, withScope scope: Scope) {
// Use dynamic dispatch to work around bridging limitations
perform(#selector(ClientSelectors.captureLog(_:withScope:)), with: log, with: scope)
}
}

#endif // SWIFT_PACKAGE
27 changes: 3 additions & 24 deletions Sources/Swift/Helper/SentrySDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,9 @@ import Foundation
if let _logger, _loggerConfigured {
return _logger
}
let hub = SentryDependencyContainerSwiftHelper.currentHub()
var batcher: SentryLogBatcher?
if let client = hub.getClient(), client.options.enableLogs {
batcher = SentryLogBatcher(client: client, dispatchQueue: Dependencies.dispatchQueueWrapper)
}
let logger = SentryLogger(
hub: hub,
dateProvider: Dependencies.dateProvider,
batcher: batcher
hub: SentryDependencyContainerSwiftHelper.currentHub(),
dateProvider: Dependencies.dateProvider
)
_logger = logger
_loggerConfigured = sdkEnabled
Expand Down Expand Up @@ -360,18 +354,12 @@ import Foundation
/// - note: This might take slightly longer than the specified timeout if there are many batched logs to capture.
@objc(flush:)
public static func flush(timeout: TimeInterval) {
let captureLogsDuration = captureLogs()
// Capturing batched logs should never take long, but we need to fall back to a sane value.
// This is a workaround for experimental logs, until we'll write batched logs to disk,
// to avoid data loss due to crashes. This is a trade-off until then.
SentrySDKInternal.flush(timeout: max(timeout / 2, timeout - captureLogsDuration))
SentrySDKInternal.flush(timeout: timeout)
}

/// Closes the SDK, uninstalls all the integrations, and calls `flush` with
/// `SentryOptions.shutdownTimeInterval`.
@objc public static func close() {
// Capturing batched logs should never take long, ignore the duration here.
_ = captureLogs()
SentrySDKInternal.close()
}

Expand Down Expand Up @@ -430,15 +418,6 @@ import Foundation
private static var _logger: SentryLogger?
// Flag to re-create instance if accessed before SDK init.
private static var _loggerConfigured = false

@discardableResult
private static func captureLogs() -> TimeInterval {
var duration: TimeInterval = 0.0
_loggerLock.synchronized {
duration = _logger?.captureLogs() ?? 0.0
}
return duration
}
}

extension SentryIdWrapper {
Expand Down
Loading
Loading