- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 372
          Structured Logs: Add captureLog to Hub and Client
          #6518
        
          New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 12 commits
455e640
              fe496c6
              79f488f
              0a4031e
              7a38ee2
              6f84e05
              010294f
              f376254
              f1e0dc3
              e9d6a1e
              b8be304
              e060a58
              ca30a2d
              585893a
              4d72a5d
              4533b76
              4446d9f
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -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 | ||
|  | ||
|  | @@ -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. | ||
|  | @@ -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
    
   There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
 | ||
| [self.transportAdapter flush:fmax(timeout / 2, timeout - captureLogsDuration)]; | ||
|         
                  denrase marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| } | ||
|  | ||
| - (void)close | ||
|  | @@ -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 | ||
|  | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|  | @@ -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
    
   There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
 
        Suggested change
       
 | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| SentryClient *client = self.client; | ||||||||||||||||||||||||||||||
| if (client != nil) { | ||||||||||||||||||||||||||||||
| [client captureLog:log withScope:self.scope]; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|         
                  denrase marked this conversation as resolved.
              Show resolved
            Hide resolved         
                  denrase marked this conversation as resolved.
              Show resolved
            Hide resolved | ||||||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||||||
| - (void)captureSerializedFeedback:(NSDictionary *)serializedFeedback | ||||||||||||||||||||||||||||||
| withEventId:(NSString *)feedbackEventId | ||||||||||||||||||||||||||||||
| attachments:(NSArray<SentryAttachment *> *)feedbackAttachments | ||||||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||||||
This file was deleted.
| 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) | ||
|          | ||
| } | ||
|  | ||
| /// 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 | ||
There was a problem hiding this comment.
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