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: Propagate TraceID to the Cocoa SDK #1990

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
12 changes: 12 additions & 0 deletions package-dev/Plugins/iOS/SentryNativeBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,18 @@ void SentryNativeBridgeUnsetUser()
return cString;
}

void SentryNativeBridgeSetTraceId(const char *traceId)
{
if (traceId == NULL) {
return;
}

[SentrySDK configureScope:^(SentryScope *scope) {
SentryId *sentryTraceId = [[SentryId alloc] initWithUUIDString:[NSString stringWithUTF8String:traceId]];
scope.propagationContext.traceId = sentryTraceId;
}];
}

static inline NSString *_NSStringOrNil(const char *value)
{
return value ? [NSString stringWithUTF8String:value] : nil;
Expand Down
52 changes: 50 additions & 2 deletions package-dev/Plugins/macOS/SentryNativeBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
static Class SentryUser;
static Class SentryOptions;
static Class PrivateSentrySDKOnly;
static Class SentryId;

#define LOAD_CLASS_OR_BREAK(name) \
name = (__bridge Class)dlsym(dylib, "OBJC_CLASS_$_" #name); \
Expand Down Expand Up @@ -41,6 +42,16 @@ int SentryNativeBridgeLoadLibrary()
LOAD_CLASS_OR_BREAK(SentryUser)
LOAD_CLASS_OR_BREAK(SentryOptions)
LOAD_CLASS_OR_BREAK(PrivateSentrySDKOnly)

// Try to load SentryId from Swift module
SentryId = (__bridge Class)dlsym(dylib, "OBJC_CLASS_$__TtC6Sentry8SentryId");
if (!SentryId) {
// Fallback to try the Objective-C name
SentryId = (__bridge Class)dlsym(dylib, "OBJC_CLASS_$_SentryId");
if (!SentryId) {
NSLog(@"Sentry (bridge): SentryId class not available - some features will be disabled");
}
}

// everything above passed - mark as successfully loaded
loadStatus = 1;
Expand Down Expand Up @@ -72,14 +83,23 @@ void SentryNativeBridgeOptionsSetInt(const void *options, const char *name, int3
dictOptions[[NSString stringWithUTF8String:name]] = [NSNumber numberWithInt:value];
}

void SentryNativeBridgeStartWithOptions(const void *options)
int SentryNativeBridgeStartWithOptions(const void *options)
{
NSMutableDictionary *dictOptions = (__bridge_transfer NSMutableDictionary *)options;
NSError *error = nil;

id sentryOptions = [[SentryOptions alloc]
performSelector:@selector(initWithDict:didFailWithError:)
withObject:dictOptions withObject:nil];
withObject:dictOptions
withObject:&error];

if (error != nil)
{
return 0;
}

[SentrySDK performSelector:@selector(startWithOptions:) withObject:sentryOptions];
return 1;
}

void SentryConfigureScope(void (^callback)(id))
Expand Down Expand Up @@ -255,6 +275,34 @@ void SentryNativeBridgeUnsetUser()
return cString;
}

void SentryNativeBridgeSetTraceId(const char *traceId)
{
if (traceId == NULL) {
return;
}

SentryConfigureScope(^(id scope) {
@try {
id sentryTraceId = [[SentryId alloc] performSelector:@selector(initWithUUIDString:)
withObject:[NSString stringWithUTF8String:traceId]];
[scope setValue:sentryTraceId forKeyPath:@"propagationContext.traceId"];
} @catch (NSException *exception) {
NSLog(@"Sentry (bridge): Failed to set trace ID: %@", exception.reason);
}
});

@try {
[SentrySDK performSelector:@selector(currentHub) withObject:nil];
id currentScope = [[SentrySDK performSelector:@selector(currentHub)] performSelector:@selector(scope)];
id propagationContext = [currentScope valueForKeyPath:@"propagationContext"];
id setTraceId = [propagationContext valueForKey:@"traceId"];
NSString *setTraceIdString = [setTraceId performSelector:@selector(sentryIdString)];
NSLog(@"Sentry (bridge): Verified trace ID is set to: %@", setTraceIdString);
} @catch (NSException *exception) {
NSLog(@"Sentry (bridge): Failed to verify trace ID: %@", exception.reason);
}
}

static inline NSString *_NSStringOrNil(const char *value)
{
return value ? [NSString stringWithUTF8String:value] : nil;
Expand Down
4 changes: 4 additions & 0 deletions package-dev/Runtime/SentryInitialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ public static void Init()

SentryUnity.Init(options);

#if SENTRY_NATIVE_COCOA
SentryNativeCocoa.SetTraceId(options);
#endif

#if !SENTRY_WEBGL
if (options.TracesSampleRate > 0.0f && options.AutoStartupTraces)
{
Expand Down
6 changes: 6 additions & 0 deletions src/Sentry.Unity.iOS/SentryCocoaBridgeProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ public static bool Init(SentryUnityOptions options)
options.DiagnosticLogger?.LogDebug("Setting MaxCacheItems: {0}", options.MaxCacheItems);
OptionsSetInt(cOptions, "maxCacheItems", options.MaxCacheItems);

options.DiagnosticLogger?.LogDebug("Setting TracesSampleRate: 0");
OptionsSetInt(cOptions, "tracesSampleRate", 0);

var result = StartWithOptions(cOptions);
return result is 1;
}
Expand Down Expand Up @@ -108,4 +111,7 @@ public static bool Init(SentryUnityOptions options)

[DllImport("__Internal", EntryPoint = "SentryNativeBridgeGetInstallationId")]
public static extern string GetInstallationId();

[DllImport("__Internal", EntryPoint = "SentryNativeBridgeSetTraceId")]
public static extern void SetTraceId(string? traceId);
}
17 changes: 17 additions & 0 deletions src/Sentry.Unity.iOS/SentryNativeCocoa.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,23 @@ internal static void Configure(SentryUnityOptions options, ISentryUnityInfo sent
options.DiagnosticLogger?.LogInfo("Successfully configured the native SDK");
}

public static void SetTraceId(SentryUnityOptions options)
{
options.DiagnosticLogger?.LogInfo("Setting Trace ID");

var traceId = SentrySdk.GetTraceHeader()?.TraceId;
if (traceId is null)
{
options.DiagnosticLogger?.LogInfo("fucking trace id is null");
}
else
{
options.DiagnosticLogger?.LogInfo("Setting the trace ID on the native layer {0}", traceId);

SentryCocoaBridgeProxy.SetTraceId(traceId.ToString());
}
}

/// <summary>
/// Closes the native Cocoa support.
/// </summary>
Expand Down
Loading