We would like to add support for local scopes for the needs of downstream SDKs (sentry-unreal).
API proposal for capturing events with local scopes, inspired by other Sentry SDKs:
sentry_uuid_t sentry_capture_event_with_scope (sentry_value_t event , sentry_scope_callback_t callback , void * userdata )
Clones the current scope and pushes it on a (thread-local?) stack
Calls the scope configuration callback
typedef void (*sentry_scope_callback_t)(sentry_scope_t *scope, void *userdata)
Flushes the local scope
Captures the event
Discards the local scope
Ideally, GenericPlatformSentryScope in sentry-unreal would be a thin wrapper around an opaque sentry_scope_t*. To achieve this, sentry-native could expose getters and setters for all the data stored in the scope:
typedef struct sentry_scope_s {
char * transaction ;
sentry_value_t fingerprint ;
sentry_value_t user ;
sentry_value_t tags ;
sentry_value_t extra ;
sentry_value_t contexts ;
sentry_value_t breadcrumbs ;
sentry_level_t level ;
sentry_value_t client_sdk ;
sentry_transaction_t * transaction_object ;
sentry_span_t * span ;
} sentry_scope_t ;
transaction
const char *sentry_scope_get_transaction (const sentry_scope_t *scope);
void sentry_scope_set_transaction (sentry_scope_t *scope, const char *transaction); // + _n
fingerprint
sentry_value_t sentry_scope_get_fingerprint (const sentry_scope_t *scope);
void sentry_scope_set_fingerprint (sentry_scope_t *scope, const char *fingerprint, ...); // + _n
void sentry_scope_remove_fingerprint (sentry_scope_t *scope);
user
sentry_value_t sentry_scope_get_user (const sentry_scope_t *scope);
void sentry_scope_set_user (sentry_scope_t *scope, sentry_value_t user);
void sentry_scope_remove_user (sentry_scope_t *scope);
tags
const char *sentry_scope_get_tag (const sentry_scope_t *scope, const char *key);
void sentry_scope_set_tag (sentry_scope_t *scope, const char *key, const char *value); // + _n
void sentry_scope_remove_tag (sentry_scope_t *scope, const char *key); // + _n
sentry_value_t sentry_scope_get_tags (const sentry_scope_t *scope)
void sentry_scope_set_tags(sentry_scope_t *scope, sentry_value_t tags)
extras
sentry_value_t sentry_scope_get_extra (const sentry_scope_t *scope, const char *key);
void sentry_scope_set_extra (sentry_scope_t *scope, const char *key, sentry_value_t value); // + _n
void sentry_scope_remove_extra (sentry_scope_t *scope, const char *key); // + _n
sentry_value_t sentry_scope_get_extras (const sentry_scope_t *scope);
void sentry_scope_set_extras (sentry_scope_t *scope, sentry_value_t extras);
contexts
sentry_value_t sentry_scope_get_context (const sentry_scope_t *scope, const char *key);
void sentry_scope_set_context (sentry_scope_t *scope, const char *key, sentry_value_t value); // + _n
void sentry_scope_remove_context (sentry_scope_t *scope, const char *key); // + _n
sentry_value_t sentry_scope_get_contexts (const sentry_scope_t *scope);
void sentry_scope_set_contexts (sentry_scope_t *scope, sentry_value_t contexts);
breadcrumbs
void sentry_scope_add_breadcrumb (sentry_scope_t *scope, sentry_value_t breadcrumb);
void sentry_scope_clear_breadcrumbs (sentry_scope_t *scope);
attachments (TODO feat: Support modifying attachments after init #433 )
level
sentry_level_t sentry_scope_get_level (const sentry_scope_t *scope);
void sentry_scope_set_level (sentry_scope_t *scope, sentry_level_t level);
other
void sentry_scope_clear (sentry_scope_t *scope);
Open questions
should transaction_object and span be cloned?
add dist for FGenericPlatformSentryScope::Get/SetDist?
add environment for FGenericPlatformSentryScope::Get/SetEnvironment?
With all this in place, the implementation of CaptureEventWithScope in sentry-unreal could look something along the lines of:
TSharedPtr<ISentryId> FGenericPlatformSentrySubsystem::CaptureEventWithScope (TSharedPtr<ISentryEvent> event, const FSentryScopeDelegate& onScopeConfigure)
{
FScopeLock Lock (&CriticalSection);
sentry_value_t nativeEvent = Event->GetNativeObject ();
sentry_uuid_t id = sentry_capture_event_with_scope (nativeEvent, [](sentry_scope_t *scope, void *userdata) {
TSharedPtr<FGenericPlatformSentryScope> NewLocalScope = MakeShareable (new FGenericPlatformSentryScope (scope));
const FSentryScopeDelegate *onScopeConfigure = static_cast <const FSentryScopeDelegate *>(userdata);
onScopeConfigure->ExecuteIfBound (NewLocalScope);
}, &onScopeConfigure);
return MakeShareable (new FGenericPlatformSentryId (id));
}
We would like to add support for local scopes for the needs of downstream SDKs (sentry-unreal).
API proposal for capturing events with local scopes, inspired by other Sentry SDKs:
typedef void (*sentry_scope_callback_t)(sentry_scope_t *scope, void *userdata)Ideally, GenericPlatformSentryScope in sentry-unreal would be a thin wrapper around an opaque
sentry_scope_t*. To achieve this, sentry-native could expose getters and setters for all the data stored in the scope:Open questions
transaction_objectandspanbe cloned?adddistforFGenericPlatformSentryScope::Get/SetDist?addenvironmentforFGenericPlatformSentryScope::Get/SetEnvironment?With all this in place, the implementation of
CaptureEventWithScopein sentry-unreal could look something along the lines of: