Skip to content
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

Feat: Add native SDK information in the replay option event #4663

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Improvements

- Add native SDK information in the replay option event (#4663)
Copy link

Choose a reason for hiding this comment

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

  • 🚫 The changelog entry seems to be part of an already released section ## 8.43.0.
    Consider moving the entry to the ## Unreleased section, please.


## 8.43.0-beta.1

### Improvements
Expand Down
23 changes: 21 additions & 2 deletions Sources/Sentry/SentryMeta.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@

@implementation SentryMeta

const NSString *const sentryVersionString = @"8.43.0-beta.1";
const NSString *const sentrySdkName = @"sentry.cocoa";

// Don't remove the static keyword. If you do the compiler adds the constant name to the global
// symbol table and it might clash with other constants. When keeping the static keyword the
// compiler replaces all occurrences with the value.
static NSString *versionString = @"8.43.0-beta.1";
static NSString *sdkName = @"sentry.cocoa";
static NSString *versionString;
static NSString *sdkName;

+ (void)initialize
{
versionString = sentryVersionString.copy;
sdkName = sentrySdkName.copy;
Comment on lines +16 to +17
Copy link
Member

Choose a reason for hiding this comment

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

m: It's a good practice to do this check to avoid getting called multiple times in case we ever subclass this, see https://developer.apple.com/documentation/objectivec/nsobject/1418639-initialize.

if (self == [SentryMeta class]) {

}

}

+ (NSString *)versionString
{
Expand All @@ -28,4 +37,14 @@ + (void)setSdkName:(NSString *)value
sdkName = value;
}

+ (NSString *)nativeSdkName
{
return sentrySdkName.copy;
}

+ (NSString *)nativeVersionString
{
return sentryVersionString.copy;
}

@end
5 changes: 5 additions & 0 deletions Sources/Sentry/SentrySessionReplayIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# import "SentryReachability.h"
# import "SentrySDK+Private.h"
# import "SentryScope+Private.h"
# import "SentrySdkInfo.h"
brustolin marked this conversation as resolved.
Show resolved Hide resolved
# import "SentrySerialization.h"
# import "SentrySessionReplaySyncC.h"
# import "SentrySwift.h"
Expand Down Expand Up @@ -50,6 +51,7 @@ @implementation SentrySessionReplayIntegration {
id<SentryRateLimits> _rateLimits;
id<SentryViewScreenshotProvider> _currentScreenshotProvider;
id<SentryReplayBreadcrumbConverter> _currentBreadcrumbConverter;
NSDictionary<NSString *, id> *_sdkInfo;
// We need to use this variable to identify whether rate limiting was ever activated for session
// replay in this session, instead of always looking for the rate status in `SentryRateLimits`
// This is the easiest way to ensure segment 0 will always reach the server, because session
Expand Down Expand Up @@ -88,6 +90,7 @@ - (void)setupWith:(SentryReplayOptions *)replayOptions enableTouchTracker:(BOOL)
_replayOptions = replayOptions;
_viewPhotographer = [[SentryViewPhotographer alloc] initWithRedactOptions:replayOptions];
_rateLimits = SentryDependencyContainer.sharedInstance.rateLimits;
_sdkInfo = replayOptions.sdkInfo;

if (touchTracker) {
_touchTracker = [[SentryTouchTracker alloc]
Expand Down Expand Up @@ -582,6 +585,8 @@ - (void)sessionReplayNewSegmentWithReplayEvent:(SentryReplayEvent *)replayEvent
return;
}

replayEvent.sdk = _sdkInfo;

[SentrySDK.currentHub captureReplayEvent:replayEvent
replayRecording:replayRecording
video:videoUrl];
Expand Down
15 changes: 15 additions & 0 deletions Sources/Sentry/include/SentryMeta.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, class, copy) NSString *sdkName;

/**
* Return a version string e.g: 1.2.3 (3)
* This always report the version of Sentry.cocoa,
* `versionString` can be changed by hybrid SDKs.
* We can use this property to get which version of Sentry cocoa
* the hybrid SDK is using.
*/
@property (nonatomic, class, readonly) NSString *nativeVersionString;

/**
* Returns "sentry.cocoa"
* `sdkName` can be changed by hybrid SDKs.
*/
@property (nonatomic, class, readonly) NSString *nativeSdkName;

@end

NS_ASSUME_NONNULL_END
1 change: 1 addition & 0 deletions Sources/Sentry/include/SentryPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#import "SentryDisplayLinkWrapper.h"
#import "SentryLevelHelper.h"
#import "SentryLogC.h"
#import "SentryMeta.h"
brustolin marked this conversation as resolved.
Show resolved Hide resolved
#import "SentryRandom.h"
#import "SentrySdkInfo.h"
#import "SentrySession.h"
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@

#if SENTRY_TARGET_REPLAY_SUPPORTED

NS_ASSUME_NONNULL_BEGIN

brustolin marked this conversation as resolved.
Show resolved Hide resolved
@class SentrySessionReplay;
@class SentryViewPhotographer;

@interface SentrySessionReplayIntegration () <SentryIntegrationProtocol, SentrySessionListener,
SentrySessionReplayDelegate>

@property (nonatomic, strong) SentrySessionReplay *sessionReplay;
@property (nonatomic, strong, nullable) SentrySessionReplay *sessionReplay;
brustolin marked this conversation as resolved.
Show resolved Hide resolved

@property (nonatomic, strong) SentryViewPhotographer *viewPhotographer;

@end

NS_ASSUME_NONNULL_END

brustolin marked this conversation as resolved.
Show resolved Hide resolved
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import Foundation
"maskAllImages": options.maskAllImages,
"quality": String(describing: options.quality),
"maskedViewClasses": options.maskedViewClasses.map(String.init(describing: )).joined(separator: ", "),
"unmaskedViewClasses": options.unmaskedViewClasses.map(String.init(describing: )).joined(separator: ", ")
"unmaskedViewClasses": options.unmaskedViewClasses.map(String.init(describing: )).joined(separator: ", "),
"nativeSdkName": SentryMeta.nativeSdkName,
"nativeSdkVersion": SentryMeta.nativeVersionString
]
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@_implementationOnly import _SentryPrivate
import Foundation

@objcMembers
Expand Down Expand Up @@ -146,6 +147,10 @@ public class SentryReplayOptions: NSObject, SentryRedactOptions {
*/
let maximumDuration = TimeInterval(3_600)

/**
* Used by hybrid SDKs to be able to configure SDK info for Session Replay
*/
var sdkInfo: [String: Any]?
Copy link
Member

Choose a reason for hiding this comment

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

m: We should set the intial value to the values of the SentryMeta.

Copy link
Member

Choose a reason for hiding this comment

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

m: We should use SentrySDKInfo here, convert it to Swift, and make it public. That's also how Android does it. Unfortunately, that's not trivial.

/**
* Inittialize session replay options disabled
*/
Expand Down Expand Up @@ -183,5 +188,6 @@ public class SentryReplayOptions: NSObject, SentryRedactOptions {
if let quality = SentryReplayQuality(rawValue: dictionary["quality"] as? Int ?? -1) {
self.quality = quality
}
sdkInfo = dictionary["sdkInfo"] as? [String: Any]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,8 @@ class SentrySessionReplayTests: XCTestCase {
XCTAssertEqual(options["maskedViewClasses"] as? String, "")
XCTAssertEqual(options["unmaskedViewClasses"] as? String, "")
XCTAssertEqual(options["quality"] as? String, "medium")
XCTAssertEqual(options["nativeSdkName"] as? String, SentryMeta.nativeSdkName)
XCTAssertEqual(options["nativeSdkVersion"] as? String, SentryMeta.nativeVersionString)
}

func testOptionsInTheEventAllChanged() throws {
Expand Down