-
-
Notifications
You must be signed in to change notification settings - Fork 53
Add traces sampling function support for Windows and Linux #1057
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
Changes from 8 commits
d670600
6672871
492dcd1
5a024ed
d12c3de
a00ae2c
6de2df9
531f9ac
53d5e92
9672dcf
3cc0841
506605b
3dc6473
5cb46d8
3cd7694
6f1dcb8
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 |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| // Copyright (c) 2025 Sentry. All Rights Reserved. | ||
|
|
||
| #include "GenericPlatformSentrySamplingContext.h" | ||
| #include "GenericPlatformSentryTransactionContext.h" | ||
|
|
||
| #include "Infrastructure/GenericPlatformSentryConverters.h" | ||
|
|
||
| #include "Convenience/GenericPlatformSentryInclude.h" | ||
|
|
||
| #if USE_SENTRY_NATIVE | ||
|
|
||
| FGenericPlatformSentrySamplingContext::FGenericPlatformSentrySamplingContext(sentry_transaction_context_t* transactionContext, sentry_value_t customSamplingContext) | ||
| { | ||
| TransactionContext = transactionContext; | ||
| CustomSamplingContext = customSamplingContext; | ||
| } | ||
|
|
||
| FGenericPlatformSentrySamplingContext::~FGenericPlatformSentrySamplingContext() | ||
| { | ||
| // Put custom destructor logic here if needed | ||
| } | ||
|
|
||
| TSharedPtr<ISentryTransactionContext> FGenericPlatformSentrySamplingContext::GetTransactionContext() const | ||
| { | ||
| return MakeShareable(new FGenericPlatformSentryTransactionContext(TransactionContext)); | ||
| } | ||
|
|
||
| TMap<FString, FSentryVariant> FGenericPlatformSentrySamplingContext::GetCustomSamplingContext() const | ||
| { | ||
| return FGenericPlatformSentryConverters::VariantToUnreal(CustomSamplingContext); | ||
| } | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // Copyright (c) 2025 Sentry. All Rights Reserved. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include "Convenience/GenericPlatformSentryInclude.h" | ||
|
|
||
| #include "Interface/SentrySamplingContextInterface.h" | ||
|
|
||
| #if USE_SENTRY_NATIVE | ||
|
|
||
| class FGenericPlatformSentrySamplingContext : public ISentrySamplingContext | ||
| { | ||
| public: | ||
| FGenericPlatformSentrySamplingContext(sentry_transaction_context_t* transactionContext, sentry_value_t customSamplingContext); | ||
| virtual ~FGenericPlatformSentrySamplingContext() override; | ||
|
|
||
| virtual TSharedPtr<ISentryTransactionContext> GetTransactionContext() const override; | ||
| virtual TMap<FString, FSentryVariant> GetCustomSamplingContext() const override; | ||
|
|
||
| private: | ||
| sentry_transaction_context_t* TransactionContext; | ||
| sentry_value_t CustomSamplingContext; | ||
| }; | ||
|
|
||
| typedef FGenericPlatformSentrySamplingContext FPlatformSentrySamplingContext; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| #include "GenericPlatformSentryEvent.h" | ||
| #include "GenericPlatformSentryFeedback.h" | ||
| #include "GenericPlatformSentryId.h" | ||
| #include "GenericPlatformSentrySamplingContext.h" | ||
| #include "GenericPlatformSentryScope.h" | ||
| #include "GenericPlatformSentryTransaction.h" | ||
| #include "GenericPlatformSentryTransactionContext.h" | ||
|
|
@@ -17,6 +18,7 @@ | |
| #include "SentryDefines.h" | ||
| #include "SentryEvent.h" | ||
| #include "SentryModule.h" | ||
| #include "SentrySamplingContext.h" | ||
| #include "SentrySettings.h" | ||
|
|
||
| #include "SentryTraceSampler.h" | ||
|
|
@@ -44,6 +46,8 @@ extern CORE_API bool GIsGPUCrashed; | |
|
|
||
| #if USE_SENTRY_NATIVE | ||
|
|
||
| static FGenericPlatformSentrySubsystem* GGenericPlatformSentrySubsystem; | ||
|
|
||
| void PrintVerboseLog(sentry_level_t level, const char* message, va_list args, void* userdata) | ||
| { | ||
| char buffer[512]; | ||
|
|
@@ -96,6 +100,18 @@ void PrintVerboseLog(sentry_level_t level, const char* message, va_list args, vo | |
| } | ||
| } | ||
|
|
||
| /* static */ double FGenericPlatformSentrySubsystem::HandleTraceSampling(const sentry_transaction_context_t* transaction_ctx, sentry_value_t custom_sampling_ctx, const int* parent_sampled) | ||
| { | ||
| if (GGenericPlatformSentrySubsystem) | ||
| { | ||
| return StaticCast<FGenericPlatformSentrySubsystem*>(GGenericPlatformSentrySubsystem)->OnTraceSampling(transaction_ctx, custom_sampling_ctx, parent_sampled); | ||
| } | ||
| else | ||
| { | ||
| return parent_sampled != nullptr ? *parent_sampled : 0.0; | ||
| } | ||
| } | ||
tustanivsky marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| sentry_value_t FGenericPlatformSentrySubsystem::OnBeforeSend(sentry_value_t event, void* hint, void* closure, bool isCrash) | ||
| { | ||
| if (!closure || this != closure) | ||
|
|
@@ -187,6 +203,42 @@ sentry_value_t FGenericPlatformSentrySubsystem::OnCrash(const sentry_ucontext_t* | |
| return OnBeforeSend(event, nullptr, closure, true); | ||
| } | ||
|
|
||
| double FGenericPlatformSentrySubsystem::OnTraceSampling(const sentry_transaction_context_t* transaction_ctx, sentry_value_t custom_sampling_ctx, const int* parent_sampled) | ||
| { | ||
| USentryTraceSampler* Sampler = GetTraceSampler(); | ||
| if (!Sampler) | ||
| { | ||
| // If custom sampler isn't set skip further processing | ||
| return parent_sampled != nullptr ? *parent_sampled : 0.0; | ||
| } | ||
|
|
||
| if (FUObjectThreadContext::Get().IsRoutingPostLoad) | ||
| { | ||
| UE_LOG(LogSentrySdk, Log, TEXT("Executing traces sampler is not allowed during object post-loading.")); | ||
| return parent_sampled != nullptr ? *parent_sampled : 0.0; | ||
| } | ||
|
|
||
| if (IsGarbageCollecting()) | ||
| { | ||
| // If traces sampling happens during garbage collection we can't instantiate UObjects safely or obtain a GC lock | ||
| // since it will cause a deadlock (see https://github.com/getsentry/sentry-unreal/issues/850). | ||
| // In this case event will be reported without calling a `beforeSend` handler. | ||
| UE_LOG(LogSentrySdk, Log, TEXT("Executing traces sampler is not allowed during garbage collection.")); | ||
| return parent_sampled != nullptr ? *parent_sampled : 0.0; | ||
| } | ||
|
|
||
| USentrySamplingContext* Context = USentrySamplingContext::Create( | ||
| MakeShareable(new FGenericPlatformSentrySamplingContext(const_cast<sentry_transaction_context_t*>(transaction_ctx), custom_sampling_ctx))); | ||
|
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. Bug:
|
||
|
|
||
| float samplingValue; | ||
| if (Sampler->Sample(Context, samplingValue)) | ||
| { | ||
| return samplingValue; | ||
| } | ||
|
|
||
| return parent_sampled != nullptr ? *parent_sampled : 0.0; | ||
| } | ||
|
|
||
| void FGenericPlatformSentrySubsystem::InitCrashReporter(const FString& release, const FString& environment) | ||
| { | ||
| crashReporter = MakeShareable(new FGenericPlatformSentryCrashReporter); | ||
|
|
@@ -233,6 +285,7 @@ void FGenericPlatformSentrySubsystem::AddByteAttachment(TSharedPtr<ISentryAttach | |
| FGenericPlatformSentrySubsystem::FGenericPlatformSentrySubsystem() | ||
| : beforeSend(nullptr) | ||
| , beforeBreadcrumb(nullptr) | ||
| , sampler(nullptr) | ||
| , crashReporter(nullptr) | ||
| , isEnabled(false) | ||
| , isStackTraceEnabled(true) | ||
|
|
@@ -244,8 +297,11 @@ FGenericPlatformSentrySubsystem::FGenericPlatformSentrySubsystem() | |
|
|
||
| void FGenericPlatformSentrySubsystem::InitWithSettings(const USentrySettings* settings, USentryBeforeSendHandler* beforeSendHandler, USentryBeforeBreadcrumbHandler* beforeBreadcrumbHandler, USentryTraceSampler* traceSampler) | ||
| { | ||
| GGenericPlatformSentrySubsystem = this; | ||
|
|
||
| beforeSend = beforeSendHandler; | ||
| beforeBreadcrumb = beforeBreadcrumbHandler; | ||
| sampler = traceSampler; | ||
|
|
||
| sentry_options_t* options = sentry_options_new(); | ||
|
|
||
|
|
@@ -290,7 +346,7 @@ void FGenericPlatformSentrySubsystem::InitWithSettings(const USentrySettings* se | |
| } | ||
| if (settings->EnableTracing && settings->SamplingType == ESentryTracesSamplingType::TracesSampler) | ||
| { | ||
| UE_LOG(LogSentrySdk, Warning, TEXT("The Native SDK doesn't currently support sampling functions")); | ||
| sentry_options_set_traces_sampler(options, HandleTraceSampling); | ||
|
Contributor
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. Can we make HandleTraceSampling non-static and forward "this" here. We could get rid of the static pointer to the class then?
Collaborator
Author
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. Unlike other Native SDK callbacks
Collaborator
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. |
||
| } | ||
|
|
||
| ConfigureHandlerPath(options); | ||
|
|
@@ -672,10 +728,17 @@ TSharedPtr<ISentryTransaction> FGenericPlatformSentrySubsystem::StartTransaction | |
| return nullptr; | ||
| } | ||
|
|
||
| TSharedPtr<ISentryTransaction> FGenericPlatformSentrySubsystem::StartTransactionWithContextAndOptions(TSharedPtr<ISentryTransactionContext> context, const TMap<FString, FString>& options) | ||
| TSharedPtr<ISentryTransaction> FGenericPlatformSentrySubsystem::StartTransactionWithContextAndOptions(TSharedPtr<ISentryTransactionContext> context, const FSentryTransactionOptions& options) | ||
| { | ||
| UE_LOG(LogSentrySdk, Log, TEXT("Transaction options currently not supported (and therefore ignored) on generic platform.")); | ||
| return StartTransactionWithContext(context); | ||
| if (TSharedPtr<FGenericPlatformSentryTransactionContext> platformTransactionContext = StaticCastSharedPtr<FGenericPlatformSentryTransactionContext>(context)) | ||
| { | ||
| if (sentry_transaction_t* nativeTransaction = sentry_transaction_start(platformTransactionContext->GetNativeObject(), FGenericPlatformSentryConverters::VariantMapToNative(options.CustomSamplingContext))) | ||
| { | ||
| return MakeShareable(new FGenericPlatformSentryTransaction(nativeTransaction)); | ||
| } | ||
| } | ||
|
|
||
| return nullptr; | ||
| } | ||
|
|
||
| TSharedPtr<ISentryTransactionContext> FGenericPlatformSentrySubsystem::ContinueTrace(const FString& sentryTrace, const TArray<FString>& baggageHeaders) | ||
|
|
@@ -699,6 +762,11 @@ USentryBeforeBreadcrumbHandler* FGenericPlatformSentrySubsystem::GetBeforeBreadc | |
| return beforeBreadcrumb; | ||
| } | ||
|
|
||
| USentryTraceSampler* FGenericPlatformSentrySubsystem::GetTraceSampler() | ||
| { | ||
| return sampler; | ||
| } | ||
|
|
||
| void FGenericPlatformSentrySubsystem::TryCaptureScreenshot() | ||
| { | ||
| const FString& ScreenshotPath = GetScreenshotPath(); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.