diff --git a/CHANGELOG.md b/CHANGELOG.md index f913d3ac9..1c41e266b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - Remove custom transport implementation for Linux ([#748](https://github.com/getsentry/sentry-unreal/pull/748)) +- Refactor code to better align with Unreal's structure ([#745](https://github.com/getsentry/sentry-unreal/pull/745)) ### Fixes diff --git a/plugin-dev/Source/Sentry/Private/Android/Jni/SentryJniAndroid.cpp b/plugin-dev/Source/Sentry/Private/Android/Jni/SentryJniAndroid.cpp index ff9e198b8..eec203b8a 100644 --- a/plugin-dev/Source/Sentry/Private/Android/Jni/SentryJniAndroid.cpp +++ b/plugin-dev/Source/Sentry/Private/Android/Jni/SentryJniAndroid.cpp @@ -35,10 +35,8 @@ JNI_METHOD jobject Java_io_sentry_unreal_SentryBridgeJava_onBeforeSend(JNIEnv* e USentryBeforeSendHandler* handler = reinterpret_cast(objAddr); - USentryEvent* EventToProcess = NewObject(); - EventToProcess->InitWithNativeImpl(MakeShareable(new SentryEventAndroid(event))); - USentryHint* HintToProcess = NewObject(); - HintToProcess->InitWithNativeImpl(MakeShareable(new SentryHintAndroid(hint))); + USentryEvent* EventToProcess = USentryEvent::Create(MakeShareable(new SentryEventAndroid(event))); + USentryHint* HintToProcess = USentryHint::Create(MakeShareable(new SentryHintAndroid(hint))); return handler->HandleBeforeSend(EventToProcess, HintToProcess) ? event : nullptr; } @@ -49,8 +47,7 @@ JNI_METHOD jfloat Java_io_sentry_unreal_SentryBridgeJava_onTracesSampler(JNIEnv* USentryTraceSampler* sampler = reinterpret_cast(objAddr); - USentrySamplingContext* Context = NewObject(); - Context->InitWithNativeImpl(MakeShareable(new SentrySamplingContextAndroid(samplingContext))); + USentrySamplingContext* Context = USentrySamplingContext::Create(MakeShareable(new SentrySamplingContextAndroid(samplingContext))); float samplingValue; if(sampler->Sample(Context, samplingValue)) diff --git a/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.h b/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.h index 3926e049d..e100afed4 100644 --- a/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.h +++ b/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.h @@ -37,3 +37,5 @@ class SentrySubsystemAndroid : public ISentrySubsystem virtual TSharedPtr StartTransactionWithContextAndOptions(TSharedPtr context, const TMap& options) override; virtual TSharedPtr ContinueTrace(const FString& sentryTrace, const TArray& baggageHeaders) override; }; + +typedef SentrySubsystemAndroid FPlatformSentrySubsystem; diff --git a/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.cpp b/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.cpp index 9269b08d1..b0102731b 100644 --- a/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.cpp +++ b/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.cpp @@ -25,16 +25,16 @@ void SentryTransactionAndroid::SetupClassMethods() ToSentryTraceMethod = GetMethod("toSentryTrace", "()Lio/sentry/SentryTraceHeader;"); } -TSharedPtr SentryTransactionAndroid::StartChild(const FString& operation, const FString& desctiption) +TSharedPtr SentryTransactionAndroid::StartChildSpan(const FString& operation, const FString& desctiption) { auto span = CallObjectMethod(StartChildMethod, *GetJString(operation), *GetJString(desctiption)); return MakeShareable(new SentrySpanAndroid(*span)); } -TSharedPtr SentryTransactionAndroid::StartChildWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) +TSharedPtr SentryTransactionAndroid::StartChildSpanWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) { UE_LOG(LogSentrySdk, Log, TEXT("Starting child span with explicit timestamp not supported on Android.")); - return StartChild(operation, desctiption); + return StartChildSpan(operation, desctiption); } void SentryTransactionAndroid::Finish() diff --git a/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.h b/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.h index f7bb27f00..4d86e3a6e 100644 --- a/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.h +++ b/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.h @@ -13,8 +13,8 @@ class SentryTransactionAndroid : public ISentryTransaction, public FSentryJavaOb void SetupClassMethods(); - virtual TSharedPtr StartChild(const FString& operation, const FString& desctiption) override; - virtual TSharedPtr StartChildWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) override; + virtual TSharedPtr StartChildSpan(const FString& operation, const FString& desctiption) override; + virtual TSharedPtr StartChildSpanWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) override; virtual void Finish() override; virtual void FinishWithTimestamp(int64 timestamp) override; virtual bool IsFinished() const override; diff --git a/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.cpp b/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.cpp index 0bc5b9c11..66d6a6d98 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.cpp +++ b/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.cpp @@ -62,8 +62,7 @@ void SentrySubsystemApple::InitWithSettings(const USentrySettings* settings, USe }; options.beforeSend = ^SentryEvent* (SentryEvent* event) { FGCScopeGuard GCScopeGuard; - USentryEvent* EventToProcess = NewObject(); - EventToProcess->InitWithNativeImpl(MakeShareable(new SentryEventApple(event))); + USentryEvent* EventToProcess = USentryEvent::Create(MakeShareable(new SentryEventApple(event))); return beforeSendHandler->HandleBeforeSend(EventToProcess, nullptr) ? event : nullptr; }; for (auto it = settings->InAppInclude.CreateConstIterator(); it; ++it) @@ -83,8 +82,7 @@ void SentrySubsystemApple::InitWithSettings(const USentrySettings* settings, USe { options.tracesSampler = ^NSNumber* (SentrySamplingContext* samplingContext) { FGCScopeGuard GCScopeGuard; - USentrySamplingContext* Context = NewObject(); - Context->InitWithNativeImpl(MakeShareable(new SentrySamplingContextApple(samplingContext))); + USentrySamplingContext* Context = USentrySamplingContext::Create(MakeShareable(new SentrySamplingContextApple(samplingContext))); float samplingValue; return traceSampler->Sample(Context, samplingValue) ? [NSNumber numberWithFloat:samplingValue] : nil; }; diff --git a/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.h b/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.h index ef2144025..c87b0cbbf 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.h +++ b/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.h @@ -37,3 +37,5 @@ class SentrySubsystemApple : public ISentrySubsystem virtual TSharedPtr StartTransactionWithContextAndOptions(TSharedPtr context, const TMap& options) override; virtual TSharedPtr ContinueTrace(const FString& sentryTrace, const TArray& baggageHeaders) override; }; + +typedef SentrySubsystemApple FPlatformSentrySubsystem; diff --git a/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.cpp b/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.cpp index 2acc11a63..b73a69bc5 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.cpp +++ b/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.cpp @@ -26,16 +26,16 @@ id SentryTransactionApple::GetNativeObject() return TransactionApple; } -TSharedPtr SentryTransactionApple::StartChild(const FString& operation, const FString& desctiption) +TSharedPtr SentryTransactionApple::StartChildSpan(const FString& operation, const FString& desctiption) { id span = [TransactionApple startChildWithOperation:operation.GetNSString() description:desctiption.GetNSString()]; return MakeShareable(new SentrySpanApple(span)); } -TSharedPtr SentryTransactionApple::StartChildWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) +TSharedPtr SentryTransactionApple::StartChildSpanWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) { UE_LOG(LogSentrySdk, Log, TEXT("Starting child span with explicit timestamp not supported on Mac/iOS.")); - return StartChild(operation, desctiption); + return StartChildSpan(operation, desctiption); } void SentryTransactionApple::Finish() diff --git a/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.h b/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.h index 5b1307262..6d98556df 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.h +++ b/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.h @@ -14,8 +14,8 @@ class SentryTransactionApple : public ISentryTransaction id GetNativeObject(); - virtual TSharedPtr StartChild(const FString& operation, const FString& desctiption) override; - virtual TSharedPtr StartChildWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) override; + virtual TSharedPtr StartChildSpan(const FString& operation, const FString& desctiption) override; + virtual TSharedPtr StartChildSpanWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) override; virtual void Finish() override; virtual void FinishWithTimestamp(int64 timestamp) override; virtual bool IsFinished() const override; diff --git a/plugin-dev/Source/Sentry/Private/Core/SentryDsnUrl.h b/plugin-dev/Source/Sentry/Private/Core/SentryDsnUrl.h new file mode 100644 index 000000000..f7967ef13 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Core/SentryDsnUrl.h @@ -0,0 +1,48 @@ +// Copyright (c) 2023 Sentry. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" + +#if USE_SENTRY_NATIVE + +class FSentryDsnUrl +{ +public: + FSentryDsnUrl(const FString& Dsn) + { + FString UrlRemainder; + + Dsn.Split(TEXT("://"), &Scheme, &UrlRemainder); + UrlRemainder.Split(TEXT("@"), &Key, &UrlRemainder); + UrlRemainder.Split(TEXT("/"), &Host, &ProjectId); + } + + const FString& GetScheme() const + { + return Scheme; + } + + const FString& GetHost() const + { + return Host; + } + + const FString& GetProjectId() const + { + return ProjectId; + } + + const FString& GetKey() const + { + return Key; + } + +private: + FString Scheme; + FString Key; + FString Host; + FString ProjectId; +}; + +#endif // USE_SENTRY_NATIVE diff --git a/plugin-dev/Source/Sentry/Private/Desktop/Convenience/SentryInclude.h b/plugin-dev/Source/Sentry/Private/Desktop/Convenience/SentryInclude.h deleted file mode 100644 index a5818143c..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/Convenience/SentryInclude.h +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2022 Sentry. All Rights Reserved. - -#pragma once - -#include "HAL/Platform.h" - -#if PLATFORM_WINDOWS -#include "Windows/AllowWindowsPlatformTypes.h" -#include "sentry.h" -#include "Windows/HideWindowsPlatformTypes.h" -#elif PLATFORM_LINUX -#include "sentry.h" -#endif \ No newline at end of file diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryBreadcrumbDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentryBreadcrumbDesktop.cpp deleted file mode 100644 index 6530daba7..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryBreadcrumbDesktop.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2022 Sentry. All Rights Reserved. - -#include "SentryBreadcrumbDesktop.h" - -#include "Infrastructure/SentryConvertersDesktop.h" - -#if USE_SENTRY_NATIVE - -SentryBreadcrumbDesktop::SentryBreadcrumbDesktop() -{ - BreadcrumbDesktop = sentry_value_new_breadcrumb("", ""); -} - -SentryBreadcrumbDesktop::SentryBreadcrumbDesktop(sentry_value_t breadcrumb) -{ - BreadcrumbDesktop = breadcrumb; -} - -SentryBreadcrumbDesktop::~SentryBreadcrumbDesktop() -{ - // Put custom destructor logic here if needed -} - -sentry_value_t SentryBreadcrumbDesktop::GetNativeObject() -{ - return BreadcrumbDesktop; -} - -void SentryBreadcrumbDesktop::SetMessage(const FString& message) -{ - sentry_value_set_by_key(BreadcrumbDesktop, "message", sentry_value_new_string(TCHAR_TO_UTF8(*message))); -} - -FString SentryBreadcrumbDesktop::GetMessage() const -{ - sentry_value_t message = sentry_value_get_by_key(BreadcrumbDesktop, "message"); - return FString(sentry_value_as_string(message)); -} - -void SentryBreadcrumbDesktop::SetType(const FString& type) -{ - sentry_value_set_by_key(BreadcrumbDesktop, "type", sentry_value_new_string(TCHAR_TO_ANSI(*type))); -} - -FString SentryBreadcrumbDesktop::GetType() const -{ - sentry_value_t type = sentry_value_get_by_key(BreadcrumbDesktop, "type"); - return FString(sentry_value_as_string(type)); -} - -void SentryBreadcrumbDesktop::SetCategory(const FString& category) -{ - sentry_value_set_by_key(BreadcrumbDesktop, "category", sentry_value_new_string(TCHAR_TO_ANSI(*category))); -} - -FString SentryBreadcrumbDesktop::GetCategory() const -{ - sentry_value_t category = sentry_value_get_by_key(BreadcrumbDesktop, "category"); - return FString(sentry_value_as_string(category)); -} - -void SentryBreadcrumbDesktop::SetData(const TMap& data) -{ - sentry_value_set_by_key(BreadcrumbDesktop, "data", SentryConvertersDesktop::StringMapToNative(data)); -} - -TMap SentryBreadcrumbDesktop::GetData() const -{ - sentry_value_t data = sentry_value_get_by_key(BreadcrumbDesktop, "data"); - return SentryConvertersDesktop::StringMapToUnreal(data); -} - -void SentryBreadcrumbDesktop::SetLevel(ESentryLevel level) -{ - FString levelStr = SentryConvertersDesktop::SentryLevelToString(level); - if (!levelStr.IsEmpty()) - sentry_value_set_by_key(BreadcrumbDesktop, "level", sentry_value_new_string(TCHAR_TO_ANSI(*levelStr))); -} - -ESentryLevel SentryBreadcrumbDesktop::GetLevel() const -{ - sentry_value_t level = sentry_value_get_by_key(BreadcrumbDesktop, "level"); - return SentryConvertersDesktop::SentryLevelToUnreal(level); -} - -#endif \ No newline at end of file diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryEventDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentryEventDesktop.cpp deleted file mode 100644 index 5d3061c6b..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryEventDesktop.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2022 Sentry. All Rights Reserved. - -#include "SentryEventDesktop.h" -#include "SentryDefines.h" - -#include "Infrastructure/SentryConvertersDesktop.h" - -#if USE_SENTRY_NATIVE - -SentryEventDesktop::SentryEventDesktop() -{ - EventDesktop = sentry_value_new_event(); -} - -SentryEventDesktop::SentryEventDesktop(sentry_value_t event, bool isCrash) -{ - EventDesktop = event; - IsCrashEvent = isCrash; -} - -SentryEventDesktop::~SentryEventDesktop() -{ - // Put custom destructor logic here if needed -} - -sentry_value_t SentryEventDesktop::GetNativeObject() -{ - return EventDesktop; -} - -void SentryEventDesktop::SetMessage(const FString& message) -{ - sentry_value_t messageСontainer = sentry_value_new_object(); - sentry_value_set_by_key(messageСontainer, "formatted", sentry_value_new_string(TCHAR_TO_UTF8(*message))); - sentry_value_set_by_key(EventDesktop, "message", messageСontainer); -} - -FString SentryEventDesktop::GetMessage() const -{ - sentry_value_t messageСontainer = sentry_value_get_by_key(EventDesktop, "message"); - sentry_value_t message = sentry_value_get_by_key(messageСontainer, "formatted"); - return FString(sentry_value_as_string(message)); -} - -void SentryEventDesktop::SetLevel(ESentryLevel level) -{ - FString levelStr = SentryConvertersDesktop::SentryLevelToString(level).ToLower(); - if (!levelStr.IsEmpty()) - sentry_value_set_by_key(EventDesktop, "level", sentry_value_new_string(TCHAR_TO_ANSI(*levelStr))); -} - -ESentryLevel SentryEventDesktop::GetLevel() const -{ - sentry_value_t level = sentry_value_get_by_key(EventDesktop, "level"); - return SentryConvertersDesktop::SentryLevelToUnreal(level); -} - -bool SentryEventDesktop::IsCrash() const -{ - return IsCrashEvent; -} - -bool SentryEventDesktop::IsAnr() const -{ - // ANR error tracking is not available in `sentry-native` - return false; -} - -#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryIdDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentryIdDesktop.cpp deleted file mode 100644 index 90b196e85..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryIdDesktop.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2022 Sentry. All Rights Reserved. - -#include "SentryIdDesktop.h" - -#if USE_SENTRY_NATIVE - -SentryIdDesktop::SentryIdDesktop() -{ - IdDesktop = sentry_uuid_new_v4(); -} - -SentryIdDesktop::SentryIdDesktop(sentry_uuid_t id) -{ - IdDesktop = id; -} - -SentryIdDesktop::~SentryIdDesktop() -{ - // Put custom destructor logic here if needed -} - -sentry_uuid_t SentryIdDesktop::GetNativeObject() -{ - return IdDesktop; -} - -FString SentryIdDesktop::ToString() const -{ - char IdString[37]; - sentry_uuid_as_string(&IdDesktop, IdString); - return FString(IdString); -} - -#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryScopeDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentryScopeDesktop.cpp deleted file mode 100644 index a6d19ac67..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryScopeDesktop.cpp +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. - -#include "SentryScopeDesktop.h" -#include "SentryBreadcrumbDesktop.h" -#include "SentryEventDesktop.h" - -#include "Interface/SentryAttachmentInterface.h" - -#include "SentryModule.h" -#include "SentrySettings.h" - -#include "Infrastructure/SentryConvertersDesktop.h" - -#if USE_SENTRY_NATIVE - -SentryScopeDesktop::SentryScopeDesktop() - : LevelDesktop(ESentryLevel::Debug) -{ -} - -SentryScopeDesktop::SentryScopeDesktop(const SentryScopeDesktop& Scope) -{ - Dist = Scope.Dist; - Environment = Scope.Environment; - FingerprintDesktop = Scope.FingerprintDesktop; - TagsDesktop = Scope.TagsDesktop; - ExtraDesktop = Scope.ExtraDesktop; - ContextsDesktop = Scope.ContextsDesktop; - BreadcrumbsDesktop = TRingBuffer>(Scope.BreadcrumbsDesktop); - LevelDesktop = Scope.LevelDesktop; -} - -SentryScopeDesktop::~SentryScopeDesktop() -{ -} - -void SentryScopeDesktop::AddBreadcrumb(TSharedPtr breadcrumb) -{ - FScopeLock Lock(&CriticalSection); - - if(BreadcrumbsDesktop.Num() >= FSentryModule::Get().GetSettings()->MaxBreadcrumbs) - { - BreadcrumbsDesktop.PopFront(); - } - - BreadcrumbsDesktop.Add(StaticCastSharedPtr(breadcrumb)); -} - -void SentryScopeDesktop::ClearBreadcrumbs() -{ - FScopeLock Lock(&CriticalSection); - - BreadcrumbsDesktop.Empty(); -} - -void SentryScopeDesktop::AddAttachment(TSharedPtr attachment) -{ - // Not available for desktop -} - -void SentryScopeDesktop::ClearAttachments() -{ - // Not available for desktop -} - -void SentryScopeDesktop::SetTagValue(const FString& key, const FString& value) -{ - TagsDesktop.Add(key, value); -} - -FString SentryScopeDesktop::GetTagValue(const FString& key) const -{ - if(!TagsDesktop.Contains(key)) - return FString(); - - return TagsDesktop[key]; -} - -void SentryScopeDesktop::RemoveTag(const FString& key) -{ - TagsDesktop.Remove(key); -} - -void SentryScopeDesktop::SetTags(const TMap& tags) -{ - TagsDesktop.Append(tags); -} - -TMap SentryScopeDesktop::GetTags() const -{ - return TagsDesktop; -} - -void SentryScopeDesktop::SetDist(const FString& dist) -{ - Dist = dist; -} - -FString SentryScopeDesktop::GetDist() const -{ - return Dist; -} - -void SentryScopeDesktop::SetEnvironment(const FString& environment) -{ - Environment = environment; -} - -FString SentryScopeDesktop::GetEnvironment() const -{ - return Environment; -} - -void SentryScopeDesktop::SetFingerprint(const TArray& fingerprint) -{ - FingerprintDesktop = fingerprint; -} - -TArray SentryScopeDesktop::GetFingerprint() const -{ - return FingerprintDesktop; -} - -void SentryScopeDesktop::SetLevel(ESentryLevel level) -{ - LevelDesktop = level; -} - -ESentryLevel SentryScopeDesktop::GetLevel() const -{ - - return LevelDesktop; -} - -void SentryScopeDesktop::SetContext(const FString& key, const TMap& values) -{ - ContextsDesktop.Add(key, values); -} - -void SentryScopeDesktop::RemoveContext(const FString& key) -{ - if(!ContextsDesktop.Contains(key)) - return; - - ContextsDesktop.Remove(key); -} - -void SentryScopeDesktop::SetExtraValue(const FString& key, const FString& value) -{ - ExtraDesktop.Add(key, value); -} - -FString SentryScopeDesktop::GetExtraValue(const FString& key) const -{ - if(!ExtraDesktop.Contains(key)) - return FString(); - - return ExtraDesktop[key]; -} - -void SentryScopeDesktop::RemoveExtra(const FString& key) -{ - if(!ExtraDesktop.Contains(key)) - return; - - ExtraDesktop.Remove(key); -} - -void SentryScopeDesktop::SetExtras(const TMap& extras) -{ - ExtraDesktop.Append(extras); -} - -TMap SentryScopeDesktop::GetExtras() const -{ - return ExtraDesktop; -} - -void SentryScopeDesktop::Clear() -{ - Dist = FString(); - Environment = FString(); - FingerprintDesktop.Empty(); - TagsDesktop.Empty(); - ExtraDesktop.Empty(); - ContextsDesktop.Empty(); - BreadcrumbsDesktop.Empty(); - LevelDesktop = ESentryLevel::Debug; -} - -void SentryScopeDesktop::Apply(TSharedPtr event) -{ - sentry_value_t nativeEvent = event->GetNativeObject(); - - sentry_value_t eventLevel = sentry_value_get_by_key(nativeEvent, "level"); - - FString scopeLevelStr = SentryConvertersDesktop::SentryLevelToString(LevelDesktop).ToLower(); - if (!scopeLevelStr.IsEmpty() && sentry_value_is_null(eventLevel)) - { - sentry_value_set_by_key(nativeEvent, "level", sentry_value_new_string(TCHAR_TO_ANSI(*scopeLevelStr))); - } - - if(!Dist.IsEmpty()) - { - sentry_value_set_by_key(nativeEvent, "dist", sentry_value_new_string(TCHAR_TO_ANSI(*Dist))); - } - - if(!Environment.IsEmpty()) - { - sentry_value_set_by_key(nativeEvent, "environment", sentry_value_new_string(TCHAR_TO_ANSI(*Environment))); - } - - if(FingerprintDesktop.Num() > 0) - { - sentry_value_set_by_key(nativeEvent, "fingerprint", SentryConvertersDesktop::StringArrayToNative(FingerprintDesktop)); - } - - if(TagsDesktop.Num() > 0) - { - sentry_value_t tagsExtra = sentry_value_get_by_key(nativeEvent, "tags"); - if(sentry_value_is_null(tagsExtra)) - { - sentry_value_set_by_key(nativeEvent, "tags", SentryConvertersDesktop::StringMapToNative(TagsDesktop)); - } - else - { - for (const auto& TagItem : TagsDesktop) - { - sentry_value_set_by_key(tagsExtra, TCHAR_TO_ANSI(*TagItem.Key), sentry_value_new_string(TCHAR_TO_ANSI(*TagItem.Value))); - } - } - } - - if(ExtraDesktop.Num() > 0) - { - sentry_value_t eventExtra = sentry_value_get_by_key(nativeEvent, "extra"); - if(sentry_value_is_null(eventExtra)) - { - sentry_value_set_by_key(nativeEvent, "extra", SentryConvertersDesktop::StringMapToNative(ExtraDesktop)); - } - else - { - for (const auto& ExtraItem : ExtraDesktop) - { - sentry_value_set_by_key(eventExtra, TCHAR_TO_ANSI(*ExtraItem.Key), sentry_value_new_string(TCHAR_TO_ANSI(*ExtraItem.Value))); - } - } - - } - - if(ContextsDesktop.Num() > 0) - { - sentry_value_t eventContexts = sentry_value_get_by_key(nativeEvent, "contexts"); - if(sentry_value_is_null(eventContexts)) - { - eventContexts = sentry_value_new_object(); - - for (const auto& ContextsItem : ContextsDesktop) - { - sentry_value_set_by_key(eventContexts, TCHAR_TO_ANSI(*ContextsItem.Key), SentryConvertersDesktop::StringMapToNative(ContextsItem.Value)); - } - - sentry_value_set_by_key(nativeEvent, "contexts", eventContexts); - } - else - { - for (const auto& ContextsItem : ContextsDesktop) - { - sentry_value_set_by_key(eventContexts, TCHAR_TO_ANSI(*ContextsItem.Key), SentryConvertersDesktop::StringMapToNative(ContextsItem.Value)); - } - } - } - - if(!BreadcrumbsDesktop.IsEmpty()) - { - sentry_value_t eventBreadcrumbs = sentry_value_get_by_key(nativeEvent, "breadcrumbs"); - if(sentry_value_is_null(eventBreadcrumbs)) - { - eventBreadcrumbs = sentry_value_new_list(); - - for (const auto& Breadcrumb : BreadcrumbsDesktop) - { - sentry_value_t nativeBreadcrumb = Breadcrumb->GetNativeObject(); - sentry_value_incref(nativeBreadcrumb); - sentry_value_append(eventBreadcrumbs, nativeBreadcrumb); - } - - sentry_value_set_by_key(nativeEvent, "breadcrumbs", eventBreadcrumbs); - } - else - { - for (const auto& Breadcrumb : BreadcrumbsDesktop) - { - sentry_value_t nativeBreadcrumb = Breadcrumb->GetNativeObject(); - sentry_value_incref(nativeBreadcrumb); - sentry_value_append(eventBreadcrumbs, nativeBreadcrumb); - } - } - } -} - -#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.cpp deleted file mode 100644 index 4eb5d48a4..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. - -#include "SentrySpanDesktop.h" - -#include "Infrastructure/SentryConvertersDesktop.h" - -#if USE_SENTRY_NATIVE - -void CopySpanTracingHeader(const char *key, const char *value, void *userdata) -{ - sentry_value_t *header = static_cast(userdata); - sentry_value_set_by_key(*header, key, sentry_value_new_string(value)); -} - -SentrySpanDesktop::SentrySpanDesktop(sentry_span_t* span) - : SpanDesktop(span) - , isFinished(false) -{ -} - -SentrySpanDesktop::~SentrySpanDesktop() -{ - // Put custom destructor logic here if needed -} - -sentry_span_t* SentrySpanDesktop::GetNativeObject() -{ - return SpanDesktop; -} - -TSharedPtr SentrySpanDesktop::StartChild(const FString& operation, const FString& desctiption) -{ - sentry_span_t* nativeSpan = sentry_span_start_child(SpanDesktop, TCHAR_TO_ANSI(*operation), TCHAR_TO_ANSI(*desctiption)); - return MakeShareable(new SentrySpanDesktop(nativeSpan)); -} - -TSharedPtr SentrySpanDesktop::StartChildWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) -{ - sentry_span_t* nativeSpan = sentry_span_start_child_ts(SpanDesktop, TCHAR_TO_ANSI(*operation), TCHAR_TO_ANSI(*desctiption), timestamp); - return MakeShareable(new SentrySpanDesktop(nativeSpan)); -} - -void SentrySpanDesktop::Finish() -{ - sentry_span_finish(SpanDesktop); - - isFinished = true; -} - -void SentrySpanDesktop::FinishWithTimestamp(int64 timestamp) -{ - sentry_span_finish_ts(SpanDesktop, timestamp); - - isFinished = true; -} - -bool SentrySpanDesktop::IsFinished() const -{ - return isFinished; -} - -void SentrySpanDesktop::SetTag(const FString& key, const FString& value) -{ - FScopeLock Lock(&CriticalSection); - - sentry_span_set_tag(SpanDesktop, TCHAR_TO_ANSI(*key), TCHAR_TO_ANSI(*value)); -} - -void SentrySpanDesktop::RemoveTag(const FString& key) -{ - FScopeLock Lock(&CriticalSection); - - sentry_span_remove_tag(SpanDesktop, TCHAR_TO_ANSI(*key)); -} - -void SentrySpanDesktop::SetData(const FString& key, const TMap& values) -{ - FScopeLock Lock(&CriticalSection); - - sentry_span_set_data(SpanDesktop, TCHAR_TO_ANSI(*key), SentryConvertersDesktop::StringMapToNative(values)); -} - -void SentrySpanDesktop::RemoveData(const FString& key) -{ - FScopeLock Lock(&CriticalSection); - - sentry_span_remove_data(SpanDesktop, TCHAR_TO_ANSI(*key)); -} - -void SentrySpanDesktop::GetTrace(FString& name, FString& value) -{ - sentry_value_t tracingHeader = sentry_value_new_object(); - - sentry_span_iter_headers(SpanDesktop, CopySpanTracingHeader, &tracingHeader); - - name = TEXT("sentry-trace"); - value = FString(sentry_value_as_string(sentry_value_get_by_key(tracingHeader, "sentry-trace"))); - - sentry_value_decref(tracingHeader); -} - -#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.cpp deleted file mode 100644 index e14fee0c3..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.cpp +++ /dev/null @@ -1,637 +0,0 @@ -// Copyright (c) 2022 Sentry. All Rights Reserved. - -#include "SentrySubsystemDesktop.h" -#include "SentryEventDesktop.h" -#include "SentryBreadcrumbDesktop.h" -#include "SentryUserDesktop.h" -#include "SentryUserFeedbackDesktop.h" -#include "SentryScopeDesktop.h" -#include "SentryTransactionDesktop.h" -#include "SentryTransactionContextDesktop.h" -#include "SentryIdDesktop.h" - -#include "SentryDefines.h" -#include "SentrySettings.h" -#include "SentryEvent.h" -#include "SentryModule.h" -#include "SentryBeforeSendHandler.h" - -#include "SentryTraceSampler.h" - -#include "Utils/SentryFileUtils.h" -#include "Utils/SentryLogUtils.h" -#include "Utils/SentryScreenshotUtils.h" - -#include "Infrastructure/SentryConvertersDesktop.h" - -#include "CrashReporter/SentryCrashReporter.h" -#include "CrashReporter/SentryCrashContext.h" - -#include "Misc/Paths.h" -#include "Misc/ScopeLock.h" -#include "Misc/CoreDelegates.h" -#include "HAL/FileManager.h" -#include "Misc/EngineVersionComparison.h" -#include "GenericPlatform/GenericPlatformOutputDevices.h" -#include "GenericPlatform/GenericPlatformCrashContext.h" -#include "HAL/ExceptionHandling.h" -#include "UObject/GarbageCollection.h" -#include "UObject/UObjectThreadContext.h" - -#if PLATFORM_WINDOWS -#include "Windows/WindowsPlatformMisc.h" -#include "Windows/WindowsPlatformCrashContext.h" -#endif - -extern CORE_API bool GIsGPUCrashed; - -#if USE_SENTRY_NATIVE - -void PrintVerboseLog(sentry_level_t level, const char *message, va_list args, void *userdata) -{ - char buffer[512]; - vsnprintf(buffer, 512, message, args); - - FString MessageBuf = FString(buffer); - - // The WER (Windows Error Reporting) module (crashpad_wer.dll) can't be distributed along with other Sentry binaries - // within the plugin package due to some UE Marketplace restrictions. Its absence doesn't affect crash capturing - // and the corresponding warning can be disregarded - if(MessageBuf.Equals(TEXT("crashpad WER handler module not found"))) - { - return; - } - -#if !NO_LOGGING - const FName SentryCategoryName(LogSentrySdk.GetCategoryName()); -#else - const FName SentryCategoryName(TEXT("LogSentrySdk")); -#endif - - GLog->CategorizedLogf(SentryCategoryName, SentryConvertersDesktop::SentryLevelToLogVerbosity(level), TEXT("%s"), *MessageBuf); -} - -void PrintCrashLog(const sentry_ucontext_t *uctx) -{ -#if PLATFORM_WINDOWS && !UE_VERSION_OLDER_THAN(5, 0, 0) - - SentryConvertersDesktop::SentryCrashContextToString(uctx, GErrorExceptionDescription, UE_ARRAY_COUNT(GErrorExceptionDescription)); - - const SIZE_T StackTraceSize = 65535; - ANSICHAR* StackTrace = (ANSICHAR*)GMalloc->Malloc(StackTraceSize); - StackTrace[0] = 0; - - // Currently raw crash data stored in `uctx` can be utilized for stalk walking on Windows only - void* ProgramCounter = uctx->exception_ptrs.ExceptionRecord->ExceptionAddress; - - FPlatformStackWalk::StackWalkAndDump(StackTrace, StackTraceSize, ProgramCounter); - - FCString::Strncat(GErrorHist, GErrorExceptionDescription, UE_ARRAY_COUNT(GErrorHist)); - FCString::Strncat(GErrorHist, TEXT("\r\n\r\n"), UE_ARRAY_COUNT(GErrorHist)); - FCString::Strncat(GErrorHist, ANSI_TO_TCHAR(StackTrace), UE_ARRAY_COUNT(GErrorHist)); - -#if !NO_LOGGING - FDebug::LogFormattedMessageWithCallstack(LogSentrySdk.GetCategoryName(), __FILE__, __LINE__, TEXT("=== Critical error: ==="), GErrorHist, ELogVerbosity::Error); -#endif - -#if !UE_VERSION_OLDER_THAN(5, 1, 0) - GLog->Panic(); -#endif - - GMalloc->Free(StackTrace); - -#endif -} - -sentry_value_t HandleBeforeSend(sentry_value_t event, void *hint, void *closure) -{ - SentrySubsystemDesktop* SentrySubsystem = static_cast(closure); - - TSharedPtr eventDesktop = MakeShareable(new SentryEventDesktop(event)); - - SentrySubsystem->GetCurrentScope()->Apply(eventDesktop); - - FGCScopeGuard GCScopeGuard; - - USentryEvent* EventToProcess = NewObject(); - EventToProcess->InitWithNativeImpl(eventDesktop); - - USentryEvent* ProcessedEvent = EventToProcess; - if(!FUObjectThreadContext::Get().IsRoutingPostLoad) - { - // Executing UFUNCTION is allowed only when not post-loading - ProcessedEvent = SentrySubsystem->GetBeforeSendHandler()->HandleBeforeSend(EventToProcess, nullptr); - } - - return ProcessedEvent ? event : sentry_value_new_null(); -} - -sentry_value_t HandleBeforeCrash(const sentry_ucontext_t *uctx, sentry_value_t event, void *closure) -{ -#if PLATFORM_WINDOWS - // Ensures that error message and corresponding callstack flushed to a log file (if available) - // before it's attached to the captured crash event and uploaded to Sentry. - PrintCrashLog(uctx); -#endif - - SentrySubsystemDesktop* SentrySubsystem = static_cast(closure); - SentrySubsystem->TryCaptureScreenshot(); - - if (GIsGPUCrashed) - { - IFileManager::Get().Copy(*SentrySubsystem->GetGpuDumpBackupPath(), *SentryFileUtils::GetGpuDumpPath()); - } - - FSentryCrashContext::Get()->Apply(SentrySubsystem->GetCurrentScope()); - - TSharedPtr eventDesktop = MakeShareable(new SentryEventDesktop(event, true)); - - SentrySubsystem->GetCurrentScope()->Apply(eventDesktop); - - if(!IsGarbageCollecting()) - { - USentryEvent* EventToProcess = NewObject(); - EventToProcess->InitWithNativeImpl(eventDesktop); - - USentryEvent* ProcessedEvent = EventToProcess; - if(!FUObjectThreadContext::Get().IsRoutingPostLoad) - { - // Executing UFUNCTION is allowed only when not post-loading - ProcessedEvent = SentrySubsystem->GetBeforeSendHandler()->HandleBeforeSend(EventToProcess, nullptr); - } - - return ProcessedEvent ? event : sentry_value_new_null(); - } - else - { - // If crash occured during garbage collection we can't just obtain a GC lock like with normal events - // since there is no guarantee it will be ever freed. In this case crash event will be reported - // without calling a `beforeSend` handler. - return event; - } -} - -SentrySubsystemDesktop::SentrySubsystemDesktop() - : beforeSend(nullptr) - , crashReporter(MakeShareable(new SentryCrashReporter)) - , isEnabled(false) - , isStackTraceEnabled(true) - , isScreenshotAttachmentEnabled(false) -{ -} - -void SentrySubsystemDesktop::InitWithSettings(const USentrySettings* settings, USentryBeforeSendHandler* beforeSendHandler, USentryTraceSampler* traceSampler) -{ - beforeSend = beforeSendHandler; - - scopeStack.Push(MakeShareable(new SentryScopeDesktop())); - - sentry_options_t* options = sentry_options_new(); - - if(settings->EnableAutoLogAttachment) - { - const FString LogFilePath = FGenericPlatformOutputDevices::GetAbsoluteLogFilename(); - -#if PLATFORM_WINDOWS - sentry_options_add_attachmentw(options, *FPaths::ConvertRelativePathToFull(LogFilePath)); -#elif PLATFORM_LINUX - sentry_options_add_attachment(options, TCHAR_TO_UTF8(*FPaths::ConvertRelativePathToFull(LogFilePath))); -#endif - } - - switch (settings->DatabaseLocation) - { - case ESentryDatabaseLocation::ProjectDirectory: - databaseParentPath = FPaths::ProjectDir(); - break; - case ESentryDatabaseLocation::ProjectUserDirectory: - databaseParentPath = FPaths::ProjectUserDir(); - break; - } - - if(databaseParentPath.IsEmpty()) - { - UE_LOG(LogSentrySdk, Warning, TEXT("Unknown Sentry database location. Falling back to FPaths::ProjectUserDir().")); - databaseParentPath = FPaths::ProjectUserDir(); - } - - if(settings->AttachScreenshot) - { - isScreenshotAttachmentEnabled = true; - -#if PLATFORM_WINDOWS - sentry_options_add_attachmentw(options, *GetScreenshotPath()); -#elif PLATFORM_LINUX - sentry_options_add_attachment(options, TCHAR_TO_UTF8(*GetScreenshotPath())); -#endif - } - - if (settings->AttachGpuDump) - { -#if PLATFORM_WINDOWS - sentry_options_add_attachmentw(options, *GetGpuDumpBackupPath()); -#elif PLATFORM_LINUX - sentry_options_add_attachment(options, TCHAR_TO_UTF8(*GetGpuDumpBackupPath())); -#endif - } - - if(settings->UseProxy) - { - sentry_options_set_http_proxy(options, TCHAR_TO_ANSI(*settings->ProxyUrl)); - } - - if(settings->EnableTracing && settings->SamplingType == ESentryTracesSamplingType::UniformSampleRate) - { - sentry_options_set_traces_sample_rate(options, settings->TracesSampleRate); - } - if(settings->EnableTracing && settings->SamplingType == ESentryTracesSamplingType::TracesSampler) - { - UE_LOG(LogSentrySdk, Warning, TEXT("The Native SDK doesn't currently support sampling functions")); - } - -#if PLATFORM_WINDOWS - if(!FSentryModule::Get().IsMarketplaceVersion()) - { - const FString HandlerPath = GetHandlerPath(); - - if(!FPaths::FileExists(HandlerPath)) - { - UE_LOG(LogSentrySdk, Log, TEXT("Crashpad executable couldn't be found so Breakpad will be used instead. " - "Please make sure that the plugin was rebuilt to avoid initialization failure.")); - } - - sentry_options_set_handler_pathw(options, *HandlerPath); - } -#elif PLATFORM_LINUX - sentry_options_set_handler_path(options, TCHAR_TO_UTF8(*GetHandlerPath())); -#endif - -#if PLATFORM_WINDOWS - sentry_options_set_database_pathw(options, *GetDatabasePath()); -#elif PLATFORM_LINUX - sentry_options_set_database_path(options, TCHAR_TO_UTF8(*GetDatabasePath())); -#endif - - sentry_options_set_release(options, TCHAR_TO_ANSI(settings->OverrideReleaseName - ? *settings->Release - : *settings->GetFormattedReleaseName())); - - sentry_options_set_dsn(options, TCHAR_TO_ANSI(*settings->Dsn)); - sentry_options_set_environment(options, TCHAR_TO_ANSI(*settings->Environment)); - sentry_options_set_logger(options, PrintVerboseLog, nullptr); - sentry_options_set_debug(options, settings->Debug); - sentry_options_set_auto_session_tracking(options, settings->EnableAutoSessionTracking); - sentry_options_set_sample_rate(options, settings->SampleRate); - sentry_options_set_max_breadcrumbs(options, settings->MaxBreadcrumbs); - sentry_options_set_before_send(options, HandleBeforeSend, this); - sentry_options_set_on_crash(options, HandleBeforeCrash, this); - sentry_options_set_shutdown_timeout(options, 3000); - - int initResult = sentry_init(options); - - UE_LOG(LogSentrySdk, Log, TEXT("Sentry initialization completed with result %d (0 on success)."), initResult); - - isEnabled = initResult == 0 ? true : false; - - sentry_clear_crashed_last_run(); - -#if PLATFORM_WINDOWS && !UE_VERSION_OLDER_THAN(5, 2, 0) - FPlatformMisc::SetCrashHandlingType(settings->EnableAutoCrashCapturing - ? ECrashHandlingType::Disabled - : ECrashHandlingType::Default); -#endif - - isStackTraceEnabled = settings->AttachStacktrace; - - crashReporter->SetRelease(settings->Release); - crashReporter->SetEnvironment(settings->Environment); -} - -void SentrySubsystemDesktop::Close() -{ - isEnabled = false; - - sentry_close(); - - scopeStack.Empty(); -} - -bool SentrySubsystemDesktop::IsEnabled() -{ - return isEnabled; -} - -ESentryCrashedLastRun SentrySubsystemDesktop::IsCrashedLastRun() -{ - ESentryCrashedLastRun unrealIsCrashed = ESentryCrashedLastRun::NotEvaluated; - - switch (sentry_get_crashed_last_run()) - { - case -1: - unrealIsCrashed = ESentryCrashedLastRun::NotEvaluated; - break; - case 0: - unrealIsCrashed = ESentryCrashedLastRun::NotCrashed; - break; - case 1: - unrealIsCrashed = ESentryCrashedLastRun::Crashed; - break; - default: - UE_LOG(LogSentrySdk, Warning, TEXT("Unknown IsCrashedLastRun result. NotEvaluated will be returned.")); - } - - return unrealIsCrashed; -} - -void SentrySubsystemDesktop::AddBreadcrumb(TSharedPtr breadcrumb) -{ - GetCurrentScope()->AddBreadcrumb(breadcrumb); -} - -void SentrySubsystemDesktop::AddBreadcrumbWithParams(const FString& Message, const FString& Category, const FString& Type, const TMap& Data, ESentryLevel Level) -{ - TSharedPtr breadcrumbDesktop = MakeShareable(new SentryBreadcrumbDesktop()); - breadcrumbDesktop->SetMessage(Message); - breadcrumbDesktop->SetCategory(Category); - breadcrumbDesktop->SetType(Type); - breadcrumbDesktop->SetData(Data); - breadcrumbDesktop->SetLevel(Level); - - GetCurrentScope()->AddBreadcrumb(breadcrumbDesktop); -} - -void SentrySubsystemDesktop::ClearBreadcrumbs() -{ - GetCurrentScope()->ClearBreadcrumbs(); -} - -TSharedPtr SentrySubsystemDesktop::CaptureMessage(const FString& message, ESentryLevel level) -{ - sentry_value_t sentryEvent = sentry_value_new_message_event(SentryConvertersDesktop::SentryLevelToNative(level), nullptr, TCHAR_TO_UTF8(*message)); - - if(isStackTraceEnabled) - { - sentry_value_set_stacktrace(sentryEvent, nullptr, 0); - } - - sentry_uuid_t id = sentry_capture_event(sentryEvent); - return MakeShareable(new SentryIdDesktop(id)); -} - -TSharedPtr SentrySubsystemDesktop::CaptureMessageWithScope(const FString& message, const FSentryScopeDelegate& onScopeConfigure, ESentryLevel level) -{ - FScopeLock Lock(&CriticalSection); - - TSharedPtr NewLocalScope = MakeShareable(new SentryScopeDesktop(*GetCurrentScope())); - - onScopeConfigure.ExecuteIfBound(NewLocalScope); - - scopeStack.Push(NewLocalScope); - TSharedPtr Id = CaptureMessage(message, level); - scopeStack.Pop(); - - return Id; -} - -TSharedPtr SentrySubsystemDesktop::CaptureEvent(TSharedPtr event) -{ - TSharedPtr eventDesktop = StaticCastSharedPtr(event); - - sentry_value_t nativeEvent = eventDesktop->GetNativeObject(); - - if(isStackTraceEnabled) - { - sentry_value_set_stacktrace(nativeEvent, nullptr, 0); - } - - sentry_uuid_t id = sentry_capture_event(nativeEvent); - return MakeShareable(new SentryIdDesktop(id)); -} - -TSharedPtr SentrySubsystemDesktop::CaptureEventWithScope(TSharedPtr event, const FSentryScopeDelegate& onScopeConfigure) -{ - FScopeLock Lock(&CriticalSection); - - TSharedPtr NewLocalScope = MakeShareable(new SentryScopeDesktop(*GetCurrentScope())); - - onScopeConfigure.ExecuteIfBound(NewLocalScope); - - scopeStack.Push(NewLocalScope); - TSharedPtr Id = CaptureEvent(event); - scopeStack.Pop(); - - return Id; -} - -TSharedPtr SentrySubsystemDesktop::CaptureException(const FString& type, const FString& message, int32 framesToSkip) -{ - sentry_value_t exceptionEvent = sentry_value_new_event(); - - auto StackFrames = FGenericPlatformStackWalk::GetStack(framesToSkip); - sentry_value_set_by_key(exceptionEvent, "stacktrace", SentryConvertersDesktop::CallstackToNative(StackFrames)); - - sentry_value_t nativeException = sentry_value_new_exception(TCHAR_TO_ANSI(*type), TCHAR_TO_ANSI(*message)); - sentry_event_add_exception(exceptionEvent, nativeException); - - sentry_uuid_t id = sentry_capture_event(exceptionEvent); - return MakeShareable(new SentryIdDesktop(id)); -} - -TSharedPtr SentrySubsystemDesktop::CaptureAssertion(const FString& type, const FString& message) -{ -#if PLATFORM_WINDOWS - int32 framesToSkip = 7; -#else - int32 framesToSkip = 5; -#endif - - SentryLogUtils::LogStackTrace(*message, ELogVerbosity::Error, framesToSkip); - - return CaptureException(type, message, framesToSkip); -} - -TSharedPtr SentrySubsystemDesktop::CaptureEnsure(const FString& type, const FString& message) -{ -#if PLATFORM_WINDOWS && !UE_VERSION_OLDER_THAN(5, 3, 0) - int32 framesToSkip = 8; -#else - int32 framesToSkip = 7; -#endif - return CaptureException(type, message, framesToSkip); -} - -void SentrySubsystemDesktop::CaptureUserFeedback(TSharedPtr userFeedback) -{ - TSharedPtr userFeedbackDesktop = StaticCastSharedPtr(userFeedback); - sentry_capture_user_feedback(userFeedbackDesktop->GetNativeObject()); -} - -void SentrySubsystemDesktop::SetUser(TSharedPtr user) -{ - TSharedPtr userDesktop = StaticCastSharedPtr(user); - sentry_set_user(userDesktop->GetNativeObject()); - - crashReporter->SetUser(userDesktop); -} - -void SentrySubsystemDesktop::RemoveUser() -{ - sentry_remove_user(); - - crashReporter->RemoveUser(); -} - -void SentrySubsystemDesktop::ConfigureScope(const FSentryScopeDelegate& onConfigureScope) -{ - onConfigureScope.ExecuteIfBound(GetCurrentScope()); -} - -void SentrySubsystemDesktop::SetContext(const FString& key, const TMap& values) -{ - GetCurrentScope()->SetContext(key, values); - - crashReporter->SetContext(key, values); -} - -void SentrySubsystemDesktop::SetTag(const FString& key, const FString& value) -{ - GetCurrentScope()->SetTagValue(key, value); - - crashReporter->SetTag(key, value); -} - -void SentrySubsystemDesktop::RemoveTag(const FString& key) -{ - GetCurrentScope()->RemoveTag(key); - - crashReporter->RemoveTag(key); -} - -void SentrySubsystemDesktop::SetLevel(ESentryLevel level) -{ - GetCurrentScope()->SetLevel(level); -} - -void SentrySubsystemDesktop::StartSession() -{ - sentry_start_session(); -} - -void SentrySubsystemDesktop::EndSession() -{ - sentry_end_session(); -} - -TSharedPtr SentrySubsystemDesktop::StartTransaction(const FString& name, const FString& operation) -{ - sentry_transaction_context_t* transactionContext = sentry_transaction_context_new(TCHAR_TO_ANSI(*name), TCHAR_TO_ANSI(*operation)); - - sentry_transaction_t* nativeTransaction = sentry_transaction_start(transactionContext, sentry_value_new_null()); - - return MakeShareable(new SentryTransactionDesktop(nativeTransaction)); -} - -TSharedPtr SentrySubsystemDesktop::StartTransactionWithContext(TSharedPtr context) -{ - TSharedPtr transactionContextDesktop = StaticCastSharedPtr(context); - - sentry_transaction_t* nativeTransaction = sentry_transaction_start(transactionContextDesktop->GetNativeObject(), sentry_value_new_null()); - - return MakeShareable(new SentryTransactionDesktop(nativeTransaction)); -} - -TSharedPtr SentrySubsystemDesktop::StartTransactionWithContextAndTimestamp(TSharedPtr context, int64 timestamp) -{ - TSharedPtr transactionContextDesktop = StaticCastSharedPtr(context); - - sentry_transaction_t* nativeTransaction = sentry_transaction_start_ts(transactionContextDesktop->GetNativeObject(), sentry_value_new_null(), timestamp); - - return MakeShareable(new SentryTransactionDesktop(nativeTransaction)); -} - -TSharedPtr SentrySubsystemDesktop::StartTransactionWithContextAndOptions(TSharedPtr context, const TMap& options) -{ - UE_LOG(LogSentrySdk, Log, TEXT("Transaction options currently not supported on desktop.")); - return StartTransactionWithContext(context); -} - -TSharedPtr SentrySubsystemDesktop::ContinueTrace(const FString& sentryTrace, const TArray& baggageHeaders) -{ - sentry_transaction_context_t* nativeTransactionContext = sentry_transaction_context_new("", "default"); - sentry_transaction_context_update_from_header(nativeTransactionContext, "sentry-trace", TCHAR_TO_ANSI(*sentryTrace)); - - // currently `sentry-native` doesn't have API for `sentry_transaction_context_t` to set `baggageHeaders` - - TSharedPtr transactionContextDesktop = MakeShareable(new SentryTransactionContextDesktop(nativeTransactionContext)); - - return transactionContextDesktop; -} - -USentryBeforeSendHandler* SentrySubsystemDesktop::GetBeforeSendHandler() -{ - return beforeSend; -} - -void SentrySubsystemDesktop::TryCaptureScreenshot() const -{ - if(!isScreenshotAttachmentEnabled) - { - UE_LOG(LogSentrySdk, Log, TEXT("Screenshot attachment is disabled in plugin settings.")); - return; - } - - SentryScreenshotUtils::CaptureScreenshot(GetScreenshotPath()); -} - -FString SentrySubsystemDesktop::GetGpuDumpBackupPath() const -{ - static const FString DateTimeString = FDateTime::Now().ToString(); - - const FString GpuDumpPath = FPaths::Combine(GetDatabasePath(), TEXT("gpudumps"), *FString::Printf(TEXT("UEAftermath-%s.nv-gpudmp"), *DateTimeString));; - const FString GpuDumpFullPath = FPaths::ConvertRelativePathToFull(GpuDumpPath); - - return GpuDumpFullPath; -} - -TSharedPtr SentrySubsystemDesktop::GetCurrentScope() -{ - if(scopeStack.Num() == 0) - { - UE_LOG(LogSentrySdk, Warning, TEXT("Scope stack is empty.")); - return nullptr; - } - - return scopeStack.Top(); -} - -FString SentrySubsystemDesktop::GetHandlerPath() const -{ -#if PLATFORM_WINDOWS - const FString HandlerExecutableName = TEXT("crashpad_handler.exe"); -#elif PLATFORM_LINUX - const FString HandlerExecutableName = TEXT("crashpad_handler"); -#endif - - const FString HandlerPath = FPaths::Combine(FSentryModule::Get().GetBinariesPath(), HandlerExecutableName); - const FString HandlerFullPath = FPaths::ConvertRelativePathToFull(HandlerPath); - - return HandlerFullPath; -} - -FString SentrySubsystemDesktop::GetDatabasePath() const -{ - const FString DatabasePath = FPaths::Combine(databaseParentPath, TEXT(".sentry-native")); - const FString DatabaseFullPath = FPaths::ConvertRelativePathToFull(DatabasePath); - - return DatabaseFullPath; -} - -FString SentrySubsystemDesktop::GetScreenshotPath() const -{ - const FString ScreenshotPath = FPaths::Combine(GetDatabasePath(), TEXT("screenshots"), TEXT("crash_screenshot.png")); - const FString ScreenshotFullPath = FPaths::ConvertRelativePathToFull(ScreenshotPath); - - return ScreenshotFullPath; -} - -#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionContextDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionContextDesktop.cpp deleted file mode 100644 index e70f434a1..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionContextDesktop.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2024 Sentry. All Rights Reserved. - -#include "SentryTransactionContextDesktop.h" - -#include "SentryDefines.h" - -#if USE_SENTRY_NATIVE - -SentryTransactionContextDesktop::SentryTransactionContextDesktop(const FString& name, const FString& operation) - : TransactionContextDesktop(sentry_transaction_context_new(TCHAR_TO_ANSI(*name), TCHAR_TO_ANSI(*operation))) -{ -} - -SentryTransactionContextDesktop::SentryTransactionContextDesktop(sentry_transaction_context_t* context) - : TransactionContextDesktop(context) -{ -} - -SentryTransactionContextDesktop::~SentryTransactionContextDesktop() -{ - // Put custom destructor logic here if needed -} - -FString SentryTransactionContextDesktop::GetName() const -{ - // no corresponding implementation in sentry-native - UE_LOG(LogSentrySdk, Warning, TEXT("The native SDK doesn't currently support transaction's context GetName function")); - return FString(); -} - -FString SentryTransactionContextDesktop::GetOperation() const -{ - // no corresponding implementation in sentry-native - UE_LOG(LogSentrySdk, Warning, TEXT("The native SDK doesn't currently support transaction's context GetOperation function")); - return FString(); -} - -sentry_transaction_context_t* SentryTransactionContextDesktop::GetNativeObject() -{ - return TransactionContextDesktop; -} - -#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionContextDesktop.h b/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionContextDesktop.h deleted file mode 100644 index fd1a41907..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionContextDesktop.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2024 Sentry. All Rights Reserved. - -#pragma once - -#include "Convenience/SentryInclude.h" - -#include "Interface/SentryTransactionContextInterface.h" - -#if USE_SENTRY_NATIVE - -class SentryTransactionContextDesktop : public ISentryTransactionContext -{ -public: - SentryTransactionContextDesktop(const FString& name, const FString& operation); - SentryTransactionContextDesktop(sentry_transaction_context_t* context); - virtual ~SentryTransactionContextDesktop() override; - - virtual FString GetName() const override; - virtual FString GetOperation() const override; - - sentry_transaction_context_t* GetNativeObject(); - -private: - sentry_transaction_context_t* TransactionContextDesktop; -}; - -#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.cpp deleted file mode 100644 index 0d5f9abb0..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. - -#include "SentryTransactionDesktop.h" -#include "SentrySpanDesktop.h" - -#include "Infrastructure/SentryConvertersDesktop.h" - -#if USE_SENTRY_NATIVE - -void CopyTransactionTracingHeader(const char *key, const char *value, void *userdata) -{ - sentry_value_t *header = static_cast(userdata); - sentry_value_set_by_key(*header, key, sentry_value_new_string(value)); -} - -SentryTransactionDesktop::SentryTransactionDesktop(sentry_transaction_t* transaction) - : TransactionDesktop(transaction) - , isFinished(false) -{ -} - -SentryTransactionDesktop::~SentryTransactionDesktop() -{ -} - -sentry_transaction_t* SentryTransactionDesktop::GetNativeObject() -{ - return TransactionDesktop; -} - -TSharedPtr SentryTransactionDesktop::StartChild(const FString& operation, const FString& desctiption) -{ - sentry_span_t* nativeSpan = sentry_transaction_start_child(TransactionDesktop, TCHAR_TO_ANSI(*operation), TCHAR_TO_ANSI(*desctiption)); - return MakeShareable(new SentrySpanDesktop(nativeSpan)); -} - -TSharedPtr SentryTransactionDesktop::StartChildWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) -{ - sentry_span_t* nativeSpan = sentry_transaction_start_child_ts(TransactionDesktop, TCHAR_TO_ANSI(*operation), TCHAR_TO_ANSI(*desctiption), timestamp); - return MakeShareable(new SentrySpanDesktop(nativeSpan)); -} - -void SentryTransactionDesktop::Finish() -{ - sentry_transaction_finish(TransactionDesktop); - - isFinished = true; -} - -void SentryTransactionDesktop::FinishWithTimestamp(int64 timestamp) -{ - sentry_transaction_finish_ts(TransactionDesktop, timestamp); - - isFinished = true; -} - -bool SentryTransactionDesktop::IsFinished() const -{ - return isFinished; -} - -void SentryTransactionDesktop::SetName(const FString& name) -{ - FScopeLock Lock(&CriticalSection); - - sentry_transaction_set_name(TransactionDesktop, TCHAR_TO_ANSI(*name)); -} - -void SentryTransactionDesktop::SetTag(const FString& key, const FString& value) -{ - FScopeLock Lock(&CriticalSection); - - sentry_transaction_set_tag(TransactionDesktop, TCHAR_TO_ANSI(*key), TCHAR_TO_ANSI(*value)); -} - -void SentryTransactionDesktop::RemoveTag(const FString& key) -{ - FScopeLock Lock(&CriticalSection); - - sentry_transaction_remove_tag(TransactionDesktop, TCHAR_TO_ANSI(*key)); -} - -void SentryTransactionDesktop::SetData(const FString& key, const TMap& values) -{ - FScopeLock Lock(&CriticalSection); - - sentry_transaction_set_data(TransactionDesktop, TCHAR_TO_ANSI(*key), SentryConvertersDesktop::StringMapToNative(values)); -} - -void SentryTransactionDesktop::RemoveData(const FString& key) -{ - FScopeLock Lock(&CriticalSection); - - sentry_transaction_remove_data(TransactionDesktop, TCHAR_TO_ANSI(*key)); -} - -void SentryTransactionDesktop::GetTrace(FString& name, FString& value) -{ - sentry_value_t tracingHeader = sentry_value_new_object(); - - sentry_transaction_iter_headers(TransactionDesktop, CopyTransactionTracingHeader, &tracingHeader); - - name = TEXT("sentry-trace"); - value = FString(sentry_value_as_string(sentry_value_get_by_key(tracingHeader, "sentry-trace"))); - - sentry_value_decref(tracingHeader); -} - -#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryUserDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentryUserDesktop.cpp deleted file mode 100644 index 407e2f06f..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryUserDesktop.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2022 Sentry. All Rights Reserved. - -#include "SentryUserDesktop.h" - -#include "Infrastructure/SentryConvertersDesktop.h" - -#if USE_SENTRY_NATIVE - -SentryUserDesktop::SentryUserDesktop() -{ - UserDesktop = sentry_value_new_object(); - - // Due to backwards compatibility concerns it is more reliable to initialize IP address explicitly with a specific value or "{{auto}}" - sentry_value_set_by_key(UserDesktop, "ip_address", sentry_value_new_string("{{auto}}")); -} - -SentryUserDesktop::SentryUserDesktop(sentry_value_t user) -{ - UserDesktop = user; -} - -SentryUserDesktop::~SentryUserDesktop() -{ - // Put custom destructor logic here if needed -} - -sentry_value_t SentryUserDesktop::GetNativeObject() -{ - return UserDesktop; -} - -void SentryUserDesktop::SetEmail(const FString& email) -{ - sentry_value_set_by_key(UserDesktop, "email", sentry_value_new_string(TCHAR_TO_ANSI(*email))); -} - -FString SentryUserDesktop::GetEmail() const -{ - sentry_value_t email = sentry_value_get_by_key(UserDesktop, "email"); - return FString(sentry_value_as_string(email)); -} - -void SentryUserDesktop::SetId(const FString& id) -{ - sentry_value_set_by_key(UserDesktop, "id", sentry_value_new_string(TCHAR_TO_ANSI(*id))); -} - -FString SentryUserDesktop::GetId() const -{ - sentry_value_t id = sentry_value_get_by_key(UserDesktop, "id"); - return FString(sentry_value_as_string(id)); -} - -void SentryUserDesktop::SetUsername(const FString& username) -{ - sentry_value_set_by_key(UserDesktop, "username", sentry_value_new_string(TCHAR_TO_ANSI(*username))); -} - -FString SentryUserDesktop::GetUsername() const -{ - sentry_value_t username = sentry_value_get_by_key(UserDesktop, "username"); - return FString(sentry_value_as_string(username)); -} - -void SentryUserDesktop::SetIpAddress(const FString& ipAddress) -{ - if(!ipAddress.IsEmpty()) - { - sentry_value_set_by_key(UserDesktop, "ip_address", sentry_value_new_string(TCHAR_TO_ANSI(*ipAddress))); - } - else - { - sentry_value_set_by_key(UserDesktop, "ip_address", sentry_value_new_string("{{auto}}")); - } -} - -FString SentryUserDesktop::GetIpAddress() const -{ - sentry_value_t ip_address = sentry_value_get_by_key(UserDesktop, "ip_address"); - return FString(sentry_value_as_string(ip_address)); -} - -void SentryUserDesktop::SetData(const TMap& data) -{ - sentry_value_set_by_key(UserDesktop, "data", SentryConvertersDesktop::StringMapToNative(data)); -} - -TMap SentryUserDesktop::GetData() -{ - sentry_value_t data = sentry_value_get_by_key(UserDesktop, "data"); - return SentryConvertersDesktop::StringMapToUnreal(data); -} - -#endif \ No newline at end of file diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryUserFeedbackDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentryUserFeedbackDesktop.cpp deleted file mode 100644 index 6d051eadc..000000000 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryUserFeedbackDesktop.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2022 Sentry. All Rights Reserved. - -#include "SentryUserFeedbackDesktop.h" - -#include "SentryIdDesktop.h" - -#include "Infrastructure/SentryConvertersDesktop.h" - -#if USE_SENTRY_NATIVE - -SentryUserFeedbackDesktop::SentryUserFeedbackDesktop() -{ - UserFeedbackDesktop = sentry_value_new_object(); -} - -SentryUserFeedbackDesktop::SentryUserFeedbackDesktop(TSharedPtr eventId) -{ - UserFeedbackDesktop = sentry_value_new_object(); - sentry_value_set_by_key(UserFeedbackDesktop, "event_id", sentry_value_new_string(TCHAR_TO_ANSI(*eventId->ToString()))); -} - -SentryUserFeedbackDesktop::~SentryUserFeedbackDesktop() -{ - // Put custom destructor logic here if needed -} - -sentry_value_t SentryUserFeedbackDesktop::GetNativeObject() -{ - return UserFeedbackDesktop; -} - -void SentryUserFeedbackDesktop::SetName(const FString& name) -{ - sentry_value_set_by_key(UserFeedbackDesktop, "name", sentry_value_new_string(TCHAR_TO_UTF8(*name))); -} - -FString SentryUserFeedbackDesktop::GetName() const -{ - sentry_value_t username = sentry_value_get_by_key(UserFeedbackDesktop, "name"); - return FString(sentry_value_as_string(username)); -} - -void SentryUserFeedbackDesktop::SetEmail(const FString& email) -{ - sentry_value_set_by_key(UserFeedbackDesktop, "email", sentry_value_new_string(TCHAR_TO_ANSI(*email))); -} - -FString SentryUserFeedbackDesktop::GetEmail() const -{ - sentry_value_t email = sentry_value_get_by_key(UserFeedbackDesktop, "email"); - return FString(sentry_value_as_string(email)); -} - -void SentryUserFeedbackDesktop::SetComment(const FString& comment) -{ - sentry_value_set_by_key(UserFeedbackDesktop, "comments", sentry_value_new_string(TCHAR_TO_UTF8(*comment))); -} - -FString SentryUserFeedbackDesktop::GetComment() const -{ - sentry_value_t comment = sentry_value_get_by_key(UserFeedbackDesktop, "comments"); - return FString(sentry_value_as_string(comment)); -} - -#endif \ No newline at end of file diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/Convenience/SentryInclude.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/Convenience/SentryInclude.h new file mode 100644 index 000000000..6573741ae --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/Convenience/SentryInclude.h @@ -0,0 +1,13 @@ +// Copyright (c) 2022 Sentry. All Rights Reserved. + +#pragma once + +#include "HAL/Platform.h" + +#if PLATFORM_WINDOWS +#include "Microsoft/WindowsHWrapper.h" +#endif // PLATFORM_WINDOWS + +#if USE_SENTRY_NATIVE +#include "sentry.h" +#endif // USE_SENTRY_NATIVE diff --git a/plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashContext.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.cpp similarity index 83% rename from plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashContext.cpp rename to plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.cpp index a4bceb49e..5ef27a37b 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashContext.cpp +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.cpp @@ -1,15 +1,15 @@ // Copyright (c) 2023 Sentry. All Rights Reserved. -#include "SentryCrashContext.h" +#include "GenericPlatformSentryCrashContext.h" #include "SentrySettings.h" #include "SentryModule.h" -#include "Desktop/SentryScopeDesktop.h" - #if USE_SENTRY_NATIVE -FSentryCrashContext::FSentryCrashContext(TSharedPtr Context) +#include "GenericPlatform/GenericPlatformSentryScope.h" + +FGenericPlatformSentryCrashContext::FGenericPlatformSentryCrashContext(TSharedPtr Context) #if UE_VERSION_OLDER_THAN(5, 3, 0) : FGenericCrashContext(Context->CrashType, Context->ErrorMessage) , CrashContext(Context) @@ -19,15 +19,15 @@ FSentryCrashContext::FSentryCrashContext(TSharedPtr Context { } -TSharedPtr FSentryCrashContext::Get() +TSharedPtr FGenericPlatformSentryCrashContext::Get() { TSharedPtr SharedCrashContext = MakeShareable(new FSharedCrashContext); FGenericCrashContext::CopySharedCrashContext(*SharedCrashContext); - return MakeShareable(new FSentryCrashContext(SharedCrashContext)); + return MakeShareable(new FGenericPlatformSentryCrashContext(SharedCrashContext)); } -void FSentryCrashContext::Apply(TSharedPtr Scope) +void FGenericPlatformSentryCrashContext::Apply(TSharedPtr Scope) { const USentrySettings* Settings = FSentryModule::Get().GetSettings(); @@ -64,7 +64,7 @@ void FSentryCrashContext::Apply(TSharedPtr Scope) Scope->SetContext(TEXT("Crash Info"), ContextValues); } -FString FSentryCrashContext::GetGameData(const FString& Key) +FString FGenericPlatformSentryCrashContext::GetGameData(const FString& Key) { const FString* GameDataItem; diff --git a/plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashContext.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.h similarity index 54% rename from plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashContext.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.h index 2bc831c0a..0a22884cd 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashContext.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.h @@ -9,20 +9,20 @@ #if USE_SENTRY_NATIVE -class SentryScopeDesktop; +class ISentryScope; #if UE_VERSION_OLDER_THAN(5, 3, 0) -struct FSentryCrashContext : public FGenericCrashContext +struct FGenericPlatformSentryCrashContext : public FGenericCrashContext #else -struct FSentryCrashContext +struct FGenericPlatformSentryCrashContext #endif { - FSentryCrashContext(TSharedPtr Context); + FGenericPlatformSentryCrashContext(TSharedPtr Context); public: - static TSharedPtr Get(); + static TSharedPtr Get(); - void Apply(TSharedPtr Scope); + void Apply(TSharedPtr Scope); FString GetGameData(const FString& Key); diff --git a/plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashReporter.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.cpp similarity index 75% rename from plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashReporter.cpp rename to plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.cpp index d2fccd1f0..e4b512603 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashReporter.cpp +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.cpp @@ -1,24 +1,22 @@ // Copyright (c) 2022 Sentry. All Rights Reserved. -#include "SentryCrashReporter.h" -#include "SentryCrashContext.h" +#include "GenericPlatformSentryCrashReporter.h" -#include "Desktop/SentryUserDesktop.h" +#include "GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.h" +#include "GenericPlatform/GenericPlatformSentryUser.h" #include "SentryDefines.h" #include "Dom/JsonObject.h" #include "Serialization/JsonSerializer.h" -#include "GenericPlatform/GenericPlatformCrashContext.h" - #if USE_SENTRY_NATIVE -SentryCrashReporter::SentryCrashReporter() +FGenericPlatformSentryCrashReporter::FGenericPlatformSentryCrashReporter() { crashReporterConfig = MakeShareable(new FJsonObject); - const FString sentryData = FSentryCrashContext::Get()->GetGameData(TEXT("__sentry")); + const FString sentryData = FGenericPlatformSentryCrashContext::Get()->GetGameData(TEXT("__sentry")); if(!sentryData.IsEmpty()) { const TSharedRef> jsonReader = TJsonReaderFactory<>::Create(*sentryData); @@ -29,7 +27,7 @@ SentryCrashReporter::SentryCrashReporter() } } -void SentryCrashReporter::SetRelease(const FString& release) +void FGenericPlatformSentryCrashReporter::SetRelease(const FString& release) { if (!release.IsEmpty()) crashReporterConfig->SetStringField(TEXT("release"), release); @@ -37,7 +35,7 @@ void SentryCrashReporter::SetRelease(const FString& release) UpdateCrashReporterConfig(); } -void SentryCrashReporter::SetEnvironment(const FString& environment) +void FGenericPlatformSentryCrashReporter::SetEnvironment(const FString& environment) { if (!environment.IsEmpty()) crashReporterConfig->SetStringField(TEXT("environment"), environment); @@ -45,7 +43,7 @@ void SentryCrashReporter::SetEnvironment(const FString& environment) UpdateCrashReporterConfig(); } -void SentryCrashReporter::SetUser(TSharedPtr user) +void FGenericPlatformSentryCrashReporter::SetUser(TSharedPtr user) { TSharedPtr userConfig = MakeShareable(new FJsonObject); userConfig->SetStringField(TEXT("email"), user->GetEmail()); @@ -65,14 +63,14 @@ void SentryCrashReporter::SetUser(TSharedPtr user) UpdateCrashReporterConfig(); } -void SentryCrashReporter::RemoveUser() +void FGenericPlatformSentryCrashReporter::RemoveUser() { crashReporterConfig->RemoveField(TEXT("user")); UpdateCrashReporterConfig(); } -void SentryCrashReporter::SetContext(const FString& key, const TMap& values) +void FGenericPlatformSentryCrashReporter::SetContext(const FString& key, const TMap& values) { TSharedPtr valuesConfig = MakeShareable(new FJsonObject); @@ -100,7 +98,7 @@ void SentryCrashReporter::SetContext(const FString& key, const TMap tagsConfig; @@ -119,7 +117,7 @@ void SentryCrashReporter::SetTag(const FString& key, const FString& value) UpdateCrashReporterConfig(); } -void SentryCrashReporter::RemoveTag(const FString& key) +void FGenericPlatformSentryCrashReporter::RemoveTag(const FString& key) { TSharedPtr tagsConfig; @@ -132,7 +130,7 @@ void SentryCrashReporter::RemoveTag(const FString& key) UpdateCrashReporterConfig(); } -void SentryCrashReporter::UpdateCrashReporterConfig() +void FGenericPlatformSentryCrashReporter::UpdateCrashReporterConfig() { FString config; TSharedRef> jsonWriter = TJsonWriterFactory<>::Create(&config); diff --git a/plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashReporter.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.h similarity index 75% rename from plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashReporter.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.h index e68c5ea09..159cc4ee6 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/CrashReporter/SentryCrashReporter.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.h @@ -6,18 +6,18 @@ #if USE_SENTRY_NATIVE -class SentryUserDesktop; +class FGenericPlatformSentryUser; class FJsonObject; -class SentryCrashReporter +class FGenericPlatformSentryCrashReporter { public: - SentryCrashReporter(); + FGenericPlatformSentryCrashReporter(); void SetRelease(const FString& release); void SetEnvironment(const FString& environment); - void SetUser(TSharedPtr user); + void SetUser(TSharedPtr user); void RemoveUser(); void SetContext(const FString& key, const TMap& values); void SetTag(const FString& key, const FString& value); diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryBreadcrumb.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryBreadcrumb.cpp new file mode 100644 index 000000000..319b76e62 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryBreadcrumb.cpp @@ -0,0 +1,81 @@ +// Copyright (c) 2022 Sentry. All Rights Reserved. + +#include "GenericPlatformSentryBreadcrumb.h" + +#include "Infrastructure/GenericPlatformSentryConverters.h" + +#if USE_SENTRY_NATIVE + +FGenericPlatformSentryBreadcrumb::FGenericPlatformSentryBreadcrumb() +{ + Breadcrumb = sentry_value_new_breadcrumb("", ""); +} + +FGenericPlatformSentryBreadcrumb::FGenericPlatformSentryBreadcrumb(sentry_value_t breadcrumb) +{ + Breadcrumb = breadcrumb; +} + +sentry_value_t FGenericPlatformSentryBreadcrumb::GetNativeObject() +{ + return Breadcrumb; +} + +void FGenericPlatformSentryBreadcrumb::SetMessage(const FString& message) +{ + sentry_value_set_by_key(Breadcrumb, "message", sentry_value_new_string(TCHAR_TO_UTF8(*message))); +} + +FString FGenericPlatformSentryBreadcrumb::GetMessage() const +{ + sentry_value_t message = sentry_value_get_by_key(Breadcrumb, "message"); + return FString(sentry_value_as_string(message)); +} + +void FGenericPlatformSentryBreadcrumb::SetType(const FString& type) +{ + sentry_value_set_by_key(Breadcrumb, "type", sentry_value_new_string(TCHAR_TO_ANSI(*type))); +} + +FString FGenericPlatformSentryBreadcrumb::GetType() const +{ + sentry_value_t type = sentry_value_get_by_key(Breadcrumb, "type"); + return FString(sentry_value_as_string(type)); +} + +void FGenericPlatformSentryBreadcrumb::SetCategory(const FString& category) +{ + sentry_value_set_by_key(Breadcrumb, "category", sentry_value_new_string(TCHAR_TO_ANSI(*category))); +} + +FString FGenericPlatformSentryBreadcrumb::GetCategory() const +{ + sentry_value_t category = sentry_value_get_by_key(Breadcrumb, "category"); + return FString(sentry_value_as_string(category)); +} + +void FGenericPlatformSentryBreadcrumb::SetData(const TMap& data) +{ + sentry_value_set_by_key(Breadcrumb, "data", FGenericPlatformSentryConverters::StringMapToNative(data)); +} + +TMap FGenericPlatformSentryBreadcrumb::GetData() const +{ + sentry_value_t data = sentry_value_get_by_key(Breadcrumb, "data"); + return FGenericPlatformSentryConverters::StringMapToUnreal(data); +} + +void FGenericPlatformSentryBreadcrumb::SetLevel(ESentryLevel level) +{ + FString levelStr = FGenericPlatformSentryConverters::SentryLevelToString(level); + if (!levelStr.IsEmpty()) + sentry_value_set_by_key(Breadcrumb, "level", sentry_value_new_string(TCHAR_TO_ANSI(*levelStr))); +} + +ESentryLevel FGenericPlatformSentryBreadcrumb::GetLevel() const +{ + sentry_value_t level = sentry_value_get_by_key(Breadcrumb, "level"); + return FGenericPlatformSentryConverters::SentryLevelToUnreal(level); +} + +#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryBreadcrumbDesktop.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryBreadcrumb.h similarity index 75% rename from plugin-dev/Source/Sentry/Private/Desktop/SentryBreadcrumbDesktop.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryBreadcrumb.h index e050f9b9e..744ed7ec5 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryBreadcrumbDesktop.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryBreadcrumb.h @@ -8,12 +8,12 @@ #if USE_SENTRY_NATIVE -class SentryBreadcrumbDesktop : public ISentryBreadcrumb +class FGenericPlatformSentryBreadcrumb : public ISentryBreadcrumb { public: - SentryBreadcrumbDesktop(); - SentryBreadcrumbDesktop(sentry_value_t breadcrumb); - virtual ~SentryBreadcrumbDesktop() override; + FGenericPlatformSentryBreadcrumb(); + FGenericPlatformSentryBreadcrumb(sentry_value_t breadcrumb); + virtual ~FGenericPlatformSentryBreadcrumb() override = default; sentry_value_t GetNativeObject(); @@ -29,7 +29,7 @@ class SentryBreadcrumbDesktop : public ISentryBreadcrumb virtual ESentryLevel GetLevel() const override; private: - sentry_value_t BreadcrumbDesktop; + sentry_value_t Breadcrumb; }; #endif diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.cpp new file mode 100644 index 000000000..e2ecf1056 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.cpp @@ -0,0 +1,69 @@ +// Copyright (c) 2022 Sentry. All Rights Reserved. + +#include "GenericPlatformSentryEvent.h" +#include "SentryDefines.h" + +#include "Infrastructure/GenericPlatformSentryConverters.h" + +#if USE_SENTRY_NATIVE + +FGenericPlatformSentryEvent::FGenericPlatformSentryEvent() +{ + Event = sentry_value_new_event(); +} + +FGenericPlatformSentryEvent::FGenericPlatformSentryEvent(sentry_value_t event, bool isCrash) +{ + Event = event; + IsCrashEvent = isCrash; +} + +FGenericPlatformSentryEvent::~FGenericPlatformSentryEvent() +{ + // Put custom destructor logic here if needed +} + +sentry_value_t FGenericPlatformSentryEvent::GetNativeObject() +{ + return Event; +} + +void FGenericPlatformSentryEvent::SetMessage(const FString& message) +{ + sentry_value_t messageСontainer = sentry_value_new_object(); + sentry_value_set_by_key(messageСontainer, "formatted", sentry_value_new_string(TCHAR_TO_UTF8(*message))); + sentry_value_set_by_key(Event, "message", messageСontainer); +} + +FString FGenericPlatformSentryEvent::GetMessage() const +{ + sentry_value_t messageСontainer = sentry_value_get_by_key(Event, "message"); + sentry_value_t message = sentry_value_get_by_key(messageСontainer, "formatted"); + return FString(sentry_value_as_string(message)); +} + +void FGenericPlatformSentryEvent::SetLevel(ESentryLevel level) +{ + FString levelStr = FGenericPlatformSentryConverters::SentryLevelToString(level).ToLower(); + if (!levelStr.IsEmpty()) + sentry_value_set_by_key(Event, "level", sentry_value_new_string(TCHAR_TO_ANSI(*levelStr))); +} + +ESentryLevel FGenericPlatformSentryEvent::GetLevel() const +{ + sentry_value_t level = sentry_value_get_by_key(Event, "level"); + return FGenericPlatformSentryConverters::SentryLevelToUnreal(level); +} + +bool FGenericPlatformSentryEvent::IsCrash() const +{ + return IsCrashEvent; +} + +bool FGenericPlatformSentryEvent::IsAnr() const +{ + // ANR error tracking is not available in `sentry-native` + return false; +} + +#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryEventDesktop.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.h similarity index 69% rename from plugin-dev/Source/Sentry/Private/Desktop/SentryEventDesktop.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.h index 3946b0a01..88d2a8a4f 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryEventDesktop.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.h @@ -8,12 +8,12 @@ #if USE_SENTRY_NATIVE -class SentryEventDesktop : public ISentryEvent +class FGenericPlatformSentryEvent : public ISentryEvent { public: - SentryEventDesktop(); - SentryEventDesktop(sentry_value_t event, bool isCrash = false); - virtual ~SentryEventDesktop() override; + FGenericPlatformSentryEvent(); + FGenericPlatformSentryEvent(sentry_value_t event, bool isCrash = false); + virtual ~FGenericPlatformSentryEvent() override; sentry_value_t GetNativeObject(); @@ -25,7 +25,7 @@ class SentryEventDesktop : public ISentryEvent virtual bool IsAnr() const override; private: - sentry_value_t EventDesktop; + sentry_value_t Event; bool IsCrashEvent; }; diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryId.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryId.cpp new file mode 100644 index 000000000..f8c038e2c --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryId.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2022 Sentry. All Rights Reserved. + +#include "GenericPlatformSentryId.h" + +#if USE_SENTRY_NATIVE + +FGenericPlatformSentryId::FGenericPlatformSentryId() +{ + Id = sentry_uuid_new_v4(); +} + +FGenericPlatformSentryId::FGenericPlatformSentryId(sentry_uuid_t id) +{ + Id = id; +} + +FGenericPlatformSentryId::~FGenericPlatformSentryId() +{ + // Put custom destructor logic here if needed +} + +sentry_uuid_t FGenericPlatformSentryId::GetNativeObject() +{ + return Id; +} + +FString FGenericPlatformSentryId::ToString() const +{ + char IdString[37]; + sentry_uuid_as_string(&Id, IdString); + return FString(IdString); +} + +#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryIdDesktop.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryId.h similarity index 59% rename from plugin-dev/Source/Sentry/Private/Desktop/SentryIdDesktop.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryId.h index 9b3e24f85..7ad016435 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryIdDesktop.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryId.h @@ -8,19 +8,19 @@ #if USE_SENTRY_NATIVE -class SentryIdDesktop : public ISentryId +class FGenericPlatformSentryId : public ISentryId { public: - SentryIdDesktop(); - SentryIdDesktop(sentry_uuid_t id); - virtual ~SentryIdDesktop() override; + FGenericPlatformSentryId(); + FGenericPlatformSentryId(sentry_uuid_t id); + virtual ~FGenericPlatformSentryId() override; sentry_uuid_t GetNativeObject(); virtual FString ToString() const override; private: - sentry_uuid_t IdDesktop; + sentry_uuid_t Id; }; #endif diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryScope.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryScope.cpp new file mode 100644 index 000000000..defaaae92 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryScope.cpp @@ -0,0 +1,302 @@ +// Copyright (c) 2023 Sentry. All Rights Reserved. + +#include "GenericPlatformSentryScope.h" +#include "GenericPlatformSentryBreadcrumb.h" +#include "GenericPlatformSentryEvent.h" + +#include "Interface/SentryAttachmentInterface.h" + +#include "SentryModule.h" +#include "SentrySettings.h" + +#include "Infrastructure/GenericPlatformSentryConverters.h" + +#if USE_SENTRY_NATIVE + +FGenericPlatformSentryScope::FGenericPlatformSentryScope() + : Level(ESentryLevel::Debug) +{ +} + +FGenericPlatformSentryScope::FGenericPlatformSentryScope(const FGenericPlatformSentryScope& Scope) +{ + Dist = Scope.Dist; + Environment = Scope.Environment; + Fingerprint = Scope.Fingerprint; + Tags = Scope.Tags; + Extra = Scope.Extra; + Contexts = Scope.Contexts; + Breadcrumbs = TRingBuffer>(Scope.Breadcrumbs); + Level = Scope.Level; +} + +FGenericPlatformSentryScope::~FGenericPlatformSentryScope() +{ +} + +void FGenericPlatformSentryScope::AddBreadcrumb(TSharedPtr breadcrumb) +{ + FScopeLock Lock(&CriticalSection); + + if(Breadcrumbs.Num() >= FSentryModule::Get().GetSettings()->MaxBreadcrumbs) + { + Breadcrumbs.PopFront(); + } + + Breadcrumbs.Add(StaticCastSharedPtr(breadcrumb)); +} + +void FGenericPlatformSentryScope::ClearBreadcrumbs() +{ + FScopeLock Lock(&CriticalSection); + + Breadcrumbs.Empty(); +} + +void FGenericPlatformSentryScope::AddAttachment(TSharedPtr attachment) +{ + // Not available for generic platform +} + +void FGenericPlatformSentryScope::ClearAttachments() +{ + // Not available for generic platform +} + +void FGenericPlatformSentryScope::SetTagValue(const FString& key, const FString& value) +{ + Tags.Add(key, value); +} + +FString FGenericPlatformSentryScope::GetTagValue(const FString& key) const +{ + if(!Tags.Contains(key)) + return FString(); + + return Tags[key]; +} + +void FGenericPlatformSentryScope::RemoveTag(const FString& key) +{ + Tags.Remove(key); +} + +void FGenericPlatformSentryScope::SetTags(const TMap& tags) +{ + Tags.Append(tags); +} + +TMap FGenericPlatformSentryScope::GetTags() const +{ + return Tags; +} + +void FGenericPlatformSentryScope::SetDist(const FString& dist) +{ + Dist = dist; +} + +FString FGenericPlatformSentryScope::GetDist() const +{ + return Dist; +} + +void FGenericPlatformSentryScope::SetEnvironment(const FString& environment) +{ + Environment = environment; +} + +FString FGenericPlatformSentryScope::GetEnvironment() const +{ + return Environment; +} + +void FGenericPlatformSentryScope::SetFingerprint(const TArray& fingerprint) +{ + Fingerprint = fingerprint; +} + +TArray FGenericPlatformSentryScope::GetFingerprint() const +{ + return Fingerprint; +} + +void FGenericPlatformSentryScope::SetLevel(ESentryLevel level) +{ + Level = level; +} + +ESentryLevel FGenericPlatformSentryScope::GetLevel() const +{ + + return Level; +} + +void FGenericPlatformSentryScope::SetContext(const FString& key, const TMap& values) +{ + Contexts.Add(key, values); +} + +void FGenericPlatformSentryScope::RemoveContext(const FString& key) +{ + if(!Contexts.Contains(key)) + return; + + Contexts.Remove(key); +} + +void FGenericPlatformSentryScope::SetExtraValue(const FString& key, const FString& value) +{ + Extra.Add(key, value); +} + +FString FGenericPlatformSentryScope::GetExtraValue(const FString& key) const +{ + if(!Extra.Contains(key)) + return FString(); + + return Extra[key]; +} + +void FGenericPlatformSentryScope::RemoveExtra(const FString& key) +{ + if(!Extra.Contains(key)) + return; + + Extra.Remove(key); +} + +void FGenericPlatformSentryScope::SetExtras(const TMap& extras) +{ + Extra.Append(extras); +} + +TMap FGenericPlatformSentryScope::GetExtras() const +{ + return Extra; +} + +void FGenericPlatformSentryScope::Clear() +{ + Dist = FString(); + Environment = FString(); + Fingerprint.Empty(); + Tags.Empty(); + Extra.Empty(); + Contexts.Empty(); + Breadcrumbs.Empty(); + Level = ESentryLevel::Debug; +} + +void FGenericPlatformSentryScope::Apply(TSharedPtr event) +{ + sentry_value_t nativeEvent = event->GetNativeObject(); + + sentry_value_t eventLevel = sentry_value_get_by_key(nativeEvent, "level"); + + FString scopeLevelStr = FGenericPlatformSentryConverters::SentryLevelToString(Level).ToLower(); + if (!scopeLevelStr.IsEmpty() && sentry_value_is_null(eventLevel)) + { + sentry_value_set_by_key(nativeEvent, "level", sentry_value_new_string(TCHAR_TO_ANSI(*scopeLevelStr))); + } + + if(!Dist.IsEmpty()) + { + sentry_value_set_by_key(nativeEvent, "dist", sentry_value_new_string(TCHAR_TO_ANSI(*Dist))); + } + + if(!Environment.IsEmpty()) + { + sentry_value_set_by_key(nativeEvent, "environment", sentry_value_new_string(TCHAR_TO_ANSI(*Environment))); + } + + if(Fingerprint.Num() > 0) + { + sentry_value_set_by_key(nativeEvent, "fingerprint", FGenericPlatformSentryConverters::StringArrayToNative(Fingerprint)); + } + + if(Tags.Num() > 0) + { + sentry_value_t tagsExtra = sentry_value_get_by_key(nativeEvent, "tags"); + if(sentry_value_is_null(tagsExtra)) + { + sentry_value_set_by_key(nativeEvent, "tags", FGenericPlatformSentryConverters::StringMapToNative(Tags)); + } + else + { + for (const auto& TagItem : Tags) + { + sentry_value_set_by_key(tagsExtra, TCHAR_TO_ANSI(*TagItem.Key), sentry_value_new_string(TCHAR_TO_ANSI(*TagItem.Value))); + } + } + } + + if(Extra.Num() > 0) + { + sentry_value_t eventExtra = sentry_value_get_by_key(nativeEvent, "extra"); + if(sentry_value_is_null(eventExtra)) + { + sentry_value_set_by_key(nativeEvent, "extra", FGenericPlatformSentryConverters::StringMapToNative(Extra)); + } + else + { + for (const auto& ExtraItem : Extra) + { + sentry_value_set_by_key(eventExtra, TCHAR_TO_ANSI(*ExtraItem.Key), sentry_value_new_string(TCHAR_TO_ANSI(*ExtraItem.Value))); + } + } + + } + + if(Contexts.Num() > 0) + { + sentry_value_t eventContexts = sentry_value_get_by_key(nativeEvent, "contexts"); + if(sentry_value_is_null(eventContexts)) + { + eventContexts = sentry_value_new_object(); + + for (const auto& ContextsItem : Contexts) + { + sentry_value_set_by_key(eventContexts, TCHAR_TO_ANSI(*ContextsItem.Key), FGenericPlatformSentryConverters::StringMapToNative(ContextsItem.Value)); + } + + sentry_value_set_by_key(nativeEvent, "contexts", eventContexts); + } + else + { + for (const auto& ContextsItem : Contexts) + { + sentry_value_set_by_key(eventContexts, TCHAR_TO_ANSI(*ContextsItem.Key), FGenericPlatformSentryConverters::StringMapToNative(ContextsItem.Value)); + } + } + } + + if(!Breadcrumbs.IsEmpty()) + { + sentry_value_t eventBreadcrumbs = sentry_value_get_by_key(nativeEvent, "breadcrumbs"); + if(sentry_value_is_null(eventBreadcrumbs)) + { + eventBreadcrumbs = sentry_value_new_list(); + + for (const auto& Breadcrumb : Breadcrumbs) + { + sentry_value_t nativeBreadcrumb = Breadcrumb->GetNativeObject(); + sentry_value_incref(nativeBreadcrumb); + sentry_value_append(eventBreadcrumbs, nativeBreadcrumb); + } + + sentry_value_set_by_key(nativeEvent, "breadcrumbs", eventBreadcrumbs); + } + else + { + for (const auto& Breadcrumb : Breadcrumbs) + { + sentry_value_t nativeBreadcrumb = Breadcrumb->GetNativeObject(); + sentry_value_incref(nativeBreadcrumb); + sentry_value_append(eventBreadcrumbs, nativeBreadcrumb); + } + } + } +} + +#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryScopeDesktop.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryScope.h similarity index 76% rename from plugin-dev/Source/Sentry/Private/Desktop/SentryScopeDesktop.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryScope.h index 1769ebf47..52179d6c0 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryScopeDesktop.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryScope.h @@ -9,15 +9,15 @@ #if USE_SENTRY_NATIVE -class SentryBreadcrumbDesktop; -class SentryEventDesktop; +class FGenericPlatformSentryBreadcrumb; +class FGenericPlatformSentryEvent; -class SentryScopeDesktop : public ISentryScope +class FGenericPlatformSentryScope : public ISentryScope { public: - SentryScopeDesktop(); - SentryScopeDesktop(const SentryScopeDesktop& Scope); - virtual ~SentryScopeDesktop() override; + FGenericPlatformSentryScope(); + FGenericPlatformSentryScope(const FGenericPlatformSentryScope& Scope); + virtual ~FGenericPlatformSentryScope() override; virtual void AddBreadcrumb(TSharedPtr breadcrumb) override; virtual void ClearBreadcrumbs() override; @@ -45,22 +45,22 @@ class SentryScopeDesktop : public ISentryScope virtual TMap GetExtras() const override; virtual void Clear() override; - void Apply(TSharedPtr event); + void Apply(TSharedPtr event); private: FString Dist; FString Environment; - TArray FingerprintDesktop; + TArray Fingerprint; - TMap TagsDesktop; - TMap ExtraDesktop; + TMap Tags; + TMap Extra; - TMap> ContextsDesktop; + TMap> Contexts; - TRingBuffer> BreadcrumbsDesktop; + TRingBuffer> Breadcrumbs; - ESentryLevel LevelDesktop; + ESentryLevel Level; FCriticalSection CriticalSection; }; diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySpan.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySpan.cpp new file mode 100644 index 000000000..5a3bbf295 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySpan.cpp @@ -0,0 +1,109 @@ +// Copyright (c) 2023 Sentry. All Rights Reserved. + +#include "GenericPlatformSentrySpan.h" + +#include "Infrastructure/GenericPlatformSentryConverters.h" + +#if USE_SENTRY_NATIVE + +void CopySpanTracingHeader(const char* key, const char* value, void* userdata) +{ + sentry_value_t* header = static_cast(userdata); + sentry_value_set_by_key(*header, key, sentry_value_new_string(value)); +} + +FGenericPlatformSentrySpan::FGenericPlatformSentrySpan(sentry_span_t* span) + : Span(span) + , isFinished(false) +{ +} + +sentry_span_t* FGenericPlatformSentrySpan::GetNativeObject() +{ + return Span; +} + +TSharedPtr FGenericPlatformSentrySpan::StartChild(const FString& operation, const FString& description) +{ + if (sentry_span_t* nativeSpan = sentry_span_start_child(Span, TCHAR_TO_ANSI(*operation), TCHAR_TO_ANSI(*description))) + { + return MakeShareable(new FGenericPlatformSentrySpan(nativeSpan)); + } + else + { + return nullptr; + } +} + +TSharedPtr FGenericPlatformSentrySpan::StartChildWithTimestamp(const FString& operation, const FString& description, int64 timestamp) +{ + if (sentry_span_t* nativeSpan = sentry_span_start_child_ts(Span, TCHAR_TO_ANSI(*operation), TCHAR_TO_ANSI(*description), timestamp)) + { + return MakeShareable(new FGenericPlatformSentrySpan(nativeSpan)); + } + else + { + return nullptr; + } +} + +void FGenericPlatformSentrySpan::Finish() +{ + sentry_span_finish(Span); + + isFinished = true; +} + +void FGenericPlatformSentrySpan::FinishWithTimestamp(int64 timestamp) +{ + sentry_span_finish_ts(Span, timestamp); + + isFinished = true; +} + +bool FGenericPlatformSentrySpan::IsFinished() const +{ + return isFinished; +} + +void FGenericPlatformSentrySpan::SetTag(const FString& key, const FString& value) +{ + FScopeLock Lock(&CriticalSection); + + sentry_span_set_tag(Span, TCHAR_TO_ANSI(*key), TCHAR_TO_ANSI(*value)); +} + +void FGenericPlatformSentrySpan::RemoveTag(const FString& key) +{ + FScopeLock Lock(&CriticalSection); + + sentry_span_remove_tag(Span, TCHAR_TO_ANSI(*key)); +} + +void FGenericPlatformSentrySpan::SetData(const FString& key, const TMap& values) +{ + FScopeLock Lock(&CriticalSection); + + sentry_span_set_data(Span, TCHAR_TO_ANSI(*key), FGenericPlatformSentryConverters::StringMapToNative(values)); +} + +void FGenericPlatformSentrySpan::RemoveData(const FString& key) +{ + FScopeLock Lock(&CriticalSection); + + sentry_span_remove_data(Span, TCHAR_TO_ANSI(*key)); +} + +void FGenericPlatformSentrySpan::GetTrace(FString& name, FString& value) +{ + sentry_value_t tracingHeader = sentry_value_new_object(); + + sentry_span_iter_headers(Span, CopySpanTracingHeader, &tracingHeader); + + name = TEXT("sentry-trace"); + value = FString(sentry_value_as_string(sentry_value_get_by_key(tracingHeader, "sentry-trace"))); + + sentry_value_decref(tracingHeader); +} + +#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySpan.h similarity index 72% rename from plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySpan.h index bf2f95fab..b891bfcb7 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySpan.h @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. +// Copyright (c) 2023 Sentry. All Rights Reserved. #pragma once @@ -10,16 +10,16 @@ #if USE_SENTRY_NATIVE -class SentrySpanDesktop : public ISentrySpan +class FGenericPlatformSentrySpan : public ISentrySpan { public: - SentrySpanDesktop(sentry_span_t* span); - virtual ~SentrySpanDesktop() override; + FGenericPlatformSentrySpan(sentry_span_t* span); + virtual ~FGenericPlatformSentrySpan() override = default; sentry_span_t* GetNativeObject(); - virtual TSharedPtr StartChild(const FString& operation, const FString& desctiption) override; - virtual TSharedPtr StartChildWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) override; + virtual TSharedPtr StartChild(const FString& operation, const FString& description) override; + virtual TSharedPtr StartChildWithTimestamp(const FString& operation, const FString& description, int64 timestamp) override; virtual void Finish() override; virtual void FinishWithTimestamp(int64 timestamp) override; virtual bool IsFinished() const override; @@ -30,7 +30,7 @@ class SentrySpanDesktop : public ISentrySpan virtual void GetTrace(FString& name, FString& value) override; private: - sentry_span_t* SpanDesktop; + sentry_span_t* Span; FCriticalSection CriticalSection; diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.cpp new file mode 100644 index 000000000..9d67af833 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.cpp @@ -0,0 +1,572 @@ +// Copyright (c) 2022 Sentry. All Rights Reserved. + +#include "GenericPlatformSentrySubsystem.h" +#include "GenericPlatformSentryEvent.h" +#include "GenericPlatformSentryBreadcrumb.h" +#include "GenericPlatformSentryUser.h" +#include "GenericPlatformSentryUserFeedback.h" +#include "GenericPlatformSentryScope.h" +#include "GenericPlatformSentryTransaction.h" +#include "GenericPlatformSentryTransactionContext.h" +#include "GenericPlatformSentryId.h" + +#include "SentryDefines.h" +#include "SentrySettings.h" +#include "SentryEvent.h" +#include "SentryModule.h" +#include "SentryBeforeSendHandler.h" + +#include "SentryTraceSampler.h" + +#include "Utils/SentryFileUtils.h" +#include "Utils/SentryLogUtils.h" +#include "Utils/SentryScreenshotUtils.h" + +#include "Infrastructure/GenericPlatformSentryConverters.h" + +#include "GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.h" +#include "GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.h" + +#include "Misc/Paths.h" +#include "Misc/ScopeLock.h" +#include "Misc/CoreDelegates.h" +#include "HAL/FileManager.h" +#include "Misc/EngineVersionComparison.h" +#include "GenericPlatform/GenericPlatformOutputDevices.h" +#include "HAL/ExceptionHandling.h" +#include "UObject/GarbageCollection.h" +#include "UObject/UObjectThreadContext.h" + +extern CORE_API bool GIsGPUCrashed; + +#if USE_SENTRY_NATIVE + +void PrintVerboseLog(sentry_level_t level, const char* message, va_list args, void* userdata) +{ + char buffer[512]; + vsnprintf(buffer, 512, message, args); + + FString MessageBuf = FString(buffer); + + // The WER (Windows Error Reporting) module (crashpad_wer.dll) can't be distributed along with other Sentry binaries + // within the plugin package due to some UE Marketplace restrictions. Its absence doesn't affect crash capturing + // and the corresponding warning can be disregarded + if (MessageBuf.Equals(TEXT("crashpad WER handler module not found"))) + { + return; + } + +#if !NO_LOGGING + const FName SentryCategoryName(LogSentrySdk.GetCategoryName()); +#else + const FName SentryCategoryName(TEXT("LogSentrySdk")); +#endif + + GLog->CategorizedLogf(SentryCategoryName, FGenericPlatformSentryConverters::SentryLevelToLogVerbosity(level), TEXT("%s"), *MessageBuf); +} + +/* static */ sentry_value_t FGenericPlatformSentrySubsystem::HandleBeforeSend(sentry_value_t event, void* hint, void* closure) +{ + if (closure) + { + return StaticCast(closure)->OnBeforeSend(event, hint, closure); + } + else + { + return event; + } +} + +/* static */ sentry_value_t FGenericPlatformSentrySubsystem::HandleOnCrash(const sentry_ucontext_t* uctx, sentry_value_t event, void* closure) +{ + if (closure) + { + return StaticCast(closure)->OnCrash(uctx, event, closure); + } + else + { + return event; + } +} + +sentry_value_t FGenericPlatformSentrySubsystem::OnBeforeSend(sentry_value_t event, void* hint, void* closure) +{ + if (!closure || this != closure) + { + return event; + } + + TSharedPtr Event = MakeShareable(new FGenericPlatformSentryEvent(event)); + + GetCurrentScope()->Apply(Event); + + FGCScopeGuard GCScopeGuard; + + USentryEvent* EventToProcess = USentryEvent::Create(Event); + + USentryEvent* ProcessedEvent = EventToProcess; + if (!FUObjectThreadContext::Get().IsRoutingPostLoad) + { + // Executing UFUNCTION is allowed only when not post-loading + ProcessedEvent = GetBeforeSendHandler()->HandleBeforeSend(EventToProcess, nullptr); + } + + return ProcessedEvent ? event : sentry_value_new_null(); +} + +sentry_value_t FGenericPlatformSentrySubsystem::OnCrash(const sentry_ucontext_t* uctx, sentry_value_t event, void* closure) +{ + if (!closure || this != closure) + { + return event; + } + + TryCaptureScreenshot(); + + if (GIsGPUCrashed) + { + IFileManager::Get().Copy(*GetGpuDumpBackupPath(), *SentryFileUtils::GetGpuDumpPath()); + } + + FGenericPlatformSentryCrashContext::Get()->Apply(GetCurrentScope()); + + TSharedPtr Event = MakeShareable(new FGenericPlatformSentryEvent(event, true)); + + GetCurrentScope()->Apply(Event); + + if (!IsGarbageCollecting()) + { + USentryEvent* EventToProcess = USentryEvent::Create(Event); + + USentryEvent* ProcessedEvent = EventToProcess; + if (!FUObjectThreadContext::Get().IsRoutingPostLoad) + { + // Executing UFUNCTION is allowed only when not post-loading + ProcessedEvent = GetBeforeSendHandler()->HandleBeforeSend(EventToProcess, nullptr); + } + + return ProcessedEvent ? event : sentry_value_new_null(); + } + else + { + // If crash occurred during garbage collection we can't just obtain a GC lock like with normal events + // since there is no guarantee it will be ever freed. In this case crash event will be reported + // without calling a `beforeSend` handler. + return event; + } +} + +FGenericPlatformSentrySubsystem::FGenericPlatformSentrySubsystem() + : beforeSend(nullptr) + , crashReporter(MakeShareable(new FGenericPlatformSentryCrashReporter)) + , isEnabled(false) + , isStackTraceEnabled(true) + , isScreenshotAttachmentEnabled(false) +{ +} + +void FGenericPlatformSentrySubsystem::InitWithSettings(const USentrySettings* settings, USentryBeforeSendHandler* beforeSendHandler, USentryTraceSampler* traceSampler) +{ + beforeSend = beforeSendHandler; + + scopeStack.Push(MakeShareable(new FGenericPlatformSentryScope())); + + sentry_options_t* options = sentry_options_new(); + + if (settings->EnableAutoLogAttachment) + { + ConfigureLogFileAttachment(options); + } + + switch (settings->DatabaseLocation) + { + case ESentryDatabaseLocation::ProjectDirectory: + databaseParentPath = FPaths::ProjectDir(); + break; + case ESentryDatabaseLocation::ProjectUserDirectory: + databaseParentPath = FPaths::ProjectUserDir(); + break; + } + + if (databaseParentPath.IsEmpty()) + { + UE_LOG(LogSentrySdk, Warning, TEXT("Unknown Sentry database location. Falling back to FPaths::ProjectUserDir().")); + databaseParentPath = FPaths::ProjectUserDir(); + } + + if (settings->AttachScreenshot) + { + isScreenshotAttachmentEnabled = true; + + ConfigureScreenshotAttachment(options); + } + + if (settings->AttachGpuDump) + { + ConfigureGpuDumpAttachment(options); + } + + if (settings->UseProxy) + { + sentry_options_set_http_proxy(options, TCHAR_TO_ANSI(*settings->ProxyUrl)); + } + + if (settings->EnableTracing && settings->SamplingType == ESentryTracesSamplingType::UniformSampleRate) + { + sentry_options_set_traces_sample_rate(options, settings->TracesSampleRate); + } + if (settings->EnableTracing && settings->SamplingType == ESentryTracesSamplingType::TracesSampler) + { + UE_LOG(LogSentrySdk, Warning, TEXT("The Native SDK doesn't currently support sampling functions")); + } + + ConfigureHandlerPath(options); + ConfigureDatabasePath(options); + + sentry_options_set_release(options, TCHAR_TO_ANSI(settings->OverrideReleaseName + ? *settings->Release + : *settings->GetFormattedReleaseName())); + + sentry_options_set_dsn(options, TCHAR_TO_ANSI(*settings->Dsn)); + sentry_options_set_environment(options, TCHAR_TO_ANSI(*settings->Environment)); + sentry_options_set_logger(options, PrintVerboseLog, nullptr); + sentry_options_set_debug(options, settings->Debug); + sentry_options_set_auto_session_tracking(options, settings->EnableAutoSessionTracking); + sentry_options_set_sample_rate(options, settings->SampleRate); + sentry_options_set_max_breadcrumbs(options, settings->MaxBreadcrumbs); + sentry_options_set_before_send(options, HandleBeforeSend, this); + sentry_options_set_on_crash(options, HandleOnCrash, this); + sentry_options_set_shutdown_timeout(options, 3000); + + int initResult = sentry_init(options); + + UE_LOG(LogSentrySdk, Log, TEXT("Sentry initialization completed with result %d (0 on success)."), initResult); + + isEnabled = initResult == 0 ? true : false; + + sentry_clear_crashed_last_run(); + + isStackTraceEnabled = settings->AttachStacktrace; + + crashReporter->SetRelease(settings->Release); + crashReporter->SetEnvironment(settings->Environment); +} + +void FGenericPlatformSentrySubsystem::Close() +{ + isEnabled = false; + + sentry_close(); + + scopeStack.Empty(); +} + +bool FGenericPlatformSentrySubsystem::IsEnabled() +{ + return isEnabled; +} + +ESentryCrashedLastRun FGenericPlatformSentrySubsystem::IsCrashedLastRun() +{ + ESentryCrashedLastRun unrealIsCrashed = ESentryCrashedLastRun::NotEvaluated; + + switch (sentry_get_crashed_last_run()) + { + case -1: + unrealIsCrashed = ESentryCrashedLastRun::NotEvaluated; + break; + case 0: + unrealIsCrashed = ESentryCrashedLastRun::NotCrashed; + break; + case 1: + unrealIsCrashed = ESentryCrashedLastRun::Crashed; + break; + default: + UE_LOG(LogSentrySdk, Warning, TEXT("Unknown IsCrashedLastRun result. NotEvaluated will be returned.")); + } + + return unrealIsCrashed; +} + +void FGenericPlatformSentrySubsystem::AddBreadcrumb(TSharedPtr breadcrumb) +{ + GetCurrentScope()->AddBreadcrumb(breadcrumb); +} + +void FGenericPlatformSentrySubsystem::AddBreadcrumbWithParams(const FString& Message, const FString& Category, const FString& Type, const TMap& Data, ESentryLevel Level) +{ + TSharedPtr Breadcrumb = MakeShareable(new FGenericPlatformSentryBreadcrumb()); + Breadcrumb->SetMessage(Message); + Breadcrumb->SetCategory(Category); + Breadcrumb->SetType(Type); + Breadcrumb->SetData(Data); + Breadcrumb->SetLevel(Level); + + GetCurrentScope()->AddBreadcrumb(Breadcrumb); +} + +void FGenericPlatformSentrySubsystem::ClearBreadcrumbs() +{ + GetCurrentScope()->ClearBreadcrumbs(); +} + +TSharedPtr FGenericPlatformSentrySubsystem::CaptureMessage(const FString& message, ESentryLevel level) +{ + sentry_value_t sentryEvent = sentry_value_new_message_event(FGenericPlatformSentryConverters::SentryLevelToNative(level), nullptr, TCHAR_TO_UTF8(*message)); + + if (isStackTraceEnabled) + { + sentry_value_set_stacktrace(sentryEvent, nullptr, 0); + } + + sentry_uuid_t id = sentry_capture_event(sentryEvent); + return MakeShareable(new FGenericPlatformSentryId(id)); +} + +TSharedPtr FGenericPlatformSentrySubsystem::CaptureMessageWithScope(const FString& message, const FSentryScopeDelegate& onScopeConfigure, ESentryLevel level) +{ + FScopeLock Lock(&CriticalSection); + + TSharedPtr NewLocalScope = MakeShareable(new FGenericPlatformSentryScope(*GetCurrentScope())); + + onScopeConfigure.ExecuteIfBound(NewLocalScope); + + scopeStack.Push(NewLocalScope); + TSharedPtr Id = CaptureMessage(message, level); + scopeStack.Pop(); + + return Id; +} + +TSharedPtr FGenericPlatformSentrySubsystem::CaptureEvent(TSharedPtr event) +{ + TSharedPtr Event = StaticCastSharedPtr(event); + + sentry_value_t nativeEvent = Event->GetNativeObject(); + + if (isStackTraceEnabled) + { + sentry_value_set_stacktrace(nativeEvent, nullptr, 0); + } + + sentry_uuid_t id = sentry_capture_event(nativeEvent); + return MakeShareable(new FGenericPlatformSentryId(id)); +} + +TSharedPtr FGenericPlatformSentrySubsystem::CaptureEventWithScope(TSharedPtr event, const FSentryScopeDelegate& onScopeConfigure) +{ + FScopeLock Lock(&CriticalSection); + + TSharedPtr NewLocalScope = MakeShareable(new FGenericPlatformSentryScope(*GetCurrentScope())); + + onScopeConfigure.ExecuteIfBound(NewLocalScope); + + scopeStack.Push(NewLocalScope); + TSharedPtr Id = CaptureEvent(event); + scopeStack.Pop(); + + return Id; +} + +TSharedPtr FGenericPlatformSentrySubsystem::CaptureException(const FString& type, const FString& message, int32 framesToSkip) +{ + sentry_value_t exceptionEvent = sentry_value_new_event(); + + auto StackFrames = FGenericPlatformStackWalk::GetStack(framesToSkip); + sentry_value_set_by_key(exceptionEvent, "stacktrace", FGenericPlatformSentryConverters::CallstackToNative(StackFrames)); + + sentry_value_t nativeException = sentry_value_new_exception(TCHAR_TO_ANSI(*type), TCHAR_TO_ANSI(*message)); + sentry_event_add_exception(exceptionEvent, nativeException); + + sentry_uuid_t id = sentry_capture_event(exceptionEvent); + return MakeShareable(new FGenericPlatformSentryId(id)); +} + +TSharedPtr FGenericPlatformSentrySubsystem::CaptureAssertion(const FString& type, const FString& message) +{ + int32 framesToSkip = GetAssertionFramesToSkip(); + + SentryLogUtils::LogStackTrace(*message, ELogVerbosity::Error, framesToSkip); + + return CaptureException(type, message, GetAssertionFramesToSkip()); +} + +TSharedPtr FGenericPlatformSentrySubsystem::CaptureEnsure(const FString& type, const FString& message) +{ + return CaptureException(type, message, GetEnsureFramesToSkip()); +} + +void FGenericPlatformSentrySubsystem::CaptureUserFeedback(TSharedPtr InUserFeedback) +{ + TSharedPtr userFeedback = StaticCastSharedPtr(InUserFeedback); + sentry_capture_user_feedback(userFeedback->GetNativeObject()); +} + +void FGenericPlatformSentrySubsystem::SetUser(TSharedPtr InUser) +{ + TSharedPtr user = StaticCastSharedPtr(InUser); + sentry_set_user(user->GetNativeObject()); + + crashReporter->SetUser(user); +} + +void FGenericPlatformSentrySubsystem::RemoveUser() +{ + sentry_remove_user(); + + crashReporter->RemoveUser(); +} + +void FGenericPlatformSentrySubsystem::ConfigureScope(const FSentryScopeDelegate& onConfigureScope) +{ + onConfigureScope.ExecuteIfBound(GetCurrentScope()); +} + +void FGenericPlatformSentrySubsystem::SetContext(const FString& key, const TMap& values) +{ + GetCurrentScope()->SetContext(key, values); + + crashReporter->SetContext(key, values); +} + +void FGenericPlatformSentrySubsystem::SetTag(const FString& key, const FString& value) +{ + GetCurrentScope()->SetTagValue(key, value); + + crashReporter->SetTag(key, value); +} + +void FGenericPlatformSentrySubsystem::RemoveTag(const FString& key) +{ + GetCurrentScope()->RemoveTag(key); + + crashReporter->RemoveTag(key); +} + +void FGenericPlatformSentrySubsystem::SetLevel(ESentryLevel level) +{ + GetCurrentScope()->SetLevel(level); +} + +void FGenericPlatformSentrySubsystem::StartSession() +{ + sentry_start_session(); +} + +void FGenericPlatformSentrySubsystem::EndSession() +{ + sentry_end_session(); +} + +TSharedPtr FGenericPlatformSentrySubsystem::StartTransaction(const FString& name, const FString& operation) +{ + TSharedPtr transactionContext = MakeShareable(new FGenericPlatformSentryTransactionContext(name, operation)); + + return StartTransactionWithContext(transactionContext); +} + +TSharedPtr FGenericPlatformSentrySubsystem::StartTransactionWithContext(TSharedPtr context) +{ + if (TSharedPtr platformTransactionContext = StaticCastSharedPtr(context)) + { + if (sentry_transaction_t* nativeTransaction = sentry_transaction_start(platformTransactionContext->GetNativeObject(), sentry_value_new_null())) + { + return MakeShareable(new FGenericPlatformSentryTransaction(nativeTransaction)); + } + } + + return nullptr; +} + +TSharedPtr FGenericPlatformSentrySubsystem::StartTransactionWithContextAndTimestamp(TSharedPtr context, int64 timestamp) +{ + if (TSharedPtr platformTransactionContext = StaticCastSharedPtr(context)) + { + if (sentry_transaction_t* nativeTransaction = sentry_transaction_start_ts(platformTransactionContext->GetNativeObject(), sentry_value_new_null(), timestamp)) + { + return MakeShareable(new FGenericPlatformSentryTransaction(nativeTransaction)); + } + } + + return nullptr; +} + +TSharedPtr FGenericPlatformSentrySubsystem::StartTransactionWithContextAndOptions(TSharedPtr context, const TMap& options) +{ + UE_LOG(LogSentrySdk, Log, TEXT("Transaction options currently not supported (and therefore ignored) on generic platform.")); + return StartTransactionWithContext(context); +} + +TSharedPtr FGenericPlatformSentrySubsystem::ContinueTrace(const FString& sentryTrace, const TArray& baggageHeaders) +{ + TSharedPtr transactionContext = MakeShareable(new FGenericPlatformSentryTransactionContext(TEXT(""), TEXT("default"))); + + sentry_transaction_context_update_from_header(transactionContext->GetNativeObject(), "sentry-trace", TCHAR_TO_ANSI(*sentryTrace)); + + // currently `sentry-native` doesn't have API for `sentry_transaction_context_t` to set `baggageHeaders` + + return transactionContext; +} + +USentryBeforeSendHandler* FGenericPlatformSentrySubsystem::GetBeforeSendHandler() +{ + return beforeSend; +} + +void FGenericPlatformSentrySubsystem::TryCaptureScreenshot() const +{ + if (!isScreenshotAttachmentEnabled) + { + UE_LOG(LogSentrySdk, Log, TEXT("Screenshot attachment is disabled in plugin settings.")); + return; + } + + SentryScreenshotUtils::CaptureScreenshot(GetScreenshotPath()); +} + +FString FGenericPlatformSentrySubsystem::GetGpuDumpBackupPath() const +{ + static const FString DateTimeString = FDateTime::Now().ToString(); + + const FString GpuDumpPath = FPaths::Combine(GetDatabasePath(), TEXT("gpudumps"), *FString::Printf(TEXT("UEAftermath-%s.nv-gpudmp"), *DateTimeString));; + const FString GpuDumpFullPath = FPaths::ConvertRelativePathToFull(GpuDumpPath); + + return GpuDumpFullPath; +} + +TSharedPtr FGenericPlatformSentrySubsystem::GetCurrentScope() +{ + if (scopeStack.Num() == 0) + { + UE_LOG(LogSentrySdk, Warning, TEXT("Scope stack is empty.")); + return nullptr; + } + + return scopeStack.Top(); +} + +FString FGenericPlatformSentrySubsystem::GetHandlerPath() const +{ + const FString HandlerPath = FPaths::Combine(FSentryModule::Get().GetBinariesPath(), GetHandlerExecutableName()); + const FString HandlerFullPath = FPaths::ConvertRelativePathToFull(HandlerPath); + + return HandlerFullPath; +} + +FString FGenericPlatformSentrySubsystem::GetDatabasePath() const +{ + const FString DatabasePath = FPaths::Combine(databaseParentPath, TEXT(".sentry-native")); + const FString DatabaseFullPath = FPaths::ConvertRelativePathToFull(DatabasePath); + + return DatabaseFullPath; +} + +FString FGenericPlatformSentrySubsystem::GetScreenshotPath() const +{ + const FString ScreenshotPath = FPaths::Combine(GetDatabasePath(), TEXT("screenshots"), TEXT("crash_screenshot.png")); + const FString ScreenshotFullPath = FPaths::ConvertRelativePathToFull(ScreenshotPath); + + return ScreenshotFullPath; +} + +#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.h similarity index 70% rename from plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.h index 27c3c62c6..017a5963b 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.h @@ -6,15 +6,17 @@ #include "Interface/SentrySubsystemInterface.h" -class SentryScopeDesktop; -class SentryCrashReporter; +class FGenericPlatformSentryScope; +class FGenericPlatformSentryCrashReporter; #if USE_SENTRY_NATIVE -class SentrySubsystemDesktop : public ISentrySubsystem +#include "GenericPlatform/Convenience/SentryInclude.h" + +class FGenericPlatformSentrySubsystem : public ISentrySubsystem { public: - SentrySubsystemDesktop(); + FGenericPlatformSentrySubsystem(); virtual void InitWithSettings(const USentrySettings* settings, USentryBeforeSendHandler* beforeSendHandler, USentryTraceSampler* traceSampler) override; virtual void Close() override; @@ -52,18 +54,37 @@ class SentrySubsystemDesktop : public ISentrySubsystem FString GetGpuDumpBackupPath() const; - TSharedPtr GetCurrentScope(); + TSharedPtr GetCurrentScope(); + +protected: + virtual void ConfigureHandlerPath(sentry_options_t* Options) {} + virtual void ConfigureDatabasePath(sentry_options_t* Options) {} + virtual void ConfigureLogFileAttachment(sentry_options_t* Options) {} + virtual void ConfigureScreenshotAttachment(sentry_options_t* Options) {} + virtual void ConfigureGpuDumpAttachment(sentry_options_t* Options) {} -private: FString GetHandlerPath() const; FString GetDatabasePath() const; FString GetScreenshotPath() const; + virtual int32 GetEnsureFramesToSkip() const { return 7; } + virtual int32 GetAssertionFramesToSkip() const { return 5; } + virtual FString GetHandlerExecutableName() const { return TEXT("invalid"); } + + virtual sentry_value_t OnBeforeSend(sentry_value_t event, void* hint, void* closure); + virtual sentry_value_t OnCrash(const sentry_ucontext_t* uctx, sentry_value_t event, void* closure); + +private: + /** + * Static wrappers that are passed to the Sentry library. + */ + static sentry_value_t HandleBeforeSend(sentry_value_t event, void* hint, void* closure); + static sentry_value_t HandleOnCrash(const sentry_ucontext_t* uctx, sentry_value_t event, void* closure); USentryBeforeSendHandler* beforeSend; - TSharedPtr crashReporter; + TSharedPtr crashReporter; - TArray> scopeStack; + TArray> scopeStack; bool isEnabled; diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransaction.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransaction.cpp new file mode 100644 index 000000000..9abad8ff2 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransaction.cpp @@ -0,0 +1,117 @@ +// Copyright (c) 2023 Sentry. All Rights Reserved. + +#include "GenericPlatformSentryTransaction.h" +#include "GenericPlatformSentrySpan.h" + +#include "Infrastructure/GenericPlatformSentryConverters.h" + +#if USE_SENTRY_NATIVE + +void CopyTransactionTracingHeader(const char* key, const char* value, void* userdata) +{ + sentry_value_t* header = static_cast(userdata); + sentry_value_set_by_key(*header, key, sentry_value_new_string(value)); +} + +FGenericPlatformSentryTransaction::FGenericPlatformSentryTransaction(sentry_transaction_t* transaction) + : Transaction(transaction) + , isFinished(false) +{ +} + +sentry_transaction_t* FGenericPlatformSentryTransaction::GetNativeObject() +{ + return Transaction; +} + +TSharedPtr FGenericPlatformSentryTransaction::StartChildSpan(const FString& operation, const FString& description) +{ + if (sentry_span_t* nativeSpan = sentry_transaction_start_child(Transaction, TCHAR_TO_ANSI(*operation), TCHAR_TO_ANSI(*description))) + { + return MakeShareable(new FGenericPlatformSentrySpan(nativeSpan)); + } + else + { + return nullptr; + } +} + +TSharedPtr FGenericPlatformSentryTransaction::StartChildSpanWithTimestamp(const FString& operation, const FString& description, int64 timestamp) +{ + if (sentry_span_t* nativeSpan = sentry_transaction_start_child_ts(Transaction, TCHAR_TO_ANSI(*operation), TCHAR_TO_ANSI(*description), timestamp)) + { + return MakeShareable(new FGenericPlatformSentrySpan(nativeSpan)); + } + else + { + return nullptr; + } +} + +void FGenericPlatformSentryTransaction::Finish() +{ + sentry_transaction_finish(Transaction); + + isFinished = true; +} + +void FGenericPlatformSentryTransaction::FinishWithTimestamp(int64 timestamp) +{ + sentry_transaction_finish_ts(Transaction, timestamp); + + isFinished = true; +} + +bool FGenericPlatformSentryTransaction::IsFinished() const +{ + return isFinished; +} + +void FGenericPlatformSentryTransaction::SetName(const FString& name) +{ + FScopeLock Lock(&CriticalSection); + + sentry_transaction_set_name(Transaction, TCHAR_TO_ANSI(*name)); +} + +void FGenericPlatformSentryTransaction::SetTag(const FString& key, const FString& value) +{ + FScopeLock Lock(&CriticalSection); + + sentry_transaction_set_tag(Transaction, TCHAR_TO_ANSI(*key), TCHAR_TO_ANSI(*value)); +} + +void FGenericPlatformSentryTransaction::RemoveTag(const FString& key) +{ + FScopeLock Lock(&CriticalSection); + + sentry_transaction_remove_tag(Transaction, TCHAR_TO_ANSI(*key)); +} + +void FGenericPlatformSentryTransaction::SetData(const FString& key, const TMap& values) +{ + FScopeLock Lock(&CriticalSection); + + sentry_transaction_set_data(Transaction, TCHAR_TO_ANSI(*key), FGenericPlatformSentryConverters::StringMapToNative(values)); +} + +void FGenericPlatformSentryTransaction::RemoveData(const FString& key) +{ + FScopeLock Lock(&CriticalSection); + + sentry_transaction_remove_data(Transaction, TCHAR_TO_ANSI(*key)); +} + +void FGenericPlatformSentryTransaction::GetTrace(FString& name, FString& value) +{ + sentry_value_t tracingHeader = sentry_value_new_object(); + + sentry_transaction_iter_headers(Transaction, CopyTransactionTracingHeader, &tracingHeader); + + name = TEXT("sentry-trace"); + value = FString(sentry_value_as_string(sentry_value_get_by_key(tracingHeader, "sentry-trace"))); + + sentry_value_decref(tracingHeader); +} + +#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransaction.h similarity index 60% rename from plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransaction.h index 108468937..9831103eb 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransaction.h @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. +// Copyright (c) 2023 Sentry. All Rights Reserved. #pragma once @@ -10,16 +10,16 @@ #if USE_SENTRY_NATIVE -class SentryTransactionDesktop : public ISentryTransaction +class FGenericPlatformSentryTransaction : public ISentryTransaction { public: - SentryTransactionDesktop(sentry_transaction_t* transaction); - virtual ~SentryTransactionDesktop() override; + FGenericPlatformSentryTransaction(sentry_transaction_t* transaction); + virtual ~FGenericPlatformSentryTransaction() override = default; sentry_transaction_t* GetNativeObject(); - virtual TSharedPtr StartChild(const FString& operation, const FString& desctiption) override; - virtual TSharedPtr StartChildWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) override; + virtual TSharedPtr StartChildSpan(const FString& operation, const FString& description) override; + virtual TSharedPtr StartChildSpanWithTimestamp(const FString& operation, const FString& description, int64 timestamp) override; virtual void Finish() override; virtual void FinishWithTimestamp(int64 timestamp) override; virtual bool IsFinished() const override; @@ -31,7 +31,7 @@ class SentryTransactionDesktop : public ISentryTransaction virtual void GetTrace(FString& name, FString& value) override; private: - sentry_transaction_t* TransactionDesktop; + sentry_transaction_t* Transaction; FCriticalSection CriticalSection; diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransactionContext.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransactionContext.cpp new file mode 100644 index 000000000..b00d343d4 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransactionContext.cpp @@ -0,0 +1,39 @@ +// Copyright (c) 2024 Sentry. All Rights Reserved. + +#include "GenericPlatformSentryTransactionContext.h" +#include "GenericPlatformSentryTransaction.h" + +#include "SentryDefines.h" + +#if USE_SENTRY_NATIVE + +FGenericPlatformSentryTransactionContext::FGenericPlatformSentryTransactionContext(const FString& name, const FString& operation) + : TransactionContext(sentry_transaction_context_new(TCHAR_TO_ANSI(*name), TCHAR_TO_ANSI(*operation))) +{ +} + +FGenericPlatformSentryTransactionContext::FGenericPlatformSentryTransactionContext(sentry_transaction_context_t* context) + : TransactionContext(context) +{ +} + +FString FGenericPlatformSentryTransactionContext::GetName() const +{ + // no corresponding implementation in sentry-native + UE_LOG(LogSentrySdk, Warning, TEXT("The native SDK doesn't currently support transaction's context GetName function")); + return FString(); +} + +FString FGenericPlatformSentryTransactionContext::GetOperation() const +{ + // no corresponding implementation in sentry-native + UE_LOG(LogSentrySdk, Warning, TEXT("The native SDK doesn't currently support transaction's context GetOperation function")); + return FString(); +} + +sentry_transaction_context_t* FGenericPlatformSentryTransactionContext::GetNativeObject() +{ + return TransactionContext; +} + +#endif diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransactionContext.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransactionContext.h new file mode 100644 index 000000000..e66a2b765 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransactionContext.h @@ -0,0 +1,29 @@ +// Copyright (c) 2024 Sentry. All Rights Reserved. + +#pragma once + +#include "Convenience/SentryInclude.h" + +#include "Interface/SentryTransactionContextInterface.h" + +#if USE_SENTRY_NATIVE + +class ISentryTransaction; + +class FGenericPlatformSentryTransactionContext : public ISentryTransactionContext +{ +public: + FGenericPlatformSentryTransactionContext(const FString& name, const FString& operation); + FGenericPlatformSentryTransactionContext(sentry_transaction_context_t* context); + virtual ~FGenericPlatformSentryTransactionContext() override = default; + + virtual FString GetName() const override; + virtual FString GetOperation() const override; + + sentry_transaction_context_t* GetNativeObject(); + +private: + sentry_transaction_context_t* TransactionContext; +}; + +#endif diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUser.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUser.cpp new file mode 100644 index 000000000..a6c80006a --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUser.cpp @@ -0,0 +1,94 @@ +// Copyright (c) 2022 Sentry. All Rights Reserved. + +#include "GenericPlatformSentryUser.h" + +#include "Infrastructure/GenericPlatformSentryConverters.h" + +#if USE_SENTRY_NATIVE + +FGenericPlatformSentryUser::FGenericPlatformSentryUser() +{ + User = sentry_value_new_object(); + + // Due to backwards compatibility concerns it is more reliable to initialize IP address explicitly with a specific value or "{{auto}}" + sentry_value_set_by_key(User, "ip_address", sentry_value_new_string("{{auto}}")); +} + +FGenericPlatformSentryUser::FGenericPlatformSentryUser(sentry_value_t user) +{ + User = user; +} + +FGenericPlatformSentryUser::~FGenericPlatformSentryUser() +{ + // Put custom destructor logic here if needed +} + +sentry_value_t FGenericPlatformSentryUser::GetNativeObject() +{ + return User; +} + +void FGenericPlatformSentryUser::SetEmail(const FString& email) +{ + sentry_value_set_by_key(User, "email", sentry_value_new_string(TCHAR_TO_ANSI(*email))); +} + +FString FGenericPlatformSentryUser::GetEmail() const +{ + sentry_value_t email = sentry_value_get_by_key(User, "email"); + return FString(sentry_value_as_string(email)); +} + +void FGenericPlatformSentryUser::SetId(const FString& id) +{ + sentry_value_set_by_key(User, "id", sentry_value_new_string(TCHAR_TO_ANSI(*id))); +} + +FString FGenericPlatformSentryUser::GetId() const +{ + sentry_value_t id = sentry_value_get_by_key(User, "id"); + return FString(sentry_value_as_string(id)); +} + +void FGenericPlatformSentryUser::SetUsername(const FString& username) +{ + sentry_value_set_by_key(User, "username", sentry_value_new_string(TCHAR_TO_ANSI(*username))); +} + +FString FGenericPlatformSentryUser::GetUsername() const +{ + sentry_value_t username = sentry_value_get_by_key(User, "username"); + return FString(sentry_value_as_string(username)); +} + +void FGenericPlatformSentryUser::SetIpAddress(const FString& ipAddress) +{ + if(!ipAddress.IsEmpty()) + { + sentry_value_set_by_key(User, "ip_address", sentry_value_new_string(TCHAR_TO_ANSI(*ipAddress))); + } + else + { + sentry_value_set_by_key(User, "ip_address", sentry_value_new_string("{{auto}}")); + } +} + +FString FGenericPlatformSentryUser::GetIpAddress() const +{ + sentry_value_t ip_address = sentry_value_get_by_key(User, "ip_address"); + return FString(sentry_value_as_string(ip_address)); +} + +void FGenericPlatformSentryUser::SetData(const TMap& data) +{ + sentry_value_set_by_key(User, "data", FGenericPlatformSentryConverters::StringMapToNative(data)); +} + +TMap FGenericPlatformSentryUser::GetData() +{ + sentry_value_t data = sentry_value_get_by_key(User, "data"); + return FGenericPlatformSentryConverters::StringMapToUnreal(data); +} + +#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryUserDesktop.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUser.h similarity index 78% rename from plugin-dev/Source/Sentry/Private/Desktop/SentryUserDesktop.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUser.h index d96e3e62b..0688626cc 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryUserDesktop.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUser.h @@ -8,12 +8,12 @@ #if USE_SENTRY_NATIVE -class SentryUserDesktop : public ISentryUser +class FGenericPlatformSentryUser : public ISentryUser { public: - SentryUserDesktop(); - SentryUserDesktop(sentry_value_t user); - virtual ~SentryUserDesktop() override; + FGenericPlatformSentryUser(); + FGenericPlatformSentryUser(sentry_value_t user); + virtual ~FGenericPlatformSentryUser() override; sentry_value_t GetNativeObject(); @@ -29,7 +29,7 @@ class SentryUserDesktop : public ISentryUser virtual TMap GetData() override; private: - sentry_value_t UserDesktop; + sentry_value_t User; }; #endif diff --git a/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUserFeedback.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUserFeedback.cpp new file mode 100644 index 000000000..292d411a1 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUserFeedback.cpp @@ -0,0 +1,65 @@ +// Copyright (c) 2022 Sentry. All Rights Reserved. + +#include "GenericPlatformSentryUserFeedback.h" + +#include "GenericPlatformSentryId.h" + +#include "Infrastructure/GenericPlatformSentryConverters.h" + +#if USE_SENTRY_NATIVE + +FGenericPlatformSentryUserFeedback::FGenericPlatformSentryUserFeedback() +{ + UserFeedback = sentry_value_new_object(); +} + +FGenericPlatformSentryUserFeedback::FGenericPlatformSentryUserFeedback(TSharedPtr eventId) +{ + UserFeedback = sentry_value_new_object(); + sentry_value_set_by_key(UserFeedback, "event_id", sentry_value_new_string(TCHAR_TO_ANSI(*eventId->ToString()))); +} + +FGenericPlatformSentryUserFeedback::~FGenericPlatformSentryUserFeedback() +{ + // Put custom destructor logic here if needed +} + +sentry_value_t FGenericPlatformSentryUserFeedback::GetNativeObject() +{ + return UserFeedback; +} + +void FGenericPlatformSentryUserFeedback::SetName(const FString& name) +{ + sentry_value_set_by_key(UserFeedback, "name", sentry_value_new_string(TCHAR_TO_UTF8(*name))); +} + +FString FGenericPlatformSentryUserFeedback::GetName() const +{ + sentry_value_t username = sentry_value_get_by_key(UserFeedback, "name"); + return FString(sentry_value_as_string(username)); +} + +void FGenericPlatformSentryUserFeedback::SetEmail(const FString& email) +{ + sentry_value_set_by_key(UserFeedback, "email", sentry_value_new_string(TCHAR_TO_ANSI(*email))); +} + +FString FGenericPlatformSentryUserFeedback::GetEmail() const +{ + sentry_value_t email = sentry_value_get_by_key(UserFeedback, "email"); + return FString(sentry_value_as_string(email)); +} + +void FGenericPlatformSentryUserFeedback::SetComment(const FString& comment) +{ + sentry_value_set_by_key(UserFeedback, "comments", sentry_value_new_string(TCHAR_TO_UTF8(*comment))); +} + +FString FGenericPlatformSentryUserFeedback::GetComment() const +{ + sentry_value_t comment = sentry_value_get_by_key(UserFeedback, "comments"); + return FString(sentry_value_as_string(comment)); +} + +#endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryUserFeedbackDesktop.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUserFeedback.h similarity index 68% rename from plugin-dev/Source/Sentry/Private/Desktop/SentryUserFeedbackDesktop.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUserFeedback.h index 8064806b1..ed9a50308 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryUserFeedbackDesktop.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUserFeedback.h @@ -10,12 +10,12 @@ class ISentryId; -class SentryUserFeedbackDesktop : public ISentryUserFeedback +class FGenericPlatformSentryUserFeedback : public ISentryUserFeedback { public: - SentryUserFeedbackDesktop(); - SentryUserFeedbackDesktop(TSharedPtr eventId); - virtual ~SentryUserFeedbackDesktop() override; + FGenericPlatformSentryUserFeedback(); + FGenericPlatformSentryUserFeedback(TSharedPtr eventId); + virtual ~FGenericPlatformSentryUserFeedback() override; sentry_value_t GetNativeObject(); @@ -27,7 +27,7 @@ class SentryUserFeedbackDesktop : public ISentryUserFeedback virtual FString GetComment() const override; private: - sentry_value_t UserFeedbackDesktop; + sentry_value_t UserFeedback; }; #endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/Infrastructure/SentryConvertersDesktop.cpp b/plugin-dev/Source/Sentry/Private/GenericPlatform/Infrastructure/GenericPlatformSentryConverters.cpp similarity index 65% rename from plugin-dev/Source/Sentry/Private/Desktop/Infrastructure/SentryConvertersDesktop.cpp rename to plugin-dev/Source/Sentry/Private/GenericPlatform/Infrastructure/GenericPlatformSentryConverters.cpp index 833c9e835..3b1743dc5 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/Infrastructure/SentryConvertersDesktop.cpp +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/Infrastructure/GenericPlatformSentryConverters.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2022 Sentry. All Rights Reserved. -#include "SentryConvertersDesktop.h" +#include "GenericPlatformSentryConverters.h" #include "SentryDefines.h" @@ -13,35 +13,35 @@ #if USE_SENTRY_NATIVE -sentry_level_e SentryConvertersDesktop::SentryLevelToNative(ESentryLevel level) +sentry_level_e FGenericPlatformSentryConverters::SentryLevelToNative(ESentryLevel level) { - sentry_level_e desktopLevel = {}; + sentry_level_e Level = {}; switch (level) { case ESentryLevel::Debug: - desktopLevel = SENTRY_LEVEL_DEBUG; + Level = SENTRY_LEVEL_DEBUG; break; case ESentryLevel::Info: - desktopLevel = SENTRY_LEVEL_INFO; + Level = SENTRY_LEVEL_INFO; break; case ESentryLevel::Warning: - desktopLevel = SENTRY_LEVEL_WARNING; + Level = SENTRY_LEVEL_WARNING; break; case ESentryLevel::Error: - desktopLevel = SENTRY_LEVEL_ERROR; + Level = SENTRY_LEVEL_ERROR; break; case ESentryLevel::Fatal: - desktopLevel = SENTRY_LEVEL_FATAL; + Level = SENTRY_LEVEL_FATAL; break; default: UE_LOG(LogSentrySdk, Warning, TEXT("Unknown sentry level value used. Debug will be returned.")); } - return desktopLevel; + return Level; } -sentry_value_t SentryConvertersDesktop::StringMapToNative(const TMap& map) +sentry_value_t FGenericPlatformSentryConverters::StringMapToNative(const TMap& map) { sentry_value_t sentryObject = sentry_value_new_object(); @@ -53,7 +53,7 @@ sentry_value_t SentryConvertersDesktop::StringMapToNative(const TMap& array) +sentry_value_t FGenericPlatformSentryConverters::StringArrayToNative(const TArray& array) { sentry_value_t sentryArray = sentry_value_new_list(); @@ -66,7 +66,7 @@ sentry_value_t SentryConvertersDesktop::StringArrayToNative(const TArray& callstack) +sentry_value_t FGenericPlatformSentryConverters::CallstackToNative(const TArray& callstack) { int32 framesCount = callstack.Num(); @@ -96,7 +96,7 @@ sentry_value_t SentryConvertersDesktop::CallstackToNative(const TArray(Enum->GetValueByName(FName(*levelStr))); } -ESentryLevel SentryConvertersDesktop::SentryLevelToUnreal(sentry_level_t level) +ESentryLevel FGenericPlatformSentryConverters::SentryLevelToUnreal(sentry_level_t level) { ESentryLevel Level = ESentryLevel::Debug; @@ -137,7 +137,7 @@ ESentryLevel SentryConvertersDesktop::SentryLevelToUnreal(sentry_level_t level) return Level; } -TMap SentryConvertersDesktop::StringMapToUnreal(sentry_value_t map) +TMap FGenericPlatformSentryConverters::StringMapToUnreal(sentry_value_t map) { TMap unrealMap; @@ -166,7 +166,7 @@ TMap SentryConvertersDesktop::StringMapToUnreal(sentry_value_t return unrealMap; } -TArray SentryConvertersDesktop::StringArrayToUnreal(sentry_value_t array) +TArray FGenericPlatformSentryConverters::StringArrayToUnreal(sentry_value_t array) { TArray unrealArray; @@ -192,7 +192,7 @@ TArray SentryConvertersDesktop::StringArrayToUnreal(sentry_value_t arra return unrealArray; } -FString SentryConvertersDesktop::SentryLevelToString(ESentryLevel level) +FString FGenericPlatformSentryConverters::SentryLevelToString(ESentryLevel level) { const UEnum* EnumPtr = StaticEnum(); @@ -207,7 +207,7 @@ FString SentryConvertersDesktop::SentryLevelToString(ESentryLevel level) return Result; } -TArray SentryConvertersDesktop::SentryEnvelopeToByteArray(sentry_envelope_t* envelope) +TArray FGenericPlatformSentryConverters::SentryEnvelopeToByteArray(sentry_envelope_t* envelope) { size_t size; ANSICHAR* serializedEnvelopeStr = sentry_envelope_serialize(envelope, &size); @@ -219,7 +219,7 @@ TArray SentryConvertersDesktop::SentryEnvelopeToByteArray(sentry_envelope return envelopeData; } -ELogVerbosity::Type SentryConvertersDesktop::SentryLevelToLogVerbosity(sentry_level_t level) +ELogVerbosity::Type FGenericPlatformSentryConverters::SentryLevelToLogVerbosity(sentry_level_t level) { ELogVerbosity::Type LogVerbosity = ELogVerbosity::Error; @@ -247,54 +247,4 @@ ELogVerbosity::Type SentryConvertersDesktop::SentryLevelToLogVerbosity(sentry_le return LogVerbosity; } -void SentryConvertersDesktop::SentryCrashContextToString(const sentry_ucontext_t* crashContext, TCHAR* outErrorString, int32 errorStringBufSize) -{ -#if PLATFORM_WINDOWS - - EXCEPTION_RECORD* ExceptionRecord = crashContext->exception_ptrs.ExceptionRecord; - - FString ErrorString = TEXT("Unhandled Exception: "); - -#define HANDLE_CASE(x) case x: ErrorString += TEXT(#x); break; - - switch (ExceptionRecord->ExceptionCode) - { - case EXCEPTION_ACCESS_VIOLATION: - ErrorString += TEXT("EXCEPTION_ACCESS_VIOLATION "); - if (ExceptionRecord->ExceptionInformation[0] == 0) - { - ErrorString += TEXT("reading address "); - } - else if (ExceptionRecord->ExceptionInformation[0] == 1) - { - ErrorString += TEXT("writing address "); - } - ErrorString += FString::Printf( -#if PLATFORM_64BITS - TEXT("0x%016llx") -#else - TEXT("0x%08x") -#endif - , ExceptionRecord->ExceptionInformation[1]); - break; - HANDLE_CASE(EXCEPTION_ARRAY_BOUNDS_EXCEEDED) - HANDLE_CASE(EXCEPTION_DATATYPE_MISALIGNMENT) - HANDLE_CASE(EXCEPTION_FLT_DENORMAL_OPERAND) - HANDLE_CASE(EXCEPTION_FLT_DIVIDE_BY_ZERO) - HANDLE_CASE(EXCEPTION_FLT_INVALID_OPERATION) - HANDLE_CASE(EXCEPTION_ILLEGAL_INSTRUCTION) - HANDLE_CASE(EXCEPTION_INT_DIVIDE_BY_ZERO) - HANDLE_CASE(EXCEPTION_PRIV_INSTRUCTION) - HANDLE_CASE(EXCEPTION_STACK_OVERFLOW) - default: - ErrorString += FString::Printf(TEXT("0x%08x"), (uint32)ExceptionRecord->ExceptionCode); - } - - FCString::Strncpy(outErrorString, *ErrorString, errorStringBufSize); - -#undef HANDLE_CASE - -#endif -} - #endif diff --git a/plugin-dev/Source/Sentry/Private/Desktop/Infrastructure/SentryConvertersDesktop.h b/plugin-dev/Source/Sentry/Private/GenericPlatform/Infrastructure/GenericPlatformSentryConverters.h similarity index 77% rename from plugin-dev/Source/Sentry/Private/Desktop/Infrastructure/SentryConvertersDesktop.h rename to plugin-dev/Source/Sentry/Private/GenericPlatform/Infrastructure/GenericPlatformSentryConverters.h index 233024b53..28f5e6f46 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/Infrastructure/SentryConvertersDesktop.h +++ b/plugin-dev/Source/Sentry/Private/GenericPlatform/Infrastructure/GenericPlatformSentryConverters.h @@ -3,24 +3,23 @@ #pragma once #include "SentryDataTypes.h" - -#include "Convenience/SentryInclude.h" +#include "GenericPlatform/Convenience/SentryInclude.h" #include "GenericPlatform/GenericPlatformStackWalk.h" #if USE_SENTRY_NATIVE -class SentryConvertersDesktop +class FGenericPlatformSentryConverters { public: - /** Conversions to native desktop (Windows/Mac) types */ + /** Conversions to native types */ static sentry_level_e SentryLevelToNative(ESentryLevel level); static sentry_value_t StringMapToNative(const TMap& map); static sentry_value_t StringArrayToNative(const TArray& array); static sentry_value_t AddressToNative(uint64 address); static sentry_value_t CallstackToNative(const TArray& callstack); - /** Conversions from native desktop (Windows/Mac) types */ + /** Conversions from native types */ static ESentryLevel SentryLevelToUnreal(sentry_value_t level); static ESentryLevel SentryLevelToUnreal(sentry_level_t level); static TMap StringMapToUnreal(sentry_value_t map); @@ -30,8 +29,6 @@ class SentryConvertersDesktop static FString SentryLevelToString(ESentryLevel level); static TArray SentryEnvelopeToByteArray(sentry_envelope_t* envelope); static ELogVerbosity::Type SentryLevelToLogVerbosity(sentry_level_t level); - - static void SentryCrashContextToString(const sentry_ucontext_t* crashContext, TCHAR* outErrorString, int32 errorStringBufSize); }; #endif diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryAttachment.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryAttachment.h new file mode 100644 index 000000000..17286b5e8 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryAttachment.h @@ -0,0 +1,31 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentryAttachmentAndroid.h" +#elif PLATFORM_APPLE +#include "Apple/SentryAttachmentApple.h" +#else +#include "Null/NullSentryAttachment.h" +#endif + +static TSharedPtr CreateSharedSentryAttachment(const FString& Path, const FString& Filename, const FString& ContentType) +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryAttachmentAndroid(Path, Filename, ContentType)); +#elif PLATFORM_APPLE + return MakeShareable(new SentryAttachmentApple(Path, Filename, ContentType)); +#else + return MakeShareable(new FNullSentryAttachment()); +#endif +} + +static TSharedPtr CreateSharedSentryAttachment(const TArray& Data, const FString& Filename, const FString& ContentType) +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryAttachmentAndroid(Data, Filename, ContentType)); +#elif PLATFORM_APPLE + return MakeShareable(new SentryAttachmentApple(Data, Filename, ContentType)); +#else + return MakeShareable(new FNullSentryAttachment()); +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryBreadcrumb.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryBreadcrumb.h new file mode 100644 index 000000000..030fead3f --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryBreadcrumb.h @@ -0,0 +1,22 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentryBreadcrumbAndroid.h" +#elif PLATFORM_APPLE +#include "Apple/SentryBreadcrumbApple.h" +#elif USE_SENTRY_NATIVE +#include "GenericPlatform/GenericPlatformSentryBreadcrumb.h" +#endif + +static TSharedPtr CreateSharedSentryBreadcrumb() +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryBreadcrumbAndroid); +#elif PLATFORM_APPLE + return MakeShareable(new SentryBreadcrumbApple); +#elif USE_SENTRY_NATIVE + return MakeShareable(new FGenericPlatformSentryBreadcrumb); +#else + return nullptr; +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryEvent.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryEvent.h new file mode 100644 index 000000000..e48f2c240 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryEvent.h @@ -0,0 +1,20 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentryEventAndroid.h" +#elif PLATFORM_APPLE +#include "Apple/SentryEventApple.h" +#else +#include "GenericPlatform/GenericPlatformSentryEvent.h" +#endif + +static TSharedPtr CreateSharedSentryEvent() +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryEventAndroid); +#elif PLATFORM_APPLE + return MakeShareable(new SentryEventApple); +#else + return MakeShareable(new FGenericPlatformSentryEvent); +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryHint.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryHint.h new file mode 100644 index 000000000..01181875e --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryHint.h @@ -0,0 +1,16 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentryHintAndroid.h" +#else +#include "Null/NullSentryHint.h" +#endif + +static TSharedPtr CreateSharedSentryHint() +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryHintAndroid); +#else + return MakeShareable(new FNullSentryHint); +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryId.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryId.h new file mode 100644 index 000000000..acaf25d55 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryId.h @@ -0,0 +1,20 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentryIdAndroid.h" +#elif PLATFORM_APPLE +#include "Apple/SentryIdApple.h" +#else +#include "GenericPlatform/GenericPlatformSentryId.h" +#endif + +static TSharedPtr CreateSharedSentryId() +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryIdAndroid); +#elif PLATFORM_APPLE + return MakeShareable(new SentryIdApple); +#else + return MakeShareable(new FGenericPlatformSentryId); +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentrySamplingContext.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentrySamplingContext.h new file mode 100644 index 000000000..a5420f043 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentrySamplingContext.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Null/NullSentrySamplingContext.h" + +static TSharedPtr CreateSharedSentrySamplingContext() +{ + // Sampling context is supposed to be created internally by the SDK using the platform-specific implementations. + // Currently, it doesn't provide default constructor for Apple/Android thus we can only return Null-version here. + return MakeShareable(new FNullSentrySamplingContext); +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryScope.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryScope.h new file mode 100644 index 000000000..4260f9320 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryScope.h @@ -0,0 +1,20 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentryScopeAndroid.h" +#elif PLATFORM_APPLE +#include "Apple/SentryScopeApple.h" +#else +#include "GenericPlatform/GenericPlatformSentryScope.h" +#endif + +static TSharedPtr CreateSharedSentryScope() +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryScopeAndroid); +#elif PLATFORM_APPLE + return MakeShareable(new SentryScopeApple); +#else + return MakeShareable(new FGenericPlatformSentryScope); +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentrySpan.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentrySpan.h new file mode 100644 index 000000000..97daf2644 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentrySpan.h @@ -0,0 +1,20 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentrySpanAndroid.h" +#elif PLATFORM_APPLE +#include "Apple/SentrySpanApple.h" +#else +#include "GenericPlatform/GenericPlatformSentrySpan.h" +#endif + +static TSharedPtr CreateSharedSentrySpan(const FString& Name, const FString& Operation) +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentrySpanAndroid); +#elif PLATFORM_APPLE + return MakeShareable(new SentrySpanApple); +#else + return MakeShareable(new FGenericPlatformSentrySpan); +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentrySubsystem.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentrySubsystem.h new file mode 100644 index 000000000..f5de30eaa --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentrySubsystem.h @@ -0,0 +1,11 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentrySubsystemAndroid.h" +#elif PLATFORM_IOS || PLATFORM_MAC +#include "Apple/SentrySubsystemApple.h" +#elif PLATFORM_WINDOWS +#include "Windows/WindowsSentrySubsystem.h" +#elif PLATFORM_LINUX +#include "Linux/LinuxSentrySubsystem.h" +#endif diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryTransaction.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryTransaction.h new file mode 100644 index 000000000..f9476c6b3 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryTransaction.h @@ -0,0 +1,20 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentryTransactionAndroid.h" +#elif PLATFORM_APPLE +#include "Apple/SentryTransactionApple.h" +#else +#include "GenericPlatform/GenericPlatformSentryTransaction.h" +#endif + +static TSharedPtr CreateSharedSentryTransaction() +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryTransactionAndroid); +#elif PLATFORM_APPLE + return MakeShareable(new SentryTransactionApple); +#else + return MakeShareable(new FGenericPlatformSentryTransaction); +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryTransactionContext.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryTransactionContext.h new file mode 100644 index 000000000..d8ba9a525 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryTransactionContext.h @@ -0,0 +1,20 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentryTransactionContextAndroid.h" +#elif PLATFORM_APPLE +#include "Apple/SentryTransactionContextApple.h" +#else +#include "GenericPlatform/GenericPlatformSentryTransactionContext.h" +#endif + +static TSharedPtr CreateSharedSentryTransactionContext(const FString& Name, const FString& Operation) +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryTransactionContextAndroid(Name, Operation)); +#elif PLATFORM_APPLE + return MakeShareable(new SentryTransactionContextApple(Name, Operation)); +#else + return MakeShareable(new FGenericPlatformSentryTransactionContext(Name, Operation)); +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryUser.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryUser.h new file mode 100644 index 000000000..64e210047 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryUser.h @@ -0,0 +1,20 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentryUserAndroid.h" +#elif PLATFORM_APPLE +#include "Apple/SentryUserApple.h" +#else +#include "GenericPlatform/GenericPlatformSentryUser.h" +#endif + +static TSharedPtr CreateSharedSentryUser() +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryUserAndroid); +#elif PLATFORM_APPLE + return MakeShareable(new SentryUserApple); +#else + return MakeShareable(new FGenericPlatformSentryUser); +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryUserFeedback.h b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryUserFeedback.h new file mode 100644 index 000000000..5fe867172 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/HAL/PlatformSentryUserFeedback.h @@ -0,0 +1,20 @@ +#pragma once + +#if PLATFORM_ANDROID +#include "Android/SentryUserFeedbackAndroid.h" +#elif PLATFORM_APPLE +#include "Apple/SentryUserFeedbackApple.h" +#else +#include "GenericPlatform/GenericPlatformSentryUserFeedback.h" +#endif + +static TSharedPtr CreateSharedSentryUserFeedback(TSharedPtr EventId) +{ +#if PLATFORM_ANDROID + return MakeShareable(new SentryUserFeedbackAndroid(EventId)); +#elif PLATFORM_APPLE + return MakeShareable(new SentryUserFeedbackApple(EventId)); +#else + return MakeShareable(new FGenericPlatformSentryUserFeedback(EventId)); +#endif +} diff --git a/plugin-dev/Source/Sentry/Private/Interface/SentrySpanInterface.h b/plugin-dev/Source/Sentry/Private/Interface/SentrySpanInterface.h index a3aafdfaf..90191f5ed 100644 --- a/plugin-dev/Source/Sentry/Private/Interface/SentrySpanInterface.h +++ b/plugin-dev/Source/Sentry/Private/Interface/SentrySpanInterface.h @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. +// Copyright (c) 2023 Sentry. All Rights Reserved. #pragma once diff --git a/plugin-dev/Source/Sentry/Private/Interface/SentryTransactionContextInterface.h b/plugin-dev/Source/Sentry/Private/Interface/SentryTransactionContextInterface.h index 641e3d888..354310a83 100644 --- a/plugin-dev/Source/Sentry/Private/Interface/SentryTransactionContextInterface.h +++ b/plugin-dev/Source/Sentry/Private/Interface/SentryTransactionContextInterface.h @@ -4,6 +4,8 @@ #include "CoreMinimal.h" +class ISentryTransaction; + class ISentryTransactionContext { public: @@ -11,4 +13,4 @@ class ISentryTransactionContext virtual FString GetName() const = 0; virtual FString GetOperation() const = 0; -}; \ No newline at end of file +}; diff --git a/plugin-dev/Source/Sentry/Private/Interface/SentryTransactionInterface.h b/plugin-dev/Source/Sentry/Private/Interface/SentryTransactionInterface.h index 723b38056..65547eb31 100644 --- a/plugin-dev/Source/Sentry/Private/Interface/SentryTransactionInterface.h +++ b/plugin-dev/Source/Sentry/Private/Interface/SentryTransactionInterface.h @@ -1,4 +1,4 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. +// Copyright (c) 2023 Sentry. All Rights Reserved. #pragma once @@ -11,8 +11,8 @@ class ISentryTransaction public: virtual ~ISentryTransaction() = default; - virtual TSharedPtr StartChild(const FString& operation, const FString& desctiption) = 0; - virtual TSharedPtr StartChildWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) = 0; + virtual TSharedPtr StartChildSpan(const FString& operation, const FString& desctiption) = 0; + virtual TSharedPtr StartChildSpanWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) = 0; virtual void Finish() = 0; virtual void FinishWithTimestamp(int64 timestamp) = 0; virtual bool IsFinished() const = 0; diff --git a/plugin-dev/Source/Sentry/Private/Linux/LinuxSentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/Linux/LinuxSentrySubsystem.cpp new file mode 100644 index 000000000..ce0b9a76a --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Linux/LinuxSentrySubsystem.cpp @@ -0,0 +1,34 @@ +#include "LinuxSentrySubsystem.h" + +#include "GenericPlatform/GenericPlatformOutputDevices.h" +#include "Misc/Paths.h" + +#if USE_SENTRY_NATIVE + +void FLinuxSentrySubsystem::ConfigureHandlerPath(sentry_options_t* Options) +{ + sentry_options_set_handler_path(Options, TCHAR_TO_UTF8(*GetHandlerPath())); +} + +void FLinuxSentrySubsystem::ConfigureDatabasePath(sentry_options_t* Options) +{ + sentry_options_set_database_path(Options, TCHAR_TO_UTF8(*GetDatabasePath())); +} + +void FLinuxSentrySubsystem::ConfigureLogFileAttachment(sentry_options_t* Options) +{ + const FString LogFilePath = FGenericPlatformOutputDevices::GetAbsoluteLogFilename(); + sentry_options_add_attachment(Options, TCHAR_TO_UTF8(*FPaths::ConvertRelativePathToFull(LogFilePath))); +} + +void FLinuxSentrySubsystem::ConfigureScreenshotAttachment(sentry_options_t* Options) +{ + sentry_options_add_attachment(Options, TCHAR_TO_UTF8(*GetScreenshotPath())); +} + +void FLinuxSentrySubsystem::ConfigureGpuDumpAttachment(sentry_options_t* Options) +{ + sentry_options_add_attachment(Options, TCHAR_TO_UTF8(*GetGpuDumpBackupPath())); +} + +#endif // USE_SENTRY_NATIVE diff --git a/plugin-dev/Source/Sentry/Private/Linux/LinuxSentrySubsystem.h b/plugin-dev/Source/Sentry/Private/Linux/LinuxSentrySubsystem.h new file mode 100644 index 000000000..6536dad99 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Linux/LinuxSentrySubsystem.h @@ -0,0 +1,21 @@ +#pragma once + +#if USE_SENTRY_NATIVE + +#include "GenericPlatform/GenericPlatformSentrySubsystem.h" + +class FLinuxSentrySubsystem : public FGenericPlatformSentrySubsystem +{ +protected: + virtual void ConfigureHandlerPath(sentry_options_t* Options) override; + virtual void ConfigureDatabasePath(sentry_options_t* Options) override; + virtual void ConfigureLogFileAttachment(sentry_options_t* Options) override; + virtual void ConfigureScreenshotAttachment(sentry_options_t* Options) override; + virtual void ConfigureGpuDumpAttachment(sentry_options_t* Options) override; + + virtual FString GetHandlerExecutableName() const override { return TEXT("crashpad_handler"); } +}; + +typedef FLinuxSentrySubsystem FPlatformSentrySubsystem; + +#endif // USE_SENTRY_NATIVE diff --git a/plugin-dev/Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.cpp new file mode 100644 index 000000000..a4ed5e6a5 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.cpp @@ -0,0 +1,43 @@ +#include "MicrosoftSentrySubsystem.h" + +#if USE_SENTRY_NATIVE + +#include "Misc/Paths.h" + +#include "SentryDefines.h" +#include "SentryModule.h" +#include "GenericPlatform/GenericPlatformOutputDevices.h" + +void FMicrosoftSentrySubsystem::ConfigureHandlerPath(sentry_options_t* Options) +{ + if (!FSentryModule::Get().IsMarketplaceVersion()) + { + const FString HandlerPath = GetHandlerPath(); + + if (!FPaths::FileExists(HandlerPath)) + { + UE_LOG(LogSentrySdk, Log, TEXT("Crashpad executable couldn't be found so Breakpad will be used instead. " + "Please make sure that the plugin was rebuilt to avoid initialization failure.")); + } + + sentry_options_set_handler_pathw(Options, *HandlerPath); + } +} + +void FMicrosoftSentrySubsystem::ConfigureDatabasePath(sentry_options_t* Options) +{ + sentry_options_set_database_pathw(Options, *GetDatabasePath()); +} + +void FMicrosoftSentrySubsystem::ConfigureLogFileAttachment(sentry_options_t* Options) +{ + const FString LogFilePath = FGenericPlatformOutputDevices::GetAbsoluteLogFilename(); + sentry_options_add_attachmentw(Options, *FPaths::ConvertRelativePathToFull(LogFilePath)); +} + +void FMicrosoftSentrySubsystem::ConfigureScreenshotAttachment(sentry_options_t* Options) +{ + sentry_options_add_attachmentw(Options, *GetScreenshotPath()); +} + +#endif // USE_SENTRY_NATIVE diff --git a/plugin-dev/Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.h b/plugin-dev/Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.h new file mode 100644 index 000000000..e3c8078a6 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.h @@ -0,0 +1,23 @@ +#pragma once + +#if USE_SENTRY_NATIVE + +#include "Misc/EngineVersionComparison.h" + +#include "GenericPlatform/GenericPlatformSentrySubsystem.h" + +class FMicrosoftSentrySubsystem : public FGenericPlatformSentrySubsystem +{ +protected: + virtual void ConfigureHandlerPath(sentry_options_t* Options) override; + virtual void ConfigureDatabasePath(sentry_options_t* Options) override; + virtual void ConfigureLogFileAttachment(sentry_options_t* Options) override; + virtual void ConfigureScreenshotAttachment(sentry_options_t* Options) override; + +#if !UE_VERSION_OLDER_THAN(5, 3, 0) + virtual int32 GetEnsureFramesToSkip() const override { return 8; } +#endif // !UE_VERSION_OLDER_THAN(5, 3, 0) + virtual int32 GetAssertionFramesToSkip() const override { return 7; } +}; + +#endif // USE_SENTRY_NATIVE diff --git a/plugin-dev/Source/Sentry/Private/Null/NullSentryAttachment.h b/plugin-dev/Source/Sentry/Private/Null/NullSentryAttachment.h new file mode 100644 index 000000000..8a57d0d57 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Null/NullSentryAttachment.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Interface/SentryAttachmentInterface.h" + +class FNullSentryAttachment final : public ISentryAttachment +{ +public: + virtual ~FNullSentryAttachment() override = default; + + virtual TArray GetData() const override { return {}; } + virtual FString GetPath() const override { return TEXT(""); } + virtual FString GetFilename() const override { return TEXT(""); } + virtual FString GetContentType() const override { return TEXT(""); } +}; diff --git a/plugin-dev/Source/Sentry/Private/Null/NullSentryHint.h b/plugin-dev/Source/Sentry/Private/Null/NullSentryHint.h new file mode 100644 index 000000000..9194985c0 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Null/NullSentryHint.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Interface/SentryHintInterface.h" + +class ISentryAttachment; + +class FNullSentryHint final : public ISentryHint +{ +public: + virtual ~FNullSentryHint() override = default; + + virtual void AddAttachment(TSharedPtr attachment) override {} +}; diff --git a/plugin-dev/Source/Sentry/Private/Null/NullSentrySamplingContext.h b/plugin-dev/Source/Sentry/Private/Null/NullSentrySamplingContext.h new file mode 100644 index 000000000..799b0d24e --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Null/NullSentrySamplingContext.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Interface/SentrySamplingContextInterface.h" + +class FNullSentrySamplingContext final : public ISentrySamplingContext +{ +public: + virtual ~FNullSentrySamplingContext() override = default; + + virtual TSharedPtr GetTransactionContext() const override { return nullptr; } + virtual TMap GetCustomSamplingContext() const override { return {}; } +}; diff --git a/plugin-dev/Source/Sentry/Private/SentryAttachment.cpp b/plugin-dev/Source/Sentry/Private/SentryAttachment.cpp index 4ef55f98a..901da8076 100644 --- a/plugin-dev/Source/Sentry/Private/SentryAttachment.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryAttachment.cpp @@ -2,70 +2,46 @@ #include "SentryAttachment.h" -#include "Interface/SentryAttachmentInterface.h" +#include "HAL/PlatformSentryAttachment.h" -#if PLATFORM_ANDROID -#include "Android/SentryAttachmentAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentryAttachmentApple.h" -#endif - -void USentryAttachment::InitializeWithData(const TArray& Data, const FString& Filename, const FString& ContentType) +void USentryAttachment::InitializeWithData(const TArray& Data, const FString& Filename, const FString& ContentType /* = FString(TEXT("application/octet-stream")) */) { -#if PLATFORM_ANDROID - AttachmentNativeImpl = MakeShareable(new SentryAttachmentAndroid(Data, Filename, ContentType)); -#elif PLATFORM_IOS || PLATFORM_MAC - AttachmentNativeImpl = MakeShareable(new SentryAttachmentApple(Data, Filename, ContentType)); -#endif + NativeImpl = CreateSharedSentryAttachment(Data, Filename, ContentType); } -void USentryAttachment::InitializeWithPath(const FString& Path, const FString& Filename, const FString& ContentType) +void USentryAttachment::InitializeWithPath(const FString& Path, const FString& Filename, const FString& ContentType /* = FString(TEXT("application/octet-stream")) */) { -#if PLATFORM_ANDROID - AttachmentNativeImpl = MakeShareable(new SentryAttachmentAndroid(Path, Filename, ContentType)); -#elif PLATFORM_IOS || PLATFORM_MAC - AttachmentNativeImpl = MakeShareable(new SentryAttachmentApple(Path, Filename, ContentType)); -#endif + NativeImpl = CreateSharedSentryAttachment(Path, Filename, ContentType); } TArray USentryAttachment::GetData() const { - if(!AttachmentNativeImpl) + if(!NativeImpl) return TArray(); - return AttachmentNativeImpl->GetData(); + return NativeImpl->GetData(); } FString USentryAttachment::GetPath() const { - if(!AttachmentNativeImpl) + if(!NativeImpl) return FString(); - return AttachmentNativeImpl->GetPath(); + return NativeImpl->GetPath(); } FString USentryAttachment::GetFilename() const { - if(!AttachmentNativeImpl) + if(!NativeImpl) return FString(); - return AttachmentNativeImpl->GetFilename(); + return NativeImpl->GetFilename(); } FString USentryAttachment::GetContentType() const { - if(!AttachmentNativeImpl) + if(!NativeImpl) return FString(); - return AttachmentNativeImpl->GetContentType(); -} - -void USentryAttachment::InitWithNativeImpl(TSharedPtr attachmentImpl) -{ - AttachmentNativeImpl = attachmentImpl; -} - -TSharedPtr USentryAttachment::GetNativeImpl() -{ - return AttachmentNativeImpl; + return NativeImpl->GetContentType(); } diff --git a/plugin-dev/Source/Sentry/Private/SentryBeforeSendHandler.cpp b/plugin-dev/Source/Sentry/Private/SentryBeforeSendHandler.cpp index 9448346de..f401826c1 100644 --- a/plugin-dev/Source/Sentry/Private/SentryBeforeSendHandler.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryBeforeSendHandler.cpp @@ -2,6 +2,7 @@ #include "SentryBeforeSendHandler.h" +#include "SentryLibrary.h" #include "SentryModule.h" #include "SentrySettings.h" #include "SentryEvent.h" @@ -16,7 +17,7 @@ USentryEvent* USentryBeforeSendHandler::HandleBeforeSend_Implementation(USentryE { const USentrySettings* Settings = FSentryModule::Get().GetSettings(); - if(Settings->EnableAutoLogAttachment) + if (Settings->EnableAutoLogAttachment && Hint != nullptr) { #if PLATFORM_ANDROID || PLATFORM_APPLE const FString LogFilePath = Event->IsCrash() ? SentryFileUtils::GetGameLogBackupPath() : SentryFileUtils::GetGameLogPath(); @@ -24,13 +25,13 @@ USentryEvent* USentryBeforeSendHandler::HandleBeforeSend_Implementation(USentryE const FString LogFilePath = SentryFileUtils::GetGameLogPath(); #endif - USentryAttachment* Attachment = NewObject(); - Attachment->InitializeWithPath(LogFilePath, FPaths::GetCleanFilename(LogFilePath), TEXT("text/plain")); - - if(Hint != nullptr) - { - Hint->AddAttachment(Attachment); - } + Hint->AddAttachment( + USentryLibrary::CreateSentryAttachmentWithPath( + LogFilePath, + FPaths::GetCleanFilename(LogFilePath), + TEXT("text/plain") + ) + ); } return Event; diff --git a/plugin-dev/Source/Sentry/Private/SentryBreadcrumb.cpp b/plugin-dev/Source/Sentry/Private/SentryBreadcrumb.cpp index bff2b8931..f7ddb3fbf 100644 --- a/plugin-dev/Source/Sentry/Private/SentryBreadcrumb.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryBreadcrumb.cpp @@ -2,116 +2,89 @@ #include "SentryBreadcrumb.h" -#include "Interface/SentryBreadcrumbInterface.h" +#include "HAL/PlatformSentryBreadcrumb.h" -#if PLATFORM_ANDROID -#include "Android/SentryBreadcrumbAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentryBreadcrumbApple.h" -#elif PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentryBreadcrumbDesktop.h" -#endif - -USentryBreadcrumb::USentryBreadcrumb() +void USentryBreadcrumb::Initialize() { - if (USentryBreadcrumb::StaticClass()->GetDefaultObject() != this) - { -#if PLATFORM_ANDROID - BreadcrumbNativeImpl = MakeShareable(new SentryBreadcrumbAndroid()); -#elif PLATFORM_IOS || PLATFORM_MAC - BreadcrumbNativeImpl = MakeShareable(new SentryBreadcrumbApple()); -#elif (PLATFORM_WINDOWS || PLATFORM_LINUX) && USE_SENTRY_NATIVE - BreadcrumbNativeImpl = MakeShareable(new SentryBreadcrumbDesktop()); -#endif - } + NativeImpl = CreateSharedSentryBreadcrumb(); } -void USentryBreadcrumb::SetMessage(const FString& Message) +void USentryBreadcrumb::SetMessage(const FString &Message) { - if (!BreadcrumbNativeImpl) + if (!NativeImpl) return; - BreadcrumbNativeImpl->SetMessage(Message); + NativeImpl->SetMessage(Message); } FString USentryBreadcrumb::GetMessage() const { - if(!BreadcrumbNativeImpl) + if(!NativeImpl) return FString(); - return BreadcrumbNativeImpl->GetMessage(); + return NativeImpl->GetMessage(); } void USentryBreadcrumb::SetType(const FString& Type) { - if (!BreadcrumbNativeImpl) + if (!NativeImpl) return; - BreadcrumbNativeImpl->SetType(Type); + NativeImpl->SetType(Type); } FString USentryBreadcrumb::GetType() const { - if(!BreadcrumbNativeImpl) + if(!NativeImpl) return FString(); - return BreadcrumbNativeImpl->GetType(); + return NativeImpl->GetType(); } void USentryBreadcrumb::SetCategory(const FString& Category) { - if (!BreadcrumbNativeImpl) + if (!NativeImpl) return; - BreadcrumbNativeImpl->SetCategory(Category); + NativeImpl->SetCategory(Category); } FString USentryBreadcrumb::GetCategory() const { - if(!BreadcrumbNativeImpl) + if(!NativeImpl) return FString(); - return BreadcrumbNativeImpl->GetCategory(); + return NativeImpl->GetCategory(); } void USentryBreadcrumb::SetData(const TMap& Data) { - if (!BreadcrumbNativeImpl) + if (!NativeImpl) return; - BreadcrumbNativeImpl->SetData(Data); + NativeImpl->SetData(Data); } TMap USentryBreadcrumb::GetData() const { - if(!BreadcrumbNativeImpl) + if(!NativeImpl) return TMap(); - return BreadcrumbNativeImpl->GetData(); + return NativeImpl->GetData(); } void USentryBreadcrumb::SetLevel(ESentryLevel Level) { - if (!BreadcrumbNativeImpl) + if (!NativeImpl) return; - BreadcrumbNativeImpl->SetLevel(Level); + NativeImpl->SetLevel(Level); } ESentryLevel USentryBreadcrumb::GetLevel() const { - if(!BreadcrumbNativeImpl) + if(!NativeImpl) return ESentryLevel::Debug; - return BreadcrumbNativeImpl->GetLevel(); -} - -void USentryBreadcrumb::InitWithNativeImpl(TSharedPtr breadcrumbImpl) -{ - BreadcrumbNativeImpl = breadcrumbImpl; -} - -TSharedPtr USentryBreadcrumb::GetNativeImpl() -{ - return BreadcrumbNativeImpl; + return NativeImpl->GetLevel(); } diff --git a/plugin-dev/Source/Sentry/Private/SentryEvent.cpp b/plugin-dev/Source/Sentry/Private/SentryEvent.cpp index 662e2ce1f..8e8f755b8 100644 --- a/plugin-dev/Source/Sentry/Private/SentryEvent.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryEvent.cpp @@ -2,101 +2,60 @@ #include "SentryEvent.h" -#include "Interface/SentryEventInterface.h" +#include "HAL/PlatformSentryEvent.h" -#if PLATFORM_ANDROID -#include "Android/SentryEventAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentryEventApple.h" -#elif PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentryEventDesktop.h" -#endif - -USentryEvent::USentryEvent() -{ - if (USentryEvent::StaticClass()->GetDefaultObject() != this) - { -#if PLATFORM_ANDROID - EventNativeImpl = MakeShareable(new SentryEventAndroid()); -#elif PLATFORM_IOS || PLATFORM_MAC - EventNativeImpl = MakeShareable(new SentryEventApple()); -#elif (PLATFORM_WINDOWS || PLATFORM_LINUX) && USE_SENTRY_NATIVE - EventNativeImpl = MakeShareable(new SentryEventDesktop()); -#endif - } -} - -USentryEvent* USentryEvent::CreateEventWithMessageAndLevel(const FString& Message, ESentryLevel Level) +void USentryEvent::Initialize(const FString& Message, ESentryLevel Level) { - USentryEvent* Event = NewObject(); + NativeImpl = CreateSharedSentryEvent(); - if(!Message.IsEmpty()) - { - Event->SetMessage(Message); - } - - Event->SetLevel(Level); - - return Event; + SetMessage(Message); + SetLevel(Level); } -void USentryEvent::SetMessage(const FString& Message) +void USentryEvent::SetMessage(const FString &Message) { - if (!EventNativeImpl) + if (!NativeImpl) return; - EventNativeImpl->SetMessage(Message); + NativeImpl->SetMessage(Message); } FString USentryEvent::GetMessage() const { - if(!EventNativeImpl) + if(!NativeImpl) return FString(); - return EventNativeImpl->GetMessage(); + return NativeImpl->GetMessage(); } void USentryEvent::SetLevel(ESentryLevel Level) { - if (!EventNativeImpl) + if (!NativeImpl) return; - EventNativeImpl->SetLevel(Level); + NativeImpl->SetLevel(Level); } ESentryLevel USentryEvent::GetLevel() const { - if(!EventNativeImpl) + if(!NativeImpl) return ESentryLevel::Debug; - return EventNativeImpl->GetLevel(); + return NativeImpl->GetLevel(); } bool USentryEvent::IsCrash() const { - if(!EventNativeImpl) + if(!NativeImpl) return false; - return EventNativeImpl->IsCrash(); + return NativeImpl->IsCrash(); } bool USentryEvent::IsAnr() const { - if(!EventNativeImpl) + if(!NativeImpl) return false; - return EventNativeImpl->IsAnr(); -} - -void USentryEvent::InitWithNativeImpl(TSharedPtr eventImpl) -{ - if (!EventNativeImpl) - return; - - EventNativeImpl = eventImpl; -} - -TSharedPtr USentryEvent::GetNativeImpl() -{ - return EventNativeImpl; + return NativeImpl->IsAnr(); } diff --git a/plugin-dev/Source/Sentry/Private/SentryHint.cpp b/plugin-dev/Source/Sentry/Private/SentryHint.cpp index b4d98a76c..0af0bc8cd 100644 --- a/plugin-dev/Source/Sentry/Private/SentryHint.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryHint.cpp @@ -3,36 +3,17 @@ #include "SentryHint.h" #include "SentryAttachment.h" -#include "Interface/SentryHintInterface.h" +#include "HAL/PlatformSentryHint.h" -#if PLATFORM_ANDROID -#include "Android/SentryHintAndroid.h" -#endif - -USentryHint::USentryHint() +void USentryHint::Initialize() { - if (USentryHint::StaticClass()->GetDefaultObject() != this) - { -#if PLATFORM_ANDROID - SentryHintNativeImpl = MakeShareable(new SentryHintAndroid()); -#endif - } + NativeImpl = CreateSharedSentryHint(); } void USentryHint::AddAttachment(USentryAttachment* Attachment) { - if(!SentryHintNativeImpl) + if(!NativeImpl) return; - SentryHintNativeImpl->AddAttachment(Attachment->GetNativeImpl()); -} - -void USentryHint::InitWithNativeImpl(TSharedPtr hintImpl) -{ - SentryHintNativeImpl = hintImpl; -} - -TSharedPtr USentryHint::GetNativeImpl() -{ - return SentryHintNativeImpl; + NativeImpl->AddAttachment(Attachment->GetNativeObject()); } diff --git a/plugin-dev/Source/Sentry/Private/SentryId.cpp b/plugin-dev/Source/Sentry/Private/SentryId.cpp index 95ee4f818..46c62f5c9 100644 --- a/plugin-dev/Source/Sentry/Private/SentryId.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryId.cpp @@ -2,44 +2,17 @@ #include "SentryId.h" -#include "Interface/SentryIdInterface.h" +#include "HAL/PlatformSentryId.h" -#if PLATFORM_ANDROID -#include "Android/SentryIdAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentryIdApple.h" -#elif PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentryIdDesktop.h" -#endif - -USentryId::USentryId() +void USentryId::Initialize() { - if (USentryId::StaticClass()->GetDefaultObject() != this) - { -#if PLATFORM_ANDROID - SentryIdNativeImpl = MakeShareable(new SentryIdAndroid()); -#elif PLATFORM_IOS || PLATFORM_MAC - SentryIdNativeImpl = MakeShareable(new SentryIdApple()); -#elif (PLATFORM_WINDOWS || PLATFORM_LINUX) && USE_SENTRY_NATIVE - SentryIdNativeImpl = MakeShareable(new SentryIdDesktop()); -#endif - } + NativeImpl = CreateSharedSentryId(); } FString USentryId::ToString() const { - if(!SentryIdNativeImpl) + if(!NativeImpl) return FString(); - return SentryIdNativeImpl->ToString(); -} - -void USentryId::InitWithNativeImpl(TSharedPtr idImpl) -{ - SentryIdNativeImpl = idImpl; -} - -TSharedPtr USentryId::GetNativeImpl() -{ - return SentryIdNativeImpl; + return NativeImpl->ToString(); } diff --git a/plugin-dev/Source/Sentry/Private/SentryLibrary.cpp b/plugin-dev/Source/Sentry/Private/SentryLibrary.cpp index e48be98f5..548b09f88 100644 --- a/plugin-dev/Source/Sentry/Private/SentryLibrary.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryLibrary.cpp @@ -9,15 +9,22 @@ #include "SentryAttachment.h" #include "SentryTransactionContext.h" +#include "HAL/PlatformSentryAttachment.h" +#include "HAL/PlatformSentryBreadcrumb.h" +#include "HAL/PlatformSentryEvent.h" +#include "HAL/PlatformSentryTransactionContext.h" +#include "HAL/PlatformSentryUser.h" +#include "HAL/PlatformSentryUserFeedback.h" + #include "HAL/FileManager.h" #include "Misc/FileHelper.h" #include "Misc/Paths.h" USentryEvent* USentryLibrary::CreateSentryEvent(const FString& Message, ESentryLevel Level) { - USentryEvent* Event = NewObject(); + USentryEvent* Event = USentryEvent::Create(CreateSharedSentryEvent()); - if(!Message.IsEmpty()) + if (!Message.IsEmpty()) Event->SetMessage(Message); Event->SetLevel(Level); @@ -27,18 +34,18 @@ USentryEvent* USentryLibrary::CreateSentryEvent(const FString& Message, ESentryL USentryUser* USentryLibrary::CreateSentryUser(const FString& Email, const FString& Id, const FString& Username, const FString& IpAddress, const TMap& Data) { - USentryUser* User = NewObject(); + USentryUser* User = USentryUser::Create(CreateSharedSentryUser()); - if(!Email.IsEmpty()) + if (!Email.IsEmpty()) User->SetEmail(Email); - if(!Id.IsEmpty()) + if (!Id.IsEmpty()) User->SetId(Id); - if(!Username.IsEmpty()) + if (!Username.IsEmpty()) User->SetUsername(Username); - if(!IpAddress.IsEmpty()) + if (!IpAddress.IsEmpty()) User->SetIpAddress(IpAddress); - if(Data.Num() > 0) + if (Data.Num() > 0) User->SetData(Data); return User; @@ -46,15 +53,13 @@ USentryUser* USentryLibrary::CreateSentryUser(const FString& Email, const FStrin USentryUserFeedback* USentryLibrary::CreateSentryUserFeedback(USentryId* EventId, const FString& Name, const FString& Email, const FString& Comments) { - USentryUserFeedback* UserFeedback = NewObject(); - - UserFeedback->Initialize(EventId); + USentryUserFeedback* UserFeedback = USentryUserFeedback::Create(CreateSharedSentryUserFeedback(EventId->GetNativeObject())); - if(!Name.IsEmpty()) + if (!Name.IsEmpty()) UserFeedback->SetName(Name); - if(!Email.IsEmpty()) + if (!Email.IsEmpty()) UserFeedback->SetEmail(Email); - if(!Comments.IsEmpty()) + if (!Comments.IsEmpty()) UserFeedback->SetComment(Comments); return UserFeedback; @@ -63,7 +68,7 @@ USentryUserFeedback* USentryLibrary::CreateSentryUserFeedback(USentryId* EventId USentryBreadcrumb* USentryLibrary::CreateSentryBreadcrumb(const FString& Message, const FString& Type, const FString& Category, const TMap& Data, ESentryLevel Level) { - USentryBreadcrumb* Breadcrumb = NewObject(); + USentryBreadcrumb* Breadcrumb = USentryBreadcrumb::Create(CreateSharedSentryBreadcrumb()); Breadcrumb->SetMessage(Message); Breadcrumb->SetCategory(Category); @@ -76,23 +81,17 @@ USentryBreadcrumb* USentryLibrary::CreateSentryBreadcrumb(const FString& Message USentryAttachment* USentryLibrary::CreateSentryAttachmentWithData(const TArray& Data, const FString& Filename, const FString& ContentType) { - USentryAttachment* Attachment = NewObject(); - Attachment->InitializeWithData(Data, Filename, ContentType); - return Attachment; + return USentryAttachment::Create(CreateSharedSentryAttachment(Data, Filename, ContentType)); } USentryAttachment* USentryLibrary::CreateSentryAttachmentWithPath(const FString& Path, const FString& Filename, const FString& ContentType) { - USentryAttachment* Attachment = NewObject(); - Attachment->InitializeWithPath(Path, Filename, ContentType); - return Attachment; + return USentryAttachment::Create(CreateSharedSentryAttachment(Path, Filename, ContentType)); } USentryTransactionContext* USentryLibrary::CreateSentryTransactionContext(const FString& Name, const FString& Operation) { - USentryTransactionContext* TransactionContext = NewObject(); - TransactionContext->Initialize(Name, Operation); - return TransactionContext; + return USentryTransactionContext::Create(CreateSharedSentryTransactionContext(Name, Operation)); } TArray USentryLibrary::StringToBytesArray(const FString& InString) @@ -105,9 +104,9 @@ TArray USentryLibrary::StringToBytesArray(const FString& InString) int32 NumBytes = 0; const TCHAR* CharPos = *InString; - while( *CharPos && NumBytes < TNumericLimits::Max()) + while (*CharPos && NumBytes < TNumericLimits::Max()) { - byteArrayPtr[ NumBytes ] = (int8)(*CharPos); + byteArrayPtr[NumBytes] = (int8)(*CharPos); CharPos++; ++NumBytes; } diff --git a/plugin-dev/Source/Sentry/Private/SentryModule.cpp b/plugin-dev/Source/Sentry/Private/SentryModule.cpp index 2de321068..100100407 100644 --- a/plugin-dev/Source/Sentry/Private/SentryModule.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryModule.cpp @@ -1,128 +1,128 @@ -// Copyright (c) 2022 Sentry. All Rights Reserved. - -#include "SentryModule.h" -#include "SentryDefines.h" -#include "SentrySettings.h" - -#include "UObject/Package.h" -#include "UObject/UObjectGlobals.h" -#include "Interfaces/IPluginManager.h" -#include "Modules/ModuleManager.h" -#include "Developer/Settings/Public/ISettingsModule.h" -#include "Misc/Paths.h" - -#define LOCTEXT_NAMESPACE "FSentryModule" - -const FName FSentryModule::ModuleName = "Sentry"; - -const bool FSentryModule::IsMarketplace = false; - -void FSentryModule::StartupModule() -{ - // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module - SentrySettings = NewObject(GetTransientPackage(), "SentrySettings", RF_Standalone); - SentrySettings->AddToRoot(); - - if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings")) - { - SettingsModule->RegisterSettings("Project", "Plugins", "Sentry", - LOCTEXT("RuntimeSettingsName", "Sentry"), - LOCTEXT("RuntimeSettingsDescription", "Configure Sentry"), - SentrySettings); - } - -#if PLATFORM_MAC - const FString SentryLibName = TEXT("sentry.dylib"); - const FString BinariesDirPath = GIsEditor ? FPaths::Combine(GetThirdPartyPath(), TEXT("bin")) : GetBinariesPath(); - - FPlatformProcess::PushDllDirectory(*BinariesDirPath); - mDllHandleSentry = FPlatformProcess::GetDllHandle(*FPaths::Combine(BinariesDirPath, SentryLibName)); - FPlatformProcess::PopDllDirectory(*BinariesDirPath); -#endif -} - -void FSentryModule::ShutdownModule() -{ - // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, - // we call this function before unloading the module. - - if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings")) - { - SettingsModule->UnregisterSettings("Project", "Plugins", "Sentry"); - } - - if (!GExitPurge) - { - // If we're in exit purge, this object has already been destroyed - SentrySettings->RemoveFromRoot(); - } - else - { - SentrySettings = nullptr; - } - -#if PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX - if (mDllHandleSentry) - { - FPlatformProcess::FreeDllHandle(mDllHandleSentry); - mDllHandleSentry = nullptr; - } -#endif -} - -FSentryModule& FSentryModule::Get() -{ - return FModuleManager::LoadModuleChecked(ModuleName); -} - -bool FSentryModule::IsAvailable() -{ - return FModuleManager::Get().IsModuleLoaded(ModuleName); -} - -void* FSentryModule::GetSentryLibHandle() const -{ - return mDllHandleSentry; -} - -USentrySettings* FSentryModule::GetSettings() const -{ - return SentrySettings; -} - -FString FSentryModule::GetBinariesPath() -{ - const FString PluginDir = IPluginManager::Get().FindPlugin(TEXT("Sentry"))->GetBaseDir(); - - return FPaths::Combine(PluginDir, TEXT("Binaries"), FPlatformProcess::GetBinariesSubdirectory()); -} - -FString FSentryModule::GetThirdPartyPath() -{ - const FString PluginDir = IPluginManager::Get().FindPlugin(TEXT("Sentry"))->GetBaseDir(); - - return FPaths::Combine(PluginDir, TEXT("Source"), TEXT("ThirdParty"), FPlatformProcess::GetBinariesSubdirectory()); -} - -FString FSentryModule::GetPluginVersion() -{ - TSharedPtr plugin = IPluginManager::Get().FindPlugin(TEXT("Sentry")); - - if(!plugin) - { - return FString(); - } - - return plugin->GetDescriptor().VersionName; -} - -bool FSentryModule::IsMarketplaceVersion() -{ - return IsMarketplace; -} - -#undef LOCTEXT_NAMESPACE - -IMPLEMENT_MODULE(FSentryModule, Sentry) - -DEFINE_LOG_CATEGORY(LogSentrySdk); \ No newline at end of file +// Copyright (c) 2022 Sentry. All Rights Reserved. + +#include "SentryModule.h" +#include "SentryDefines.h" +#include "SentrySettings.h" + +#include "UObject/Package.h" +#include "UObject/UObjectGlobals.h" +#include "Interfaces/IPluginManager.h" +#include "Modules/ModuleManager.h" +#include "Developer/Settings/Public/ISettingsModule.h" +#include "Misc/Paths.h" + +#define LOCTEXT_NAMESPACE "FSentryModule" + +const FName FSentryModule::ModuleName = "Sentry"; + +const bool FSentryModule::IsMarketplace = false; + +void FSentryModule::StartupModule() +{ + // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module + SentrySettings = NewObject(GetTransientPackage(), "SentrySettings", RF_Standalone); + SentrySettings->AddToRoot(); + + if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings")) + { + SettingsModule->RegisterSettings("Project", "Plugins", "Sentry", + LOCTEXT("RuntimeSettingsName", "Sentry"), + LOCTEXT("RuntimeSettingsDescription", "Configure Sentry"), + SentrySettings); + } + +#if PLATFORM_MAC + const FString SentryLibName = TEXT("sentry.dylib"); + const FString BinariesDirPath = GIsEditor ? FPaths::Combine(GetThirdPartyPath(), TEXT("bin")) : GetBinariesPath(); + + FPlatformProcess::PushDllDirectory(*BinariesDirPath); + mDllHandleSentry = FPlatformProcess::GetDllHandle(*FPaths::Combine(BinariesDirPath, SentryLibName)); + FPlatformProcess::PopDllDirectory(*BinariesDirPath); +#endif +} + +void FSentryModule::ShutdownModule() +{ + // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, + // we call this function before unloading the module. + + if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings")) + { + SettingsModule->UnregisterSettings("Project", "Plugins", "Sentry"); + } + + if (!GExitPurge) + { + // If we're in exit purge, this object has already been destroyed + SentrySettings->RemoveFromRoot(); + } + else + { + SentrySettings = nullptr; + } + +#if PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX + if (mDllHandleSentry) + { + FPlatformProcess::FreeDllHandle(mDllHandleSentry); + mDllHandleSentry = nullptr; + } +#endif +} + +FSentryModule& FSentryModule::Get() +{ + return FModuleManager::LoadModuleChecked(ModuleName); +} + +bool FSentryModule::IsAvailable() +{ + return FModuleManager::Get().IsModuleLoaded(ModuleName); +} + +void* FSentryModule::GetSentryLibHandle() const +{ + return mDllHandleSentry; +} + +USentrySettings* FSentryModule::GetSettings() const +{ + return SentrySettings; +} + +FString FSentryModule::GetBinariesPath() +{ + const FString PluginDir = IPluginManager::Get().FindPlugin(TEXT("Sentry"))->GetBaseDir(); + + return FPaths::Combine(PluginDir, TEXT("Binaries"), FPlatformProcess::GetBinariesSubdirectory()); +} + +FString FSentryModule::GetThirdPartyPath() +{ + const FString PluginDir = IPluginManager::Get().FindPlugin(TEXT("Sentry"))->GetBaseDir(); + + return FPaths::Combine(PluginDir, TEXT("Source"), TEXT("ThirdParty"), FPlatformProcess::GetBinariesSubdirectory()); +} + +FString FSentryModule::GetPluginVersion() +{ + TSharedPtr plugin = IPluginManager::Get().FindPlugin(TEXT("Sentry")); + + if(!plugin) + { + return FString(); + } + + return plugin->GetDescriptor().VersionName; +} + +bool FSentryModule::IsMarketplaceVersion() +{ + return IsMarketplace; +} + +#undef LOCTEXT_NAMESPACE + +IMPLEMENT_MODULE(FSentryModule, Sentry) + +DEFINE_LOG_CATEGORY(LogSentrySdk); diff --git a/plugin-dev/Source/Sentry/Private/SentrySamplingContext.cpp b/plugin-dev/Source/Sentry/Private/SentrySamplingContext.cpp index 70d9861f4..ebb829e1d 100644 --- a/plugin-dev/Source/Sentry/Private/SentrySamplingContext.cpp +++ b/plugin-dev/Source/Sentry/Private/SentrySamplingContext.cpp @@ -3,45 +3,27 @@ #include "SentrySamplingContext.h" #include "SentryTransactionContext.h" -#include "Interface/SentrySamplingContextInterface.h" +#include "HAL/PlatformSentrySamplingContext.h" -#if PLATFORM_ANDROID -#include "Android/SentrySamplingContextAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentrySamplingContextApple.h" -#endif - -USentrySamplingContext::USentrySamplingContext() +void USentrySamplingContext::Initialize() { + NativeImpl = CreateSharedSentrySamplingContext(); } USentryTransactionContext* USentrySamplingContext::GetTransactionContext() const { - if (!SentrySamplingContextNativeImpl) + if (!NativeImpl) return nullptr; - TSharedPtr transactionContextNativeImpl = SentrySamplingContextNativeImpl->GetTransactionContext(); - - USentryTransactionContext* unrealTransactionContext = NewObject(); - unrealTransactionContext->InitWithNativeImpl(transactionContextNativeImpl); + TSharedPtr transactionContextNativeImpl = NativeImpl->GetTransactionContext(); - return unrealTransactionContext; + return USentryTransactionContext::Create(transactionContextNativeImpl); } TMap USentrySamplingContext::GetCustomSamplingContext() const { - if (!SentrySamplingContextNativeImpl) + if (!NativeImpl) return TMap(); - return SentrySamplingContextNativeImpl->GetCustomSamplingContext(); -} - -void USentrySamplingContext::InitWithNativeImpl(TSharedPtr samplingContextImpl) -{ - SentrySamplingContextNativeImpl = samplingContextImpl; -} - -TSharedPtr USentrySamplingContext::GetNativeImpl() -{ - return SentrySamplingContextNativeImpl; + return NativeImpl->GetCustomSamplingContext(); } diff --git a/plugin-dev/Source/Sentry/Private/SentryScope.cpp b/plugin-dev/Source/Sentry/Private/SentryScope.cpp index 65db7513c..ea9c71791 100644 --- a/plugin-dev/Source/Sentry/Private/SentryScope.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryScope.cpp @@ -4,239 +4,209 @@ #include "SentryBreadcrumb.h" #include "SentryAttachment.h" -#include "Interface/SentryScopeInterface.h" - -#if PLATFORM_ANDROID -#include "Android/SentryScopeAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentryScopeApple.h" -#elif PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentryScopeDesktop.h" -#endif - -USentryScope::USentryScope() -{ - if (USentryScope::StaticClass()->GetDefaultObject() != this) - { -#if PLATFORM_ANDROID - ScopeNativeImpl = MakeShareable(new SentryScopeAndroid()); -#elif PLATFORM_IOS || PLATFORM_MAC - ScopeNativeImpl = MakeShareable(new SentryScopeApple()); -#elif (PLATFORM_WINDOWS || PLATFORM_LINUX) && USE_SENTRY_NATIVE - ScopeNativeImpl = MakeShareable(new SentryScopeDesktop()); -#endif - } +#include "HAL/PlatformSentryScope.h" + +void USentryScope::Initialize() +{ + NativeImpl = CreateSharedSentryScope(); } void USentryScope::AddBreadcrumb(USentryBreadcrumb* Breadcrumb) { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->AddBreadcrumb(Breadcrumb->GetNativeImpl()); + NativeImpl->AddBreadcrumb(Breadcrumb->GetNativeObject()); } void USentryScope::ClearBreadcrumbs() { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->ClearBreadcrumbs(); + NativeImpl->ClearBreadcrumbs(); } void USentryScope::AddAttachment(USentryAttachment* Attachment) { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->AddAttachment(Attachment->GetNativeImpl()); + NativeImpl->AddAttachment(Attachment->GetNativeObject()); } void USentryScope::ClearAttachments() { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->ClearAttachments(); + NativeImpl->ClearAttachments(); } void USentryScope::SetTagValue(const FString& Key, const FString& Value) { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->SetTagValue(Key, Value); + NativeImpl->SetTagValue(Key, Value); } FString USentryScope::GetTagValue(const FString& Key) const { - if (!ScopeNativeImpl) + if (!NativeImpl) return FString(); - return ScopeNativeImpl->GetTagValue(Key); + return NativeImpl->GetTagValue(Key); } void USentryScope::RemoveTag(const FString& Key) { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->RemoveTag(Key); + NativeImpl->RemoveTag(Key); } void USentryScope::SetTags(const TMap& Tags) { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->SetTags(Tags); + NativeImpl->SetTags(Tags); } TMap USentryScope::GetTags() const { - if (!ScopeNativeImpl) + if (!NativeImpl) return TMap(); - return ScopeNativeImpl->GetTags(); + return NativeImpl->GetTags(); } void USentryScope::SetDist(const FString& Dist) { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->SetDist(Dist); + NativeImpl->SetDist(Dist); } FString USentryScope::GetDist() const { - if (!ScopeNativeImpl) + if (!NativeImpl) return FString(); - return ScopeNativeImpl->GetDist(); + return NativeImpl->GetDist(); } void USentryScope::SetEnvironment(const FString& Environment) { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->SetEnvironment(Environment); + NativeImpl->SetEnvironment(Environment); } FString USentryScope::GetEnvironment() const { - if (!ScopeNativeImpl) + if (!NativeImpl) return FString(); - return ScopeNativeImpl->GetEnvironment(); + return NativeImpl->GetEnvironment(); } void USentryScope::SetFingerprint(const TArray& Fingerprint) { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->SetFingerprint(Fingerprint); + NativeImpl->SetFingerprint(Fingerprint); } TArray USentryScope::GetFingerprint() const { - if (!ScopeNativeImpl) + if (!NativeImpl) return TArray(); - return ScopeNativeImpl->GetFingerprint(); + return NativeImpl->GetFingerprint(); } void USentryScope::SetLevel(ESentryLevel Level) { - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->SetLevel(Level); + NativeImpl->SetLevel(Level); } ESentryLevel USentryScope::GetLevel() const { - if(!ScopeNativeImpl) + if (!NativeImpl) return ESentryLevel::Debug; - return ScopeNativeImpl->GetLevel(); + return NativeImpl->GetLevel(); } void USentryScope::SetContext(const FString& Key, const TMap& Values) { - if(!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->SetContext(Key, Values); + NativeImpl->SetContext(Key, Values); } void USentryScope::RemoveContext(const FString& Key) { - if(!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->RemoveContext(Key); + NativeImpl->RemoveContext(Key); } void USentryScope::SetExtraValue(const FString& Key, const FString& Value) { - if(!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->SetExtraValue(Key, Value); + NativeImpl->SetExtraValue(Key, Value); } FString USentryScope::GetExtraValue(const FString& Key) const { - if(!ScopeNativeImpl) + if (!NativeImpl) return FString(); - return ScopeNativeImpl->GetExtraValue(Key); + return NativeImpl->GetExtraValue(Key); } void USentryScope::RemoveExtra(const FString& Key) { - if(!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->RemoveExtra(Key); + NativeImpl->RemoveExtra(Key); } void USentryScope::SetExtras(const TMap& Extras) { - if(!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl->SetExtras(Extras); + NativeImpl->SetExtras(Extras); } TMap USentryScope::GetExtras() const { - if (!ScopeNativeImpl) + if (!NativeImpl) return TMap(); - return ScopeNativeImpl->GetExtras(); + return NativeImpl->GetExtras(); } void USentryScope::Clear() { - if (!ScopeNativeImpl) - return; - - ScopeNativeImpl->Clear(); -} - -void USentryScope::InitWithNativeImpl(TSharedPtr scopeImpl) -{ - if (!ScopeNativeImpl) + if (!NativeImpl) return; - ScopeNativeImpl = scopeImpl; -} - -TSharedPtr USentryScope::GetNativeImpl() -{ - return ScopeNativeImpl; + NativeImpl->Clear(); } diff --git a/plugin-dev/Source/Sentry/Private/SentrySpan.cpp b/plugin-dev/Source/Sentry/Private/SentrySpan.cpp index b9d31a7c5..43c9f68b9 100644 --- a/plugin-dev/Source/Sentry/Private/SentrySpan.cpp +++ b/plugin-dev/Source/Sentry/Private/SentrySpan.cpp @@ -1,117 +1,102 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. +// Copyright (c) 2023 Sentry. All Rights Reserved. #include "SentrySpan.h" +#include "SentryDefines.h" #include "Interface/SentrySpanInterface.h" -#if PLATFORM_ANDROID -#include "Android/SentrySpanAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentrySpanApple.h" -#elif PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentrySpanDesktop.h" -#endif - -USentrySpan::USentrySpan() -{ -} - USentrySpan* USentrySpan::StartChild(const FString& Operation, const FString& Description) { - if (!SentrySpanNativeImpl || SentrySpanNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return nullptr; - TSharedPtr spanNativeImpl = SentrySpanNativeImpl->StartChild(Operation, Description); - - USentrySpan* unrealSpan = NewObject(); - unrealSpan->InitWithNativeImpl(spanNativeImpl); - - return unrealSpan; + if (TSharedPtr ChildSpan = NativeImpl->StartChild(Operation, Description)) + { + return USentrySpan::Create(ChildSpan); + } + else + { + UE_LOG(LogSentrySdk, Error, TEXT("Received invalid span after attempting to start child on span")); + return nullptr; + } } USentrySpan* USentrySpan::StartChildWithTimestamp(const FString& Operation, const FString& Description, int64 Timestamp) { - if (!SentrySpanNativeImpl || SentrySpanNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return nullptr; - TSharedPtr spanNativeImpl = SentrySpanNativeImpl->StartChildWithTimestamp(Operation, Description, Timestamp); - - USentrySpan* unrealSpan = NewObject(); - unrealSpan->InitWithNativeImpl(spanNativeImpl); - - return unrealSpan; + if (TSharedPtr ChildSpan = NativeImpl->StartChildWithTimestamp(Operation, Description, Timestamp)) + { + return USentrySpan::Create(ChildSpan); + } + else + { + UE_LOG(LogSentrySdk, Error, TEXT("Received invalid span after attempting to start child with timestamp on span")); + return nullptr; + } } void USentrySpan::Finish() { - if (!SentrySpanNativeImpl) + if (!NativeImpl) return; - SentrySpanNativeImpl->Finish(); + NativeImpl->Finish(); } void USentrySpan::FinishWithTimestamp(int64 Timestamp) { - if (!SentrySpanNativeImpl) + if (!NativeImpl) return; - SentrySpanNativeImpl->FinishWithTimestamp(Timestamp); + NativeImpl->FinishWithTimestamp(Timestamp); } bool USentrySpan::IsFinished() const { - if (!SentrySpanNativeImpl) + if (!NativeImpl) return false; - return SentrySpanNativeImpl->IsFinished(); + return NativeImpl->IsFinished(); } void USentrySpan::SetTag(const FString& key, const FString& value) { - if (!SentrySpanNativeImpl || SentrySpanNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentrySpanNativeImpl->SetTag(key, value); + NativeImpl->SetTag(key, value); } void USentrySpan::RemoveTag(const FString& key) { - if (!SentrySpanNativeImpl || SentrySpanNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentrySpanNativeImpl->RemoveTag(key); + NativeImpl->RemoveTag(key); } void USentrySpan::SetData(const FString& key, const TMap& values) { - if (!SentrySpanNativeImpl || SentrySpanNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentrySpanNativeImpl->SetData(key, values); + NativeImpl->SetData(key, values); } void USentrySpan::RemoveData(const FString& key) { - if (!SentrySpanNativeImpl || SentrySpanNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentrySpanNativeImpl->RemoveData(key); + NativeImpl->RemoveData(key); } void USentrySpan::GetTrace(FString& name, FString& value) { - if (!SentrySpanNativeImpl || SentrySpanNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentrySpanNativeImpl->GetTrace(name, value); -} - -void USentrySpan::InitWithNativeImpl(TSharedPtr spanImpl) -{ - SentrySpanNativeImpl = spanImpl; -} - -TSharedPtr USentrySpan::GetNativeImpl() -{ - return SentrySpanNativeImpl; + NativeImpl->GetTrace(name, value); } diff --git a/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp index 3c7e6428e..15af8de83 100644 --- a/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp +++ b/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp @@ -28,25 +28,14 @@ #include "Interface/SentrySubsystemInterface.h" -#if PLATFORM_ANDROID -#include "Android/SentrySubsystemAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentrySubsystemApple.h" -#elif PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentrySubsystemDesktop.h" -#endif +#include "HAL/PlatformSentrySubsystem.h" +#include "HAL/PlatformSentryUserFeedback.h" void USentrySubsystem::Initialize(FSubsystemCollectionBase& Collection) { Super::Initialize(Collection); -#if PLATFORM_ANDROID - SubsystemNativeImpl = MakeShareable(new SentrySubsystemAndroid()); -#elif PLATFORM_IOS || PLATFORM_MAC - SubsystemNativeImpl = MakeShareable(new SentrySubsystemApple()); -#elif (PLATFORM_WINDOWS || PLATFORM_LINUX) && USE_SENTRY_NATIVE - SubsystemNativeImpl = MakeShareable(new SentrySubsystemDesktop()); -#endif + SubsystemNativeImpl = MakeShareable(new FPlatformSentrySubsystem()); const USentrySettings* Settings = FSentryModule::Get().GetSettings(); @@ -214,7 +203,7 @@ void USentrySubsystem::AddBreadcrumb(USentryBreadcrumb* Breadcrumb) if (!SubsystemNativeImpl || !SubsystemNativeImpl->IsEnabled()) return; - SubsystemNativeImpl->AddBreadcrumb(Breadcrumb->GetNativeImpl()); + SubsystemNativeImpl->AddBreadcrumb(Breadcrumb->GetNativeObject()); } void USentrySubsystem::AddBreadcrumbWithParams(const FString& Message, const FString& Category, const FString& Type, const TMap& Data, ESentryLevel Level) @@ -240,10 +229,7 @@ USentryId* USentrySubsystem::CaptureMessage(const FString& Message, ESentryLevel TSharedPtr idNativeImpl = SubsystemNativeImpl->CaptureMessage(Message, Level); - USentryId* unrealId = NewObject(); - unrealId->InitWithNativeImpl(idNativeImpl); - - return unrealId; + return USentryId::Create(idNativeImpl); } USentryId* USentrySubsystem::CaptureMessageWithScope(const FString& Message, const FConfigureScopeDelegate& OnConfigureScope, ESentryLevel Level) @@ -258,15 +244,11 @@ USentryId* USentrySubsystem::CaptureMessageWithScope(const FString& Message, con TSharedPtr idNativeImpl = SubsystemNativeImpl->CaptureMessageWithScope(Message, FSentryScopeDelegate::CreateLambda([&](TSharedPtr nativeScope) { - USentryScope* unrealScope = NewObject(); - unrealScope->InitWithNativeImpl(nativeScope); + USentryScope* unrealScope = USentryScope::Create(nativeScope); OnConfigureScope.ExecuteIfBound(unrealScope); }), Level); - USentryId* unrealId = NewObject(); - unrealId->InitWithNativeImpl(idNativeImpl); - - return unrealId; + return USentryId::Create(idNativeImpl); } USentryId* USentrySubsystem::CaptureEvent(USentryEvent* Event) @@ -274,12 +256,9 @@ USentryId* USentrySubsystem::CaptureEvent(USentryEvent* Event) if (!SubsystemNativeImpl || !SubsystemNativeImpl->IsEnabled()) return nullptr; - TSharedPtr idNativeImpl = SubsystemNativeImpl->CaptureEvent(Event->GetNativeImpl()); - - USentryId* unrealId = NewObject(); - unrealId->InitWithNativeImpl(idNativeImpl); + TSharedPtr idNativeImpl = SubsystemNativeImpl->CaptureEvent(Event->GetNativeObject()); - return unrealId; + return USentryId::Create(idNativeImpl); } USentryId* USentrySubsystem::CaptureEventWithScope(USentryEvent* Event, const FConfigureScopeDelegate& OnConfigureScope) @@ -292,17 +271,13 @@ USentryId* USentrySubsystem::CaptureEventWithScope(USentryEvent* Event, const FC if (!SubsystemNativeImpl || !SubsystemNativeImpl->IsEnabled()) return nullptr; - TSharedPtr idNativeImpl = SubsystemNativeImpl->CaptureEventWithScope(Event->GetNativeImpl(), FSentryScopeDelegate::CreateLambda([&](TSharedPtr nativeScope) + TSharedPtr idNativeImpl = SubsystemNativeImpl->CaptureEventWithScope(Event->GetNativeObject(), FSentryScopeDelegate::CreateLambda([&](TSharedPtr nativeScope) { - USentryScope* unrealScope = NewObject(); - unrealScope->InitWithNativeImpl(nativeScope); + USentryScope* unrealScope = USentryScope::Create(nativeScope); OnConfigureScope.ExecuteIfBound(unrealScope); })); - USentryId* unrealId = NewObject(); - unrealId->InitWithNativeImpl(idNativeImpl); - - return unrealId; + return USentryId::Create(idNativeImpl); } void USentrySubsystem::CaptureUserFeedback(USentryUserFeedback* UserFeedback) @@ -310,13 +285,12 @@ void USentrySubsystem::CaptureUserFeedback(USentryUserFeedback* UserFeedback) if (!SubsystemNativeImpl || !SubsystemNativeImpl->IsEnabled()) return; - SubsystemNativeImpl->CaptureUserFeedback(UserFeedback->GetNativeImpl()); + SubsystemNativeImpl->CaptureUserFeedback(UserFeedback->GetNativeObject()); } void USentrySubsystem::CaptureUserFeedbackWithParams(USentryId* EventId, const FString& Email, const FString& Comments, const FString& Name) { - USentryUserFeedback* UserFeedback = NewObject(); - UserFeedback->Initialize(EventId); + USentryUserFeedback* UserFeedback = USentryUserFeedback::Create(CreateSharedSentryUserFeedback(EventId->GetNativeObject())); UserFeedback->SetEmail(Email); UserFeedback->SetComment(Comments); UserFeedback->SetName(Name); @@ -329,7 +303,7 @@ void USentrySubsystem::SetUser(USentryUser* User) if (!SubsystemNativeImpl || !SubsystemNativeImpl->IsEnabled()) return; - SubsystemNativeImpl->SetUser(User->GetNativeImpl()); + SubsystemNativeImpl->SetUser(User->GetNativeObject()); } void USentrySubsystem::RemoveUser() @@ -352,8 +326,7 @@ void USentrySubsystem::ConfigureScope(const FConfigureScopeNativeDelegate& OnCon SubsystemNativeImpl->ConfigureScope(FSentryScopeDelegate::CreateLambda([&](TSharedPtr nativeScope) { - USentryScope* unrealScope = NewObject(); - unrealScope->InitWithNativeImpl(nativeScope); + USentryScope* unrealScope = USentryScope::Create(nativeScope); OnConfigureScope.ExecuteIfBound(unrealScope); })); } @@ -413,10 +386,7 @@ USentryTransaction* USentrySubsystem::StartTransaction(const FString& Name, cons TSharedPtr transactionNativeImpl = SubsystemNativeImpl->StartTransaction(Name, Operation); - USentryTransaction* unrealTransaction = NewObject(); - unrealTransaction->InitWithNativeImpl(transactionNativeImpl); - - return unrealTransaction; + return USentryTransaction::Create(transactionNativeImpl); } USentryTransaction* USentrySubsystem::StartTransactionWithContext(USentryTransactionContext* Context) @@ -424,12 +394,9 @@ USentryTransaction* USentrySubsystem::StartTransactionWithContext(USentryTransac if (!SubsystemNativeImpl || !SubsystemNativeImpl->IsEnabled()) return nullptr; - TSharedPtr transactionNativeImpl = SubsystemNativeImpl->StartTransactionWithContext(Context->GetNativeImpl()); - - USentryTransaction* unrealTransaction = NewObject(); - unrealTransaction->InitWithNativeImpl(transactionNativeImpl); + TSharedPtr transactionNativeImpl = SubsystemNativeImpl->StartTransactionWithContext(Context->GetNativeObject()); - return unrealTransaction; + return USentryTransaction::Create(transactionNativeImpl); } USentryTransaction* USentrySubsystem::StartTransactionWithContextAndTimestamp(USentryTransactionContext* Context, int64 Timestamp) @@ -437,12 +404,9 @@ USentryTransaction* USentrySubsystem::StartTransactionWithContextAndTimestamp(US if (!SubsystemNativeImpl || !SubsystemNativeImpl->IsEnabled()) return nullptr; - TSharedPtr transactionNativeImpl = SubsystemNativeImpl->StartTransactionWithContextAndTimestamp(Context->GetNativeImpl(), Timestamp); - - USentryTransaction* unrealTransaction = NewObject(); - unrealTransaction->InitWithNativeImpl(transactionNativeImpl); + TSharedPtr transactionNativeImpl = SubsystemNativeImpl->StartTransactionWithContextAndTimestamp(Context->GetNativeObject(), Timestamp); - return unrealTransaction; + return USentryTransaction::Create(transactionNativeImpl); } USentryTransaction* USentrySubsystem::StartTransactionWithContextAndOptions(USentryTransactionContext* Context, const TMap& Options) @@ -450,12 +414,9 @@ USentryTransaction* USentrySubsystem::StartTransactionWithContextAndOptions(USen if (!SubsystemNativeImpl || !SubsystemNativeImpl->IsEnabled()) return nullptr; - TSharedPtr transactionNativeImpl = SubsystemNativeImpl->StartTransactionWithContextAndOptions(Context->GetNativeImpl(), Options); + TSharedPtr transactionNativeImpl = SubsystemNativeImpl->StartTransactionWithContextAndOptions(Context->GetNativeObject(), Options); - USentryTransaction* unrealTransaction = NewObject(); - unrealTransaction->InitWithNativeImpl(transactionNativeImpl); - - return unrealTransaction; + return USentryTransaction::Create(transactionNativeImpl); } USentryTransactionContext* USentrySubsystem::ContinueTrace(const FString& SentryTrace, const TArray& BaggageHeaders) @@ -465,10 +426,7 @@ USentryTransactionContext* USentrySubsystem::ContinueTrace(const FString& Sentry TSharedPtr transactionContextNativeImpl = SubsystemNativeImpl->ContinueTrace(SentryTrace, BaggageHeaders); - USentryTransactionContext* unrealTransactionContext = NewObject(); - unrealTransactionContext->InitWithNativeImpl(transactionContextNativeImpl); - - return unrealTransactionContext; + return USentryTransactionContext::Create(transactionContextNativeImpl); } bool USentrySubsystem::IsSupportedForCurrentSettings() diff --git a/plugin-dev/Source/Sentry/Private/SentryTransaction.cpp b/plugin-dev/Source/Sentry/Private/SentryTransaction.cpp index a8f4a7ca6..fc89e4a31 100644 --- a/plugin-dev/Source/Sentry/Private/SentryTransaction.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryTransaction.cpp @@ -1,126 +1,112 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. +// Copyright (c) 2023 Sentry. All Rights Reserved. #include "SentryTransaction.h" + +#include "SentryDefines.h" #include "SentrySpan.h" #include "Interface/SentryTransactionInterface.h" -#if PLATFORM_ANDROID -#include "Android/SentryTransactionAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentryTransactionApple.h" -#elif PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentryTransactionDesktop.h" -#endif - -USentryTransaction::USentryTransaction() -{ -} - -USentrySpan* USentryTransaction::StartChild(const FString& Operation, const FString& Description) +USentrySpan* USentryTransaction::StartChildSpan(const FString& Operation, const FString& Description) { - if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return nullptr; - TSharedPtr spanNativeImpl = SentryTransactionNativeImpl->StartChild(Operation, Description); - - USentrySpan* unrealSpan = NewObject(); - unrealSpan->InitWithNativeImpl(spanNativeImpl); - - return unrealSpan; + if (TSharedPtr spanNativeImpl = NativeImpl->StartChildSpan(Operation, Description)) + { + return USentrySpan::Create(spanNativeImpl); + } + else + { + UE_LOG(LogSentrySdk, Error, TEXT("Received invalid span after attempting to start child on transaction")); + return nullptr; + } } -USentrySpan* USentryTransaction::StartChildWithTimestamp(const FString& Operation, const FString& Description, int64 Timestamp) +USentrySpan* USentryTransaction::StartChildSpanWithTimestamp(const FString& Operation, const FString& Description, int64 Timestamp) { - if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return nullptr; - TSharedPtr spanNativeImpl = SentryTransactionNativeImpl->StartChildWithTimestamp(Operation, Description, Timestamp); - - USentrySpan* unrealSpan = NewObject(); - unrealSpan->InitWithNativeImpl(spanNativeImpl); - - return unrealSpan; + if (TSharedPtr spanNativeImpl = NativeImpl->StartChildSpanWithTimestamp(Operation, Description, Timestamp)) + { + return USentrySpan::Create(spanNativeImpl); + } + else + { + UE_LOG(LogSentrySdk, Error, TEXT("Received invalid span after attempting to start child with timestamp on transaction")); + return nullptr; + } } void USentryTransaction::Finish() { - if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentryTransactionNativeImpl->Finish(); + NativeImpl->Finish(); } void USentryTransaction::FinishWithTimestamp(int64 Timestamp) { - if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentryTransactionNativeImpl->FinishWithTimestamp(Timestamp); + NativeImpl->FinishWithTimestamp(Timestamp); } bool USentryTransaction::IsFinished() const { - if (!SentryTransactionNativeImpl) + if (!NativeImpl) return false; - return SentryTransactionNativeImpl->IsFinished(); + return NativeImpl->IsFinished(); } void USentryTransaction::SetName(const FString& name) { - if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentryTransactionNativeImpl->SetName(name); + NativeImpl->SetName(name); } void USentryTransaction::SetTag(const FString& key, const FString& value) { - if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentryTransactionNativeImpl->SetTag(key, value); + NativeImpl->SetTag(key, value); } void USentryTransaction::RemoveTag(const FString& key) { - if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentryTransactionNativeImpl->RemoveTag(key); + NativeImpl->RemoveTag(key); } void USentryTransaction::SetData(const FString& key, const TMap& values) { - if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentryTransactionNativeImpl->SetData(key, values); + NativeImpl->SetData(key, values); } void USentryTransaction::RemoveData(const FString& key) { - if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentryTransactionNativeImpl->RemoveData(key); + NativeImpl->RemoveData(key); } void USentryTransaction::GetTrace(FString& name, FString& value) { - if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + if (!NativeImpl || NativeImpl->IsFinished()) return; - SentryTransactionNativeImpl->GetTrace(name, value); -} - -void USentryTransaction::InitWithNativeImpl(TSharedPtr transactionImpl) -{ - SentryTransactionNativeImpl = transactionImpl; -} - -TSharedPtr USentryTransaction::GetNativeImpl() -{ - return SentryTransactionNativeImpl; + NativeImpl->GetTrace(name, value); } diff --git a/plugin-dev/Source/Sentry/Private/SentryTransactionContext.cpp b/plugin-dev/Source/Sentry/Private/SentryTransactionContext.cpp index 8cb7ca91e..7a7174a88 100644 --- a/plugin-dev/Source/Sentry/Private/SentryTransactionContext.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryTransactionContext.cpp @@ -2,53 +2,25 @@ #include "SentryTransactionContext.h" -#include "Interface/SentryTransactionContextInterface.h" - -#if PLATFORM_ANDROID -#include "Android/SentryTransactionContextAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentryTransactionContextApple.h" -#elif PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentryTransactionContextDesktop.h" -#endif - -USentryTransactionContext::USentryTransactionContext() -{ -} +#include "HAL/PlatformSentryTransactionContext.h" void USentryTransactionContext::Initialize(const FString& Name, const FString& Operation) { -#if PLATFORM_ANDROID - SentryTransactionContextNativeImpl = MakeShareable(new SentryTransactionContextAndroid(Name, Operation)); -#elif PLATFORM_IOS || PLATFORM_MAC - SentryTransactionContextNativeImpl = MakeShareable(new SentryTransactionContextApple(Name, Operation)); -#elif PLATFORM_WINDOWS || PLATFORM_LINUX - SentryTransactionContextNativeImpl = MakeShareable(new SentryTransactionContextDesktop(Name, Operation)); -#endif + NativeImpl = CreateSharedSentryTransactionContext(Name, Operation); } FString USentryTransactionContext::GetName() const { - if (!SentryTransactionContextNativeImpl) + if (!NativeImpl) return FString(); - return SentryTransactionContextNativeImpl->GetName(); + return NativeImpl->GetName(); } FString USentryTransactionContext::GetOperation() const { - if (!SentryTransactionContextNativeImpl) + if (!NativeImpl) return FString(); - return SentryTransactionContextNativeImpl->GetOperation(); -} - -void USentryTransactionContext::InitWithNativeImpl(TSharedPtr transactionContextImpl) -{ - SentryTransactionContextNativeImpl = transactionContextImpl; -} - -TSharedPtr USentryTransactionContext::GetNativeImpl() -{ - return SentryTransactionContextNativeImpl; + return NativeImpl->GetOperation(); } diff --git a/plugin-dev/Source/Sentry/Private/SentryUser.cpp b/plugin-dev/Source/Sentry/Private/SentryUser.cpp index 6569fb053..875b4a199 100644 --- a/plugin-dev/Source/Sentry/Private/SentryUser.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryUser.cpp @@ -2,116 +2,89 @@ #include "SentryUser.h" -#include "Interface/SentryUserInterface.h" +#include "HAL/PlatformSentryUser.h" -#if PLATFORM_ANDROID -#include "Android/SentryUserAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentryUserApple.h" -#elif PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentryUserDesktop.h" -#endif - -USentryUser::USentryUser() +void USentryUser::Initialize() { - if (USentryUser::StaticClass()->GetDefaultObject() != this) - { -#if PLATFORM_ANDROID - UserNativeImpl = MakeShareable(new SentryUserAndroid()); -#elif PLATFORM_IOS || PLATFORM_MAC - UserNativeImpl = MakeShareable(new SentryUserApple()); -#elif (PLATFORM_WINDOWS || PLATFORM_LINUX) && USE_SENTRY_NATIVE - UserNativeImpl = MakeShareable(new SentryUserDesktop()); -#endif - } + NativeImpl = CreateSharedSentryUser(); } void USentryUser::SetEmail(const FString& Email) { - if (!UserNativeImpl) + if (!NativeImpl) return; - UserNativeImpl->SetEmail(Email); + NativeImpl->SetEmail(Email); } FString USentryUser::GetEmail() const { - if(!UserNativeImpl) + if(!NativeImpl) return FString(); - return UserNativeImpl->GetEmail(); + return NativeImpl->GetEmail(); } void USentryUser::SetId(const FString& Id) { - if (!UserNativeImpl) + if (!NativeImpl) return; - UserNativeImpl->SetId(Id); + NativeImpl->SetId(Id); } FString USentryUser::GetId() const { - if(!UserNativeImpl) + if(!NativeImpl) return FString(); - return UserNativeImpl->GetId(); + return NativeImpl->GetId(); } void USentryUser::SetUsername(const FString& Username) { - if (!UserNativeImpl) + if (!NativeImpl) return; - UserNativeImpl->SetUsername(Username); + NativeImpl->SetUsername(Username); } FString USentryUser::GetUsername() const { - if(!UserNativeImpl) + if(!NativeImpl) return FString(); - return UserNativeImpl->GetUsername(); + return NativeImpl->GetUsername(); } void USentryUser::SetIpAddress(const FString& IpAddress) { - if (!UserNativeImpl) + if (!NativeImpl) return; - UserNativeImpl->SetIpAddress(IpAddress); + NativeImpl->SetIpAddress(IpAddress); } FString USentryUser::GetIpAddress() const { - if(!UserNativeImpl) + if(!NativeImpl) return FString(); - return UserNativeImpl->GetIpAddress(); + return NativeImpl->GetIpAddress(); } void USentryUser::SetData(const TMap& Data) { - if (!UserNativeImpl) + if (!NativeImpl) return; - UserNativeImpl->SetData(Data); + NativeImpl->SetData(Data); } TMap USentryUser::GetData() const { - if(!UserNativeImpl) + if(!NativeImpl) return TMap(); - return UserNativeImpl->GetData(); -} - -void USentryUser::InitWithNativeImpl(TSharedPtr userImpl) -{ - UserNativeImpl = userImpl; -} - -TSharedPtr USentryUser::GetNativeImpl() -{ - return UserNativeImpl; + return NativeImpl->GetData(); } diff --git a/plugin-dev/Source/Sentry/Private/SentryUserFeedback.cpp b/plugin-dev/Source/Sentry/Private/SentryUserFeedback.cpp index fe91208ec..df0cd572b 100644 --- a/plugin-dev/Source/Sentry/Private/SentryUserFeedback.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryUserFeedback.cpp @@ -3,81 +3,60 @@ #include "SentryUserFeedback.h" #include "SentryId.h" -#include "Interface/SentryUserFeedbackInterface.h" - -#if PLATFORM_ANDROID -#include "Android/SentryUserFeedbackAndroid.h" -#elif PLATFORM_IOS || PLATFORM_MAC -#include "Apple/SentryUserFeedbackApple.h" -#elif PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentryUserFeedbackDesktop.h" -#endif +#include "HAL/PlatformSentryUserFeedback.h" void USentryUserFeedback::Initialize(USentryId* EventId) { -#if PLATFORM_ANDROID - UserFeedbackNativeImpl = MakeShareable(new SentryUserFeedbackAndroid(EventId->GetNativeImpl())); -#elif PLATFORM_IOS || PLATFORM_MAC - UserFeedbackNativeImpl = MakeShareable(new SentryUserFeedbackApple(EventId->GetNativeImpl())); -#elif PLATFORM_WINDOWS || PLATFORM_LINUX - UserFeedbackNativeImpl = MakeShareable(new SentryUserFeedbackDesktop(EventId->GetNativeImpl())); -#endif + if (ensure(IsValid(EventId))) + { + NativeImpl = CreateSharedSentryUserFeedback(EventId->GetNativeObject()); + } } void USentryUserFeedback::SetName(const FString& Name) { - if (!UserFeedbackNativeImpl) + if (!NativeImpl) return; - UserFeedbackNativeImpl->SetName(Name); + NativeImpl->SetName(Name); } FString USentryUserFeedback::GetName() const { - if(!UserFeedbackNativeImpl) + if(!NativeImpl) return FString(); - return UserFeedbackNativeImpl->GetName(); + return NativeImpl->GetName(); } void USentryUserFeedback::SetEmail(const FString& Email) { - if (!UserFeedbackNativeImpl) + if (!NativeImpl) return; - UserFeedbackNativeImpl->SetEmail(Email); + NativeImpl->SetEmail(Email); } FString USentryUserFeedback::GetEmail() const { - if(!UserFeedbackNativeImpl) + if(!NativeImpl) return FString(); - return UserFeedbackNativeImpl->GetEmail(); + return NativeImpl->GetEmail(); } void USentryUserFeedback::SetComment(const FString& Comments) { - if (!UserFeedbackNativeImpl) + if (!NativeImpl) return; - UserFeedbackNativeImpl->SetComment(Comments); + NativeImpl->SetComment(Comments); } FString USentryUserFeedback::GetComment() const { - if (!UserFeedbackNativeImpl) + if (!NativeImpl) return FString(); - return UserFeedbackNativeImpl->GetComment(); -} - -void USentryUserFeedback::InitWithNativeImpl(TSharedPtr userFeedbackImpl) -{ - UserFeedbackNativeImpl = userFeedbackImpl; + return NativeImpl->GetComment(); } - -TSharedPtr USentryUserFeedback::GetNativeImpl() -{ - return UserFeedbackNativeImpl; -} \ No newline at end of file diff --git a/plugin-dev/Source/Sentry/Private/Tests/SentryBreadcrumb.spec.cpp b/plugin-dev/Source/Sentry/Private/Tests/SentryBreadcrumb.spec.cpp index 8ccb05b58..6a359ea5e 100644 --- a/plugin-dev/Source/Sentry/Private/Tests/SentryBreadcrumb.spec.cpp +++ b/plugin-dev/Source/Sentry/Private/Tests/SentryBreadcrumb.spec.cpp @@ -5,6 +5,8 @@ #include "Misc/AutomationTest.h" +#include "HAL/PlatformSentryBreadcrumb.h" + #if WITH_AUTOMATION_TESTS BEGIN_DEFINE_SPEC(SentryBreadcrumbSpec, "Sentry.SentryBreadcrumb", EAutomationTestFlags::ProductFilter | SentryApplicationContextMask) @@ -15,7 +17,7 @@ void SentryBreadcrumbSpec::Define() { BeforeEach([this]() { - SentryBreadcrumb = NewObject(); + SentryBreadcrumb = USentryBreadcrumb::Create(CreateSharedSentryBreadcrumb()); }); Describe("Breadcrumb params", [this]() @@ -48,4 +50,4 @@ void SentryBreadcrumbSpec::Define() }); } -#endif \ No newline at end of file +#endif diff --git a/plugin-dev/Source/Sentry/Private/Tests/SentryEvent.spec.cpp b/plugin-dev/Source/Sentry/Private/Tests/SentryEvent.spec.cpp index b2afbb476..64ecb6210 100644 --- a/plugin-dev/Source/Sentry/Private/Tests/SentryEvent.spec.cpp +++ b/plugin-dev/Source/Sentry/Private/Tests/SentryEvent.spec.cpp @@ -5,6 +5,8 @@ #include "Misc/AutomationTest.h" +#include "HAL/PlatformSentryEvent.h" + #if WITH_AUTOMATION_TESTS BEGIN_DEFINE_SPEC(SentryEventSpec, "Sentry.SentryEvent", EAutomationTestFlags::ProductFilter | SentryApplicationContextMask) @@ -15,7 +17,7 @@ void SentryEventSpec::Define() { BeforeEach([this]() { - SentryEvent = NewObject(); + SentryEvent = USentryEvent::Create(CreateSharedSentryEvent()); }); Describe("Event params", [this]() diff --git a/plugin-dev/Source/Sentry/Private/Tests/SentryScope.spec.cpp b/plugin-dev/Source/Sentry/Private/Tests/SentryScope.spec.cpp index a72014b90..49757739d 100644 --- a/plugin-dev/Source/Sentry/Private/Tests/SentryScope.spec.cpp +++ b/plugin-dev/Source/Sentry/Private/Tests/SentryScope.spec.cpp @@ -11,11 +11,10 @@ #include "Misc/AutomationTest.h" -#if PLATFORM_WINDOWS || PLATFORM_LINUX -#include "Desktop/SentryScopeDesktop.h" -#include "Desktop/SentryEventDesktop.h" -#include "Desktop/Infrastructure/SentryConvertersDesktop.h" -#endif +#include "HAL/PlatformSentryScope.h" +#include "HAL/PlatformSentryEvent.h" + +#include "GenericPlatform/Infrastructure/GenericPlatformSentryConverters.h" #if WITH_AUTOMATION_TESTS @@ -33,7 +32,7 @@ void SentryScopeSpec::Define() { BeforeEach([this]() { - SentryScope = NewObject(); + SentryScope = USentryScope::Create(CreateSharedSentryScope()); TestDist = TEXT("dist_str"); TestEnvironment = TEXT("env_str"); @@ -155,13 +154,13 @@ void SentryScopeSpec::Define() SentryScope->SetExtras(TestExtras); SentryScope->SetContext(TEXT("TestContext"), TestContext); - USentryEvent* SentryEvent = NewObject(); + USentryEvent* SentryEvent = USentryEvent::Create(CreateSharedSentryEvent()); - TSharedPtr EventDesktop = StaticCastSharedPtr(SentryEvent->GetNativeImpl()); + TSharedPtr Event = StaticCastSharedPtr(SentryEvent->GetNativeObject()); - StaticCastSharedPtr(SentryScope->GetNativeImpl())->Apply(EventDesktop); + StaticCastSharedPtr(SentryScope->GetNativeObject())->Apply(Event); - sentry_value_t NativeEvent = EventDesktop->GetNativeObject(); + sentry_value_t NativeEvent = Event->GetNativeObject(); sentry_value_t level = sentry_value_get_by_key(NativeEvent, "level"); sentry_value_t dist = sentry_value_get_by_key(NativeEvent, "dist"); @@ -173,19 +172,19 @@ void SentryScopeSpec::Define() sentry_value_t contexts = sentry_value_get_by_key(NativeEvent, "contexts"); sentry_value_t testContext = sentry_value_get_by_key(contexts, "TestContext"); - TestEqual("Event level", SentryConvertersDesktop::SentryLevelToUnreal(level), ESentryLevel::Fatal); + TestEqual("Event level", FGenericPlatformSentryConverters::SentryLevelToUnreal(level), ESentryLevel::Fatal); TestEqual("Event dist", FString(sentry_value_as_string(dist)), TestDist); TestEqual("Event environment", FString(sentry_value_as_string(environment)), TestEnvironment); - TestEqual("Event fingerprint", SentryConvertersDesktop::StringArrayToUnreal(fingerprint), TestFingerprint); - TestEqual("Event tags 1", SentryConvertersDesktop::StringMapToUnreal(tags)[TEXT("TagsKey1")], TestTags[TEXT("TagsKey1")]); - TestEqual("Event tags 2", SentryConvertersDesktop::StringMapToUnreal(tags)[TEXT("TagsKey2")], TestTags[TEXT("TagsKey2")]); - TestEqual("Event extra 1", SentryConvertersDesktop::StringMapToUnreal(extra)[TEXT("ExtrasKey1")], TestExtras[TEXT("ExtrasKey1")]); - TestEqual("Event extra 2", SentryConvertersDesktop::StringMapToUnreal(extra)[TEXT("ExtrasKey2")], TestExtras[TEXT("ExtrasKey2")]); - TestEqual("Event context 1", SentryConvertersDesktop::StringMapToUnreal(testContext)[TEXT("ContextKey1")], TestContext[TEXT("ContextKey1")]); - TestEqual("Event context 2", SentryConvertersDesktop::StringMapToUnreal(testContext)[TEXT("ContextKey2")], TestContext[TEXT("ContextKey2")]); + TestEqual("Event fingerprint", FGenericPlatformSentryConverters::StringArrayToUnreal(fingerprint), TestFingerprint); + TestEqual("Event tags 1", FGenericPlatformSentryConverters::StringMapToUnreal(tags)[TEXT("TagsKey1")], TestTags[TEXT("TagsKey1")]); + TestEqual("Event tags 2", FGenericPlatformSentryConverters::StringMapToUnreal(tags)[TEXT("TagsKey2")], TestTags[TEXT("TagsKey2")]); + TestEqual("Event extra 1", FGenericPlatformSentryConverters::StringMapToUnreal(extra)[TEXT("ExtrasKey1")], TestExtras[TEXT("ExtrasKey1")]); + TestEqual("Event extra 2", FGenericPlatformSentryConverters::StringMapToUnreal(extra)[TEXT("ExtrasKey2")], TestExtras[TEXT("ExtrasKey2")]); + TestEqual("Event context 1", FGenericPlatformSentryConverters::StringMapToUnreal(testContext)[TEXT("ContextKey1")], TestContext[TEXT("ContextKey1")]); + TestEqual("Event context 2", FGenericPlatformSentryConverters::StringMapToUnreal(testContext)[TEXT("ContextKey2")], TestContext[TEXT("ContextKey2")]); }); }); #endif } -#endif \ No newline at end of file +#endif diff --git a/plugin-dev/Source/Sentry/Private/Tests/SentrySubsystem.spec.cpp b/plugin-dev/Source/Sentry/Private/Tests/SentrySubsystem.spec.cpp index d7aa483d8..b266e6485 100644 --- a/plugin-dev/Source/Sentry/Private/Tests/SentrySubsystem.spec.cpp +++ b/plugin-dev/Source/Sentry/Private/Tests/SentrySubsystem.spec.cpp @@ -7,6 +7,9 @@ #include "SentryTransactionContext.h" #include "SentrySpan.h" +#include "HAL/PlatformSentryEvent.h" +#include "HAL/PlatformSentryTransactionContext.h" + #include "UObject/UObjectGlobals.h" #include "Misc/AutomationTest.h" #include "Misc/DateTime.h" @@ -50,7 +53,7 @@ void SentrySubsystemSpec::Define() { It("should return a non-null Event ID if event captured", [this]() { - USentryEvent* testEvent = NewObject(); + USentryEvent* testEvent = USentryEvent::Create(CreateSharedSentryEvent()); testEvent->SetMessage(TEXT("Automation: Sentry test event message")); const USentryId* eventId = SentrySubsystem->CaptureEvent(testEvent); @@ -59,7 +62,7 @@ void SentrySubsystemSpec::Define() It("should always return non-null Event ID if scoped version used", [this]() { - USentryEvent* testEvent = NewObject(); + USentryEvent* testEvent = USentryEvent::Create(CreateSharedSentryEvent()); testEvent->SetMessage(TEXT("Automation: Sentry test event message")); const FConfigureScopeNativeDelegate testDelegate; @@ -77,7 +80,7 @@ void SentrySubsystemSpec::Define() TestNotNull("Transaction is non-null", transaction); TestFalse("Transaction is not finished", transaction->IsFinished()); - USentrySpan* span = transaction->StartChild(TEXT("Automation span"), TEXT("Description text")); + USentrySpan* span = transaction->StartChildSpan(TEXT("Automation span"), TEXT("Description text")); TestNotNull("Span is non-null", span); TestFalse("Span is not finished", span->IsFinished()); @@ -97,8 +100,10 @@ void SentrySubsystemSpec::Define() It("should be started and finished with specific context", [this]() { - USentryTransactionContext* transactionContext = NewObject(); - transactionContext->Initialize(TEXT("Automation transaction"), TEXT("Automation operation")); + USentryTransactionContext* transactionContext = + USentryTransactionContext::Create( + CreateSharedSentryTransactionContext(TEXT("Automation transaction"), TEXT("Automation operation")) + ); USentryTransaction* transaction = SentrySubsystem->StartTransactionWithContext(transactionContext); TestNotNull("Transaction is non-null", transaction); @@ -110,8 +115,10 @@ void SentrySubsystemSpec::Define() It("should be started and finished with specific context and timings", [this]() { - USentryTransactionContext* transactionContext = NewObject(); - transactionContext->Initialize(TEXT("Automation transaction"), TEXT("Automation operation")); + USentryTransactionContext* transactionContext = + USentryTransactionContext::Create( + CreateSharedSentryTransactionContext(TEXT("Automation transaction"), TEXT("Automation operation")) + ); USentryTransaction* transaction = SentrySubsystem->StartTransactionWithContextAndTimestamp(transactionContext, FDateTime::UtcNow().ToUnixTimestamp()); TestNotNull("Transaction is non-null", transaction); @@ -153,4 +160,4 @@ void SentrySubsystemSpec::Define() }); } -#endif \ No newline at end of file +#endif diff --git a/plugin-dev/Source/Sentry/Private/Tests/SentryUser.spec.cpp b/plugin-dev/Source/Sentry/Private/Tests/SentryUser.spec.cpp index 1f906e7bc..bb64eb9ef 100644 --- a/plugin-dev/Source/Sentry/Private/Tests/SentryUser.spec.cpp +++ b/plugin-dev/Source/Sentry/Private/Tests/SentryUser.spec.cpp @@ -5,6 +5,8 @@ #include "Misc/AutomationTest.h" +#include "HAL/PlatformSentryUser.h" + #if WITH_AUTOMATION_TESTS BEGIN_DEFINE_SPEC(SentryUserSpec, "Sentry.SentryUser", EAutomationTestFlags::ProductFilter | SentryApplicationContextMask) @@ -15,7 +17,7 @@ void SentryUserSpec::Define() { BeforeEach([this]() { - SentryUser = NewObject(); + SentryUser = USentryUser::Create(CreateSharedSentryUser()); }); Describe("User params", [this]() diff --git a/plugin-dev/Source/Sentry/Private/Windows/Infrastructure/WindowsSentryConverters.cpp b/plugin-dev/Source/Sentry/Private/Windows/Infrastructure/WindowsSentryConverters.cpp new file mode 100644 index 000000000..006d8060e --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Windows/Infrastructure/WindowsSentryConverters.cpp @@ -0,0 +1,51 @@ +#include "WindowsSentryConverters.h" + +#if USE_SENTRY_NATIVE + +/* static */ void FWindowsSentryConverters::SentryCrashContextToString(const sentry_ucontext_t* crashContext, TCHAR* outErrorString, int32 errorStringBufSize) +{ + EXCEPTION_RECORD* ExceptionRecord = crashContext->exception_ptrs.ExceptionRecord; + + FString ErrorString = TEXT("Unhandled Exception: "); + +#define HANDLE_CASE(x) case x: ErrorString += TEXT(#x); break; + + switch (ExceptionRecord->ExceptionCode) + { + case EXCEPTION_ACCESS_VIOLATION: + ErrorString += TEXT("EXCEPTION_ACCESS_VIOLATION "); + if (ExceptionRecord->ExceptionInformation[0] == 0) + { + ErrorString += TEXT("reading address "); + } + else if (ExceptionRecord->ExceptionInformation[0] == 1) + { + ErrorString += TEXT("writing address "); + } + ErrorString += FString::Printf( +#if PLATFORM_64BITS + TEXT("0x%016llx") +#else + TEXT("0x%08x") +#endif + , ExceptionRecord->ExceptionInformation[1]); + break; + HANDLE_CASE(EXCEPTION_ARRAY_BOUNDS_EXCEEDED) + HANDLE_CASE(EXCEPTION_DATATYPE_MISALIGNMENT) + HANDLE_CASE(EXCEPTION_FLT_DENORMAL_OPERAND) + HANDLE_CASE(EXCEPTION_FLT_DIVIDE_BY_ZERO) + HANDLE_CASE(EXCEPTION_FLT_INVALID_OPERATION) + HANDLE_CASE(EXCEPTION_ILLEGAL_INSTRUCTION) + HANDLE_CASE(EXCEPTION_INT_DIVIDE_BY_ZERO) + HANDLE_CASE(EXCEPTION_PRIV_INSTRUCTION) + HANDLE_CASE(EXCEPTION_STACK_OVERFLOW) + default: + ErrorString += FString::Printf(TEXT("0x%08x"), (uint32)ExceptionRecord->ExceptionCode); + } + + FCString::Strncpy(outErrorString, *ErrorString, errorStringBufSize); + +#undef HANDLE_CASE +} + +#endif // USE_SENTRY_NATIVE diff --git a/plugin-dev/Source/Sentry/Private/Windows/Infrastructure/WindowsSentryConverters.h b/plugin-dev/Source/Sentry/Private/Windows/Infrastructure/WindowsSentryConverters.h new file mode 100644 index 000000000..fdbf1e547 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Windows/Infrastructure/WindowsSentryConverters.h @@ -0,0 +1,15 @@ +#pragma once + +#if USE_SENTRY_NATIVE + +#include "CoreMinimal.h" + +#include "GenericPlatform/Convenience/SentryInclude.h" + +class FWindowsSentryConverters +{ +public: + static void SentryCrashContextToString(const sentry_ucontext_t* crashContext, TCHAR* outErrorString, int32 errorStringBufSize); +}; + +#endif // USE_SENTRY_NATIVE diff --git a/plugin-dev/Source/Sentry/Private/Windows/WindowsSentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/Windows/WindowsSentrySubsystem.cpp new file mode 100644 index 000000000..775fd6446 --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Windows/WindowsSentrySubsystem.cpp @@ -0,0 +1,69 @@ +#include "WindowsSentrySubsystem.h" + +#if USE_SENTRY_NATIVE + +#include "SentryDefines.h" +#include "SentrySettings.h" + +#include "Windows/WindowsPlatformStackWalk.h" +#include "Windows/Infrastructure/WindowsSentryConverters.h" + +void FWindowsSentrySubsystem::InitWithSettings( + const USentrySettings* Settings, + USentryBeforeSendHandler* BeforeSendHandler, + USentryTraceSampler* TraceSampler) +{ + FMicrosoftSentrySubsystem::InitWithSettings(Settings, BeforeSendHandler, TraceSampler); + +#if !UE_VERSION_OLDER_THAN(5, 2, 0) + FPlatformMisc::SetCrashHandlingType(Settings->EnableAutoCrashCapturing + ? ECrashHandlingType::Disabled + : ECrashHandlingType::Default); +#endif // !UE_VERSION_OLDER_THAN(5, 2, 0) +} + +void FWindowsSentrySubsystem::ConfigureGpuDumpAttachment(sentry_options_t *Options) +{ + sentry_options_add_attachmentw(Options, *GetGpuDumpBackupPath()); +} + +static void PrintCrashLog(const sentry_ucontext_t *uctx) +{ +#if !UE_VERSION_OLDER_THAN(5, 0, 0) + FWindowsSentryConverters::SentryCrashContextToString(uctx, GErrorExceptionDescription, UE_ARRAY_COUNT(GErrorExceptionDescription)); + + const SIZE_T StackTraceSize = 65535; + ANSICHAR* StackTrace = (ANSICHAR*)GMalloc->Malloc(StackTraceSize); + StackTrace[0] = 0; + + // Currently raw crash data stored in `uctx` can be utilized for stalk walking on Windows only + void* ProgramCounter = uctx->exception_ptrs.ExceptionRecord->ExceptionAddress; + + FPlatformStackWalk::StackWalkAndDump(StackTrace, StackTraceSize, ProgramCounter); + + FCString::Strncat(GErrorHist, GErrorExceptionDescription, UE_ARRAY_COUNT(GErrorHist)); + FCString::Strncat(GErrorHist, TEXT("\r\n\r\n"), UE_ARRAY_COUNT(GErrorHist)); + FCString::Strncat(GErrorHist, ANSI_TO_TCHAR(StackTrace), UE_ARRAY_COUNT(GErrorHist)); + +#if !NO_LOGGING + FDebug::LogFormattedMessageWithCallstack(LogSentrySdk.GetCategoryName(), __FILE__, __LINE__, TEXT("=== Critical error: ==="), GErrorHist, ELogVerbosity::Error); +#endif // !NO_LOGGING + +#if !UE_VERSION_OLDER_THAN(5, 1, 0) + GLog->Panic(); +#endif // !UE_VERSION_OLDER_THAN(5, 1, 0) + + GMalloc->Free(StackTrace); +#endif // !UE_VERSION_OLDER_THAN(5, 0, 0) +} + +sentry_value_t FWindowsSentrySubsystem::OnCrash(const sentry_ucontext_t *uctx, sentry_value_t event, void *closure) +{ + // Ensures that error message and corresponding callstack flushed to a log file (if available) + // before it's attached to the captured crash event and uploaded to Sentry. + PrintCrashLog(uctx); + + return FMicrosoftSentrySubsystem::OnCrash(uctx, event, closure); +} + +#endif // USE_SENTRY_NATIVE diff --git a/plugin-dev/Source/Sentry/Private/Windows/WindowsSentrySubsystem.h b/plugin-dev/Source/Sentry/Private/Windows/WindowsSentrySubsystem.h new file mode 100644 index 000000000..4f9414d6c --- /dev/null +++ b/plugin-dev/Source/Sentry/Private/Windows/WindowsSentrySubsystem.h @@ -0,0 +1,25 @@ +#pragma once + +#if USE_SENTRY_NATIVE + +#include "Microsoft/MicrosoftSentrySubsystem.h" + +class FWindowsSentrySubsystem : public FMicrosoftSentrySubsystem +{ +public: + virtual void InitWithSettings( + const USentrySettings* Settings, + USentryBeforeSendHandler* BeforeSendHandler, + USentryTraceSampler* TraceSampler + ) override; + +protected: + virtual void ConfigureGpuDumpAttachment(sentry_options_t* Options) override; + virtual FString GetHandlerExecutableName() const override { return TEXT("crashpad_handler.exe"); } + + virtual sentry_value_t OnCrash(const sentry_ucontext_t* uctx, sentry_value_t event, void* closure) override; +}; + +typedef FWindowsSentrySubsystem FPlatformSentrySubsystem; + +#endif // USE_SENTRY_NATIVE diff --git a/plugin-dev/Source/Sentry/Public/SentryAttachment.h b/plugin-dev/Source/Sentry/Public/SentryAttachment.h index 1a827249c..40b16cd67 100644 --- a/plugin-dev/Source/Sentry/Public/SentryAttachment.h +++ b/plugin-dev/Source/Sentry/Public/SentryAttachment.h @@ -4,6 +4,8 @@ #include "CoreMinimal.h" +#include "SentryImplWrapper.h" + #include "SentryAttachment.generated.h" class ISentryAttachment; @@ -12,13 +14,13 @@ class ISentryAttachment; * Additional file to store alongside an event or transaction. */ UCLASS(BlueprintType) -class SENTRY_API USentryAttachment : public UObject +class SENTRY_API USentryAttachment : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - - /** Initializes an attachment with bytes and a filename. + /** + * Initializes an attachment with bytes and a filename. * * @param Data The data for the attachment. * @param Filename The name of the attachment to display in Sentry. @@ -27,7 +29,8 @@ class SENTRY_API USentryAttachment : public UObject UFUNCTION(BlueprintCallable, Category = "Sentry") void InitializeWithData(const TArray& Data, const FString& Filename, const FString& ContentType = FString(TEXT("application/octet-stream"))); - /** Initializes an attachment with a path and a filename. + /** + * Initializes an attachment with a path and a filename. * * @param Path The path string of the file to upload as an attachment. * @param Filename The name of the attachment to display in Sentry. @@ -51,10 +54,4 @@ class SENTRY_API USentryAttachment : public UObject /** Gets the content type of the attachment. Default is "application/octet-stream". */ UFUNCTION(BlueprintPure, Category = "Sentry") FString GetContentType() const; - - void InitWithNativeImpl(TSharedPtr attachmentImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr AttachmentNativeImpl; }; diff --git a/plugin-dev/Source/Sentry/Public/SentryBreadcrumb.h b/plugin-dev/Source/Sentry/Public/SentryBreadcrumb.h index 9503b2e60..748b46da9 100644 --- a/plugin-dev/Source/Sentry/Public/SentryBreadcrumb.h +++ b/plugin-dev/Source/Sentry/Public/SentryBreadcrumb.h @@ -3,6 +3,7 @@ #pragma once #include "SentryDataTypes.h" +#include "SentryImplWrapper.h" #include "SentryBreadcrumb.generated.h" @@ -12,12 +13,14 @@ class ISentryBreadcrumb; * Information to create a trail of events that happened prior to an issue. */ UCLASS(BlueprintType) -class SENTRY_API USentryBreadcrumb : public UObject +class SENTRY_API USentryBreadcrumb : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - USentryBreadcrumb(); + /** Initializes the breadcrumb. */ + UFUNCTION(BlueprintCallable, Category = "Sentry") + void Initialize(); /** Sets message of the breadcrumb. */ UFUNCTION(BlueprintCallable, Category = "Sentry") @@ -58,10 +61,4 @@ class SENTRY_API USentryBreadcrumb : public UObject /** Gets the level of the breadcrumb. */ UFUNCTION(BlueprintPure, Category = "Sentry") ESentryLevel GetLevel() const; - - void InitWithNativeImpl(TSharedPtr breadcrumbImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr BreadcrumbNativeImpl; -}; \ No newline at end of file +}; diff --git a/plugin-dev/Source/Sentry/Public/SentryEvent.h b/plugin-dev/Source/Sentry/Public/SentryEvent.h index afcc703cf..9f671bbab 100644 --- a/plugin-dev/Source/Sentry/Public/SentryEvent.h +++ b/plugin-dev/Source/Sentry/Public/SentryEvent.h @@ -3,6 +3,7 @@ #pragma once #include "SentryDataTypes.h" +#include "SentryImplWrapper.h" #include "SentryEvent.generated.h" @@ -12,21 +13,19 @@ class ISentryEvent; * Data being sent to Sentry. */ UCLASS(BlueprintType) -class SENTRY_API USentryEvent : public UObject +class SENTRY_API USentryEvent : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - USentryEvent(); - /** - * Creates the event with specified message and level. - * - * @param Message Message to sent. + * Initializes the event with the specified message and level. + * + * @param Message Message to be sent. * @param Level Level of the event. */ UFUNCTION(BlueprintCallable, Category = "Sentry") - static USentryEvent* CreateEventWithMessageAndLevel(const FString& Message, ESentryLevel Level); + void Initialize(const FString& Message, ESentryLevel Level); /** Sets message of the event. */ UFUNCTION(BlueprintCallable, Category = "Sentry") @@ -51,10 +50,4 @@ class SENTRY_API USentryEvent : public UObject /** Gets flag indicating whether the event is an Application Not Responding (ANR) error. */ UFUNCTION(BlueprintPure, Category = "Sentry", meta=(DisplayName="Is App Not Responding")) bool IsAnr() const; - - void InitWithNativeImpl(TSharedPtr eventImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr EventNativeImpl; }; diff --git a/plugin-dev/Source/Sentry/Public/SentryHint.h b/plugin-dev/Source/Sentry/Public/SentryHint.h index 5007d8768..0e55e75da 100644 --- a/plugin-dev/Source/Sentry/Public/SentryHint.h +++ b/plugin-dev/Source/Sentry/Public/SentryHint.h @@ -2,6 +2,8 @@ #pragma once +#include "SentryImplWrapper.h" + #include "SentryHint.generated.h" class ISentryHint; @@ -11,20 +13,16 @@ class USentryAttachment; * Hint associated with the event. */ UCLASS(BlueprintType) -class SENTRY_API USentryHint : public UObject +class SENTRY_API USentryHint : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - USentryHint(); + /** Initializes the hint. */ + UFUNCTION(BlueprintCallable, Category = "Sentry") + void Initialize(); /** Adds attachment to event hint. */ UFUNCTION(BlueprintCallable, Category = "Sentry") void AddAttachment(USentryAttachment* Attachment); - - void InitWithNativeImpl(TSharedPtr hintImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr SentryHintNativeImpl; }; diff --git a/plugin-dev/Source/Sentry/Public/SentryId.h b/plugin-dev/Source/Sentry/Public/SentryId.h index da418d2ff..908d010ad 100644 --- a/plugin-dev/Source/Sentry/Public/SentryId.h +++ b/plugin-dev/Source/Sentry/Public/SentryId.h @@ -2,6 +2,8 @@ #pragma once +#include "SentryImplWrapper.h" + #include "SentryId.generated.h" class ISentryId; @@ -10,20 +12,16 @@ class ISentryId; * Unique identifier of the event. */ UCLASS(BlueprintType) -class SENTRY_API USentryId : public UObject +class SENTRY_API USentryId : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - USentryId(); + /** Initializes the identifier. */ + UFUNCTION(BlueprintCallable, Category = "Sentry") + void Initialize(); /** Gets string representation of the event ID. */ UFUNCTION(BlueprintPure, Category = "Sentry") FString ToString() const; - - void InitWithNativeImpl(TSharedPtr idImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr SentryIdNativeImpl; }; diff --git a/plugin-dev/Source/Sentry/Public/SentryImplWrapper.h b/plugin-dev/Source/Sentry/Public/SentryImplWrapper.h new file mode 100644 index 000000000..78889cdef --- /dev/null +++ b/plugin-dev/Source/Sentry/Public/SentryImplWrapper.h @@ -0,0 +1,44 @@ +#pragma once + +#include "UObject/UObjectGlobals.h" +#include "Templates/SharedPointer.h" + +/** + * A templatized wrapper to simplify the Unreal <-> Sentry bridging layer. + */ +template +class TSentryImplWrapper +{ +public: + /** Pure virtual destructor to ensure class is abstract. */ + virtual ~TSentryImplWrapper() = 0; + + /** + * Method to instantiate an object with a native implementation. + * + * @param InObject The native implementation. + * @return Returns an instance of the Unreal object if instantiation is valid; otherwise nullptr. + */ + static Unreal* Create(TSharedPtr InObject) + { + if (InObject) + { + Unreal* OutObject = NewObject(); + StaticCast*>(OutObject)->NativeImpl = InObject; + return OutObject; + } + else + { + return nullptr; + } + } + + /** Retrieves the underlying native implementation. */ + TSharedPtr GetNativeObject() const { return NativeImpl; } + +protected: + TSharedPtr NativeImpl; +}; + +template +TSentryImplWrapper::~TSentryImplWrapper() {} diff --git a/plugin-dev/Source/Sentry/Public/SentrySamplingContext.h b/plugin-dev/Source/Sentry/Public/SentrySamplingContext.h index ed7a426cb..3a58deb57 100644 --- a/plugin-dev/Source/Sentry/Public/SentrySamplingContext.h +++ b/plugin-dev/Source/Sentry/Public/SentrySamplingContext.h @@ -4,18 +4,22 @@ #include "CoreMinimal.h" +#include "SentryImplWrapper.h" + #include "SentrySamplingContext.generated.h" class ISentrySamplingContext; class USentryTransactionContext; UCLASS(BlueprintType) -class SENTRY_API USentrySamplingContext : public UObject +class SENTRY_API USentrySamplingContext : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - USentrySamplingContext(); + /** Initializes the sampling context. */ + UFUNCTION(BlueprintCallable, Category = "Sentry") + void Initialize(); /** Gets transaction context used for sampling. */ UFUNCTION(BlueprintPure, Category = "Sentry") @@ -24,10 +28,4 @@ class SENTRY_API USentrySamplingContext : public UObject /** Gets custom data used for sampling. */ UFUNCTION(BlueprintPure, Category = "Sentry") TMap GetCustomSamplingContext() const; - - void InitWithNativeImpl(TSharedPtr samplingContextImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr SentrySamplingContextNativeImpl; }; diff --git a/plugin-dev/Source/Sentry/Public/SentryScope.h b/plugin-dev/Source/Sentry/Public/SentryScope.h index 2011e95eb..dc56f805c 100644 --- a/plugin-dev/Source/Sentry/Public/SentryScope.h +++ b/plugin-dev/Source/Sentry/Public/SentryScope.h @@ -3,6 +3,7 @@ #pragma once #include "SentryDataTypes.h" +#include "SentryImplWrapper.h" #include "SentryScope.generated.h" @@ -14,12 +15,14 @@ class USentryAttachment; * Scope data to be sent with the event. */ UCLASS(BlueprintType) -class SENTRY_API USentryScope : public UObject +class SENTRY_API USentryScope : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - USentryScope(); + /** Initializes the scope. */ + UFUNCTION(BlueprintCallable, Category = "Sentry") + void Initialize(); /** Adds a breadcrumb to the current Scope. */ UFUNCTION(BlueprintCallable, Category = "Sentry") @@ -120,12 +123,6 @@ class SENTRY_API USentryScope : public UObject /** Clears the current scope. */ UFUNCTION(BlueprintCallable, Category = "Sentry") void Clear(); - - void InitWithNativeImpl(TSharedPtr scopeImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr ScopeNativeImpl; }; DECLARE_DELEGATE_OneParam(FConfigureScopeNativeDelegate, USentryScope*); diff --git a/plugin-dev/Source/Sentry/Public/SentrySettings.h b/plugin-dev/Source/Sentry/Public/SentrySettings.h index 6c8f502ff..1eb170331 100644 --- a/plugin-dev/Source/Sentry/Public/SentrySettings.h +++ b/plugin-dev/Source/Sentry/Public/SentrySettings.h @@ -215,7 +215,7 @@ class SENTRY_API USentrySettings : public UObject FString Dsn; UPROPERTY(Config, EditAnywhere, Category = "General", - Meta = (DisplayName = "Enable verbose logging", ToolTip = "Flag indicating whether to enable verbose logging on desktop.")) + Meta = (DisplayName = "Enable verbose logging", ToolTip = "Flag indicating whether to enable verbose logging.")) bool Debug; UPROPERTY(Config, EditAnywhere, BlueprintReadWrite, Category = "General", @@ -274,24 +274,24 @@ class SENTRY_API USentrySettings : public UObject Meta = (DisplayName = "Override release name", ToolTip = "Release name which will be used for enriching events.", EditCondition = "OverrideReleaseName")) FString Release; - UPROPERTY(Config, EditAnywhere, Category = "General|Transport", + UPROPERTY(Config, EditAnywhere, Category = "General|Native", Meta = (InlineEditConditionToggle)) bool UseProxy; - UPROPERTY(Config, EditAnywhere, BlueprintReadWrite, Category = "General|Transport", - Meta = (DisplayName = "HTTP proxy (for Windows/Linux only)", ToolTip = "HTTP proxy through which requests can be tunneled to Sentry.", EditCondition = "UseProxy")) + UPROPERTY(Config, EditAnywhere, BlueprintReadWrite, Category = "General|Native", + Meta = (DisplayName = "HTTP proxy", ToolTip = "HTTP proxy through which requests can be tunneled to Sentry.", EditCondition = "UseProxy")) FString ProxyUrl; UPROPERTY(Config, EditAnywhere, BlueprintReadWrite, Category = "General|Hooks", - Meta = (DisplayName = "Custom `beforeSend` event hanler", ToolTip = "Custom hanler for processing events before sending them to Sentry.")) + Meta = (DisplayName = "Custom `beforeSend` event handler", ToolTip = "Custom handler for processing events before sending them to Sentry.")) TSubclassOf BeforeSendHandler; - UPROPERTY(Config, EditAnywhere, Category = "General|Desktop", + UPROPERTY(Config, EditAnywhere, Category = "General|Windows", Meta = (DisplayName = "Override Windows default crash capturing mechanism (UE 5.2+)", ToolTip = "Flag indicating whether to capture crashes automatically on Windows as an alternative to Crash Reporter.")) bool EnableAutoCrashCapturing; - UPROPERTY(Config, EditAnywhere, Category = "General|Desktop", - Meta = (DisplayName = "Sentry database location (for Windows/Linux only)", ToolTip = "Location where Sentry stores its internal/temporary files.")) + UPROPERTY(Config, EditAnywhere, Category = "General|Native", + Meta = (DisplayName = "Sentry database location", ToolTip = "Location where Sentry stores its internal/temporary files.")) ESentryDatabaseLocation DatabaseLocation; UPROPERTY(Config, EditAnywhere, BlueprintReadWrite, Category = "General|Mobile", @@ -299,7 +299,7 @@ class SENTRY_API USentrySettings : public UObject TArray InAppInclude; UPROPERTY(Config, EditAnywhere, BlueprintReadWrite, Category = "General|Mobile", - Meta = (DisplayName = "In-app exludes (for Android/Apple only)", Tooltip = "A list of string prefixes of module names that don't belong to the app.")) + Meta = (DisplayName = "In-app excludes (for Android/Apple only)", Tooltip = "A list of string prefixes of module names that don't belong to the app.")) TArray InAppExclude; UPROPERTY(Config, EditAnywhere, BlueprintReadWrite, Category = "General|Mobile", @@ -320,7 +320,7 @@ class SENTRY_API USentrySettings : public UObject float TracesSampleRate; UPROPERTY(Config, EditAnywhere, Category = "General|Performance Monitoring", - Meta = (DisplayName = "Traces sampler", ToolTip = "Custom hanler for determining traces sample rate based on the sampling context.", + Meta = (DisplayName = "Traces sampler", ToolTip = "Custom handler for determining traces sample rate based on the sampling context.", EditCondition = "EnableTracing && SamplingType == ESentryTracesSamplingType::TracesSampler", EditConditionHides)) TSubclassOf TracesSampler; @@ -353,7 +353,7 @@ class SENTRY_API USentrySettings : public UObject FString ProjectName; UPROPERTY(EditAnywhere, Category = "Debug Symbols", - Meta = (DisplayName = "Organization Name", ToolTip = "Name of the organisation associated with the project.", EditCondition = "UploadSymbolsAutomatically")) + Meta = (DisplayName = "Organization Name", ToolTip = "Name of the organization associated with the project.", EditCondition = "UploadSymbolsAutomatically")) FString OrgName; UPROPERTY(EditAnywhere, Category = "Debug Symbols", diff --git a/plugin-dev/Source/Sentry/Public/SentrySpan.h b/plugin-dev/Source/Sentry/Public/SentrySpan.h index 7dd137365..9648fc9e1 100644 --- a/plugin-dev/Source/Sentry/Public/SentrySpan.h +++ b/plugin-dev/Source/Sentry/Public/SentrySpan.h @@ -1,27 +1,32 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. +// Copyright (c) 2023 Sentry. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "UObject/Object.h" + +#include "SentryImplWrapper.h" + #include "SentrySpan.generated.h" class ISentrySpan; /** * Unit of work within a transaction. + * + * NOTE: USentrySpan should not be constructed with NewObject<...>() etc., and should instead + * only be created by calling methods like StartChild(...) on this object or USentryTransaction. */ UCLASS(BlueprintType) -class SENTRY_API USentrySpan : public UObject +class SENTRY_API USentrySpan : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - USentrySpan(); - /** Starts a new child span. */ UFUNCTION(BlueprintCallable, Category = "Sentry") USentrySpan* StartChild(const FString& Operation, const FString& Description); + /** Starts a new child span with timestamp. */ UFUNCTION(BlueprintCallable, Category = "Sentry") USentrySpan* StartChildWithTimestamp(const FString& Operation, const FString& Description, int64 Timestamp); @@ -29,6 +34,7 @@ class SENTRY_API USentrySpan : public UObject /** Finishes and sends a span to Sentry. */ UFUNCTION(BlueprintCallable, Category = "Sentry") void Finish(); + /** Finishes with timestamp and sends a span to Sentry. */ UFUNCTION(BlueprintCallable, Category = "Sentry") void FinishWithTimestamp(int64 Timestamp); @@ -56,10 +62,4 @@ class SENTRY_API USentrySpan : public UObject /** Gets trace information that could be sent as a `sentry-trace` header */ UFUNCTION(BlueprintCallable, Category = "Sentry") void GetTrace(FString& name, FString& value); - - void InitWithNativeImpl(TSharedPtr spanImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr SentrySpanNativeImpl; }; diff --git a/plugin-dev/Source/Sentry/Public/SentryTransaction.h b/plugin-dev/Source/Sentry/Public/SentryTransaction.h index fe1539b02..7c3bbf551 100644 --- a/plugin-dev/Source/Sentry/Public/SentryTransaction.h +++ b/plugin-dev/Source/Sentry/Public/SentryTransaction.h @@ -1,9 +1,12 @@ -// Copyright (c) 2023 Sentry. All Rights Reserved. +// Copyright (c) 2023 Sentry. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "UObject/Object.h" + +#include "SentryImplWrapper.h" + #include "SentryTransaction.generated.h" class ISentryTransaction; @@ -13,23 +16,23 @@ class USentrySpan; * Representation of an activity to measure or track. */ UCLASS(BlueprintType) -class SENTRY_API USentryTransaction : public UObject +class SENTRY_API USentryTransaction : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - USentryTransaction(); - /** Starts a new child span. */ UFUNCTION(BlueprintCallable, Category = "Sentry") - USentrySpan* StartChild(const FString& Operation, const FString& Description); + USentrySpan* StartChildSpan(const FString& Operation, const FString& Description); + /** Starts a new child span with timestamp. */ UFUNCTION(BlueprintCallable, Category = "Sentry") - USentrySpan* StartChildWithTimestamp(const FString& Operation, const FString& Description, int64 Timestamp); + USentrySpan* StartChildSpanWithTimestamp(const FString& Operation, const FString& Description, int64 Timestamp); /** Finishes and sends a transaction to Sentry. */ UFUNCTION(BlueprintCallable, Category = "Sentry") void Finish(); + /** Finishes with timestamp and sends a transaction to Sentry. */ UFUNCTION(BlueprintCallable, Category = "Sentry") void FinishWithTimestamp(int64 Timestamp); @@ -61,10 +64,4 @@ class SENTRY_API USentryTransaction : public UObject /** Gets trace information that could be sent as a `sentry-trace` header */ UFUNCTION(BlueprintCallable, Category = "Sentry") void GetTrace(FString& name, FString& value); - - void InitWithNativeImpl(TSharedPtr transactionImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr SentryTransactionNativeImpl; }; diff --git a/plugin-dev/Source/Sentry/Public/SentryTransactionContext.h b/plugin-dev/Source/Sentry/Public/SentryTransactionContext.h index f59ed6c38..85073d264 100644 --- a/plugin-dev/Source/Sentry/Public/SentryTransactionContext.h +++ b/plugin-dev/Source/Sentry/Public/SentryTransactionContext.h @@ -4,20 +4,21 @@ #include "CoreMinimal.h" #include "UObject/Object.h" + +#include "SentryImplWrapper.h" + #include "SentryTransactionContext.generated.h" class ISentryTransactionContext; UCLASS(BlueprintType) -class SENTRY_API USentryTransactionContext : public UObject +class SENTRY_API USentryTransactionContext : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - USentryTransactionContext(); - /** - * Initializes transaction context with specified name and operation. + * Initializes the transaction context with the specified name and operation. * * @param Name Transaction name. * @param Operation Operation name. @@ -32,10 +33,4 @@ class SENTRY_API USentryTransactionContext : public UObject /** Gets operation name. */ UFUNCTION(BlueprintPure, Category = "Sentry") FString GetOperation() const; - - void InitWithNativeImpl(TSharedPtr transactionContextImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr SentryTransactionContextNativeImpl; }; diff --git a/plugin-dev/Source/Sentry/Public/SentryUser.h b/plugin-dev/Source/Sentry/Public/SentryUser.h index f30ac7a8e..0da6af58c 100644 --- a/plugin-dev/Source/Sentry/Public/SentryUser.h +++ b/plugin-dev/Source/Sentry/Public/SentryUser.h @@ -2,6 +2,8 @@ #pragma once +#include "SentryImplWrapper.h" + #include "SentryUser.generated.h" class ISentryUser; @@ -10,12 +12,13 @@ class ISentryUser; * Information about the user who triggered an event. */ UCLASS(BlueprintType) -class SENTRY_API USentryUser : public UObject +class SENTRY_API USentryUser : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - USentryUser(); + /** Initialize the user. */ + void Initialize(); /** Sets the email address of the user. */ UFUNCTION(BlueprintCallable, Category = "Sentry") @@ -56,10 +59,4 @@ class SENTRY_API USentryUser : public UObject /** Gets additional arbitrary fields related to the user. */ UFUNCTION(BlueprintPure, Category = "Sentry") TMap GetData() const; - - void InitWithNativeImpl(TSharedPtr userImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr UserNativeImpl; }; diff --git a/plugin-dev/Source/Sentry/Public/SentryUserFeedback.h b/plugin-dev/Source/Sentry/Public/SentryUserFeedback.h index 1dc6115b9..fd7bb0dcd 100644 --- a/plugin-dev/Source/Sentry/Public/SentryUserFeedback.h +++ b/plugin-dev/Source/Sentry/Public/SentryUserFeedback.h @@ -2,6 +2,8 @@ #pragma once +#include "SentryImplWrapper.h" + #include "SentryUserFeedback.generated.h" class USentryId; @@ -11,13 +13,16 @@ class ISentryUserFeedback; * Additional information about what happened to an event. */ UCLASS(BlueprintType) -class SENTRY_API USentryUserFeedback : public UObject +class SENTRY_API USentryUserFeedback : public UObject, public TSentryImplWrapper { GENERATED_BODY() public: - - /** Initializes user feedback with Id of the event to which it is associated. */ + /** + * Initializes the user feedback with the event identifier to which it is associated. + * + * @param EventId The associated event identifier. + */ UFUNCTION(BlueprintCallable, Category = "Sentry") void Initialize(USentryId* EventId); @@ -44,10 +49,4 @@ class SENTRY_API USentryUserFeedback : public UObject /** Gets comments of the user about what happened. */ UFUNCTION(BlueprintPure, Category = "Sentry") FString GetComment() const; - - void InitWithNativeImpl(TSharedPtr userFeedbackImpl); - TSharedPtr GetNativeImpl(); - -private: - TSharedPtr UserFeedbackNativeImpl; -}; \ No newline at end of file +}; diff --git a/plugin-dev/Source/Sentry/Sentry.Build.cs b/plugin-dev/Source/Sentry/Sentry.Build.cs index cce5befee..021412bae 100644 --- a/plugin-dev/Source/Sentry/Sentry.Build.cs +++ b/plugin-dev/Source/Sentry/Sentry.Build.cs @@ -73,6 +73,7 @@ public Sentry(ReadOnlyTargetRules Target) : base(Target) AdditionalPropertiesForReceipt.Add("IOSPlugin", Path.Combine(PluginPath, "Sentry_IOS_UPL.xml")); + PublicDefinitions.Add("USE_SENTRY_NATIVE=0"); PublicDefinitions.Add("COCOAPODS=0"); PublicDefinitions.Add("SENTRY_NO_UIKIT=1"); PublicDefinitions.Add("APPLICATION_EXTENSION_API_ONLY_NO=0"); @@ -87,6 +88,8 @@ public Sentry(ReadOnlyTargetRules Target) : base(Target) string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath); AdditionalPropertiesForReceipt.Add("AndroidPlugin", Path.Combine(PluginPath, "Sentry_Android_UPL.xml")); + + PublicDefinitions.Add("USE_SENTRY_NATIVE=0"); } // Additional routine for Windows @@ -97,7 +100,7 @@ public Sentry(ReadOnlyTargetRules Target) : base(Target) string WindowsThirdPartyPath = Path.Combine(PlatformThirdPartyPath, CrashpadExists ? "Crashpad" : "Breakpad"); PublicIncludePaths.Add(Path.Combine(WindowsThirdPartyPath, "include")); - PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "Private", "Desktop")); + PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "Private", "Windows")); PublicAdditionalLibraries.Add(Path.Combine(WindowsThirdPartyPath, "lib", "sentry.lib")); @@ -137,7 +140,7 @@ public Sentry(ReadOnlyTargetRules Target) : base(Target) AddEngineThirdPartyPrivateStaticDependencies(Target, "libcurl"); PublicIncludePaths.Add(Path.Combine(PlatformThirdPartyPath, "include")); - PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "Private", "Desktop")); + PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "Private", "Linux")); RuntimeDependencies.Add(Path.Combine(PlatformBinariesPath, "crashpad_handler"), Path.Combine(PlatformThirdPartyPath, "bin", "crashpad_handler")); diff --git a/sample/Content/UI/W_SentryDemo.uasset b/sample/Content/UI/W_SentryDemo.uasset index 0cddb537c..0dc1244ec 100644 Binary files a/sample/Content/UI/W_SentryDemo.uasset and b/sample/Content/UI/W_SentryDemo.uasset differ diff --git a/scripts/packaging/package-github.snapshot b/scripts/packaging/package-github.snapshot index f411aeab7..d2b40bdf9 100644 --- a/scripts/packaging/package-github.snapshot +++ b/scripts/packaging/package-github.snapshot @@ -91,37 +91,53 @@ Source/Sentry/Private/Apple/SentryUserApple.cpp Source/Sentry/Private/Apple/SentryUserApple.h Source/Sentry/Private/Apple/SentryUserFeedbackApple.cpp Source/Sentry/Private/Apple/SentryUserFeedbackApple.h -Source/Sentry/Private/Desktop/ -Source/Sentry/Private/Desktop/Convenience/ -Source/Sentry/Private/Desktop/Convenience/SentryInclude.h -Source/Sentry/Private/Desktop/CrashReporter/ -Source/Sentry/Private/Desktop/CrashReporter/SentryCrashContext.cpp -Source/Sentry/Private/Desktop/CrashReporter/SentryCrashContext.h -Source/Sentry/Private/Desktop/CrashReporter/SentryCrashReporter.cpp -Source/Sentry/Private/Desktop/CrashReporter/SentryCrashReporter.h -Source/Sentry/Private/Desktop/Infrastructure/ -Source/Sentry/Private/Desktop/Infrastructure/SentryConvertersDesktop.cpp -Source/Sentry/Private/Desktop/Infrastructure/SentryConvertersDesktop.h -Source/Sentry/Private/Desktop/SentryBreadcrumbDesktop.cpp -Source/Sentry/Private/Desktop/SentryBreadcrumbDesktop.h -Source/Sentry/Private/Desktop/SentryEventDesktop.cpp -Source/Sentry/Private/Desktop/SentryEventDesktop.h -Source/Sentry/Private/Desktop/SentryIdDesktop.cpp -Source/Sentry/Private/Desktop/SentryIdDesktop.h -Source/Sentry/Private/Desktop/SentryScopeDesktop.cpp -Source/Sentry/Private/Desktop/SentryScopeDesktop.h -Source/Sentry/Private/Desktop/SentrySpanDesktop.cpp -Source/Sentry/Private/Desktop/SentrySpanDesktop.h -Source/Sentry/Private/Desktop/SentrySubsystemDesktop.cpp -Source/Sentry/Private/Desktop/SentrySubsystemDesktop.h -Source/Sentry/Private/Desktop/SentryTransactionContextDesktop.cpp -Source/Sentry/Private/Desktop/SentryTransactionContextDesktop.h -Source/Sentry/Private/Desktop/SentryTransactionDesktop.cpp -Source/Sentry/Private/Desktop/SentryTransactionDesktop.h -Source/Sentry/Private/Desktop/SentryUserDesktop.cpp -Source/Sentry/Private/Desktop/SentryUserDesktop.h -Source/Sentry/Private/Desktop/SentryUserFeedbackDesktop.cpp -Source/Sentry/Private/Desktop/SentryUserFeedbackDesktop.h +Source/Sentry/Private/Core/ +Source/Sentry/Private/Core/SentryDsnUrl.h +Source/Sentry/Private/GenericPlatform/ +Source/Sentry/Private/GenericPlatform/Convenience/ +Source/Sentry/Private/GenericPlatform/Convenience/SentryInclude.h +Source/Sentry/Private/GenericPlatform/CrashReporter/ +Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.cpp +Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.h +Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.cpp +Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryBreadcrumb.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryBreadcrumb.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryId.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryId.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryScope.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryScope.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySpan.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySpan.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransaction.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransaction.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransactionContext.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransactionContext.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUser.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUser.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUserFeedback.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUserFeedback.h +Source/Sentry/Private/GenericPlatform/Infrastructure/ +Source/Sentry/Private/GenericPlatform/Infrastructure/GenericPlatformSentryConverters.cpp +Source/Sentry/Private/GenericPlatform/Infrastructure/GenericPlatformSentryConverters.h +Source/Sentry/Private/HAL/ +Source/Sentry/Private/HAL/PlatformSentryAttachment.h +Source/Sentry/Private/HAL/PlatformSentryBreadcrumb.h +Source/Sentry/Private/HAL/PlatformSentryEvent.h +Source/Sentry/Private/HAL/PlatformSentryHint.h +Source/Sentry/Private/HAL/PlatformSentryId.h +Source/Sentry/Private/HAL/PlatformSentrySamplingContext.h +Source/Sentry/Private/HAL/PlatformSentryScope.h +Source/Sentry/Private/HAL/PlatformSentrySpan.h +Source/Sentry/Private/HAL/PlatformSentrySubsystem.h +Source/Sentry/Private/HAL/PlatformSentryTransaction.h +Source/Sentry/Private/HAL/PlatformSentryTransactionContext.h +Source/Sentry/Private/HAL/PlatformSentryUser.h +Source/Sentry/Private/HAL/PlatformSentryUserFeedback.h Source/Sentry/Private/Interface/ Source/Sentry/Private/Interface/SentryAttachmentInterface.h Source/Sentry/Private/Interface/SentryBreadcrumbInterface.h @@ -136,6 +152,16 @@ Source/Sentry/Private/Interface/SentryTransactionContextInterface.h Source/Sentry/Private/Interface/SentryTransactionInterface.h Source/Sentry/Private/Interface/SentryUserFeedbackInterface.h Source/Sentry/Private/Interface/SentryUserInterface.h +Source/Sentry/Private/Linux/ +Source/Sentry/Private/Linux/LinuxSentrySubsystem.cpp +Source/Sentry/Private/Linux/LinuxSentrySubsystem.h +Source/Sentry/Private/Microsoft/ +Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.cpp +Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.h +Source/Sentry/Private/Null/ +Source/Sentry/Private/Null/NullSentryAttachment.h +Source/Sentry/Private/Null/NullSentryHint.h +Source/Sentry/Private/Null/NullSentrySamplingContext.h Source/Sentry/Private/SentryAttachment.cpp Source/Sentry/Private/SentryBeforeSendHandler.cpp Source/Sentry/Private/SentryBreadcrumb.cpp @@ -171,6 +197,12 @@ Source/Sentry/Private/Utils/SentryLogUtils.cpp Source/Sentry/Private/Utils/SentryLogUtils.h Source/Sentry/Private/Utils/SentryScreenshotUtils.cpp Source/Sentry/Private/Utils/SentryScreenshotUtils.h +Source/Sentry/Private/Windows/ +Source/Sentry/Private/Windows/Infrastructure/ +Source/Sentry/Private/Windows/Infrastructure/WindowsSentryConverters.cpp +Source/Sentry/Private/Windows/Infrastructure/WindowsSentryConverters.h +Source/Sentry/Private/Windows/WindowsSentrySubsystem.cpp +Source/Sentry/Private/Windows/WindowsSentrySubsystem.h Source/Sentry/Public/ Source/Sentry/Public/SentryAttachment.h Source/Sentry/Public/SentryBeforeSendHandler.h @@ -179,6 +211,7 @@ Source/Sentry/Public/SentryDataTypes.h Source/Sentry/Public/SentryEvent.h Source/Sentry/Public/SentryHint.h Source/Sentry/Public/SentryId.h +Source/Sentry/Public/SentryImplWrapper.h Source/Sentry/Public/SentryLibrary.h Source/Sentry/Public/SentryModule.h Source/Sentry/Public/SentryOutputDevice.h diff --git a/scripts/packaging/package-marketplace.snapshot b/scripts/packaging/package-marketplace.snapshot index b4fcde047..42d9773ba 100644 --- a/scripts/packaging/package-marketplace.snapshot +++ b/scripts/packaging/package-marketplace.snapshot @@ -89,37 +89,53 @@ Source/Sentry/Private/Apple/SentryUserApple.cpp Source/Sentry/Private/Apple/SentryUserApple.h Source/Sentry/Private/Apple/SentryUserFeedbackApple.cpp Source/Sentry/Private/Apple/SentryUserFeedbackApple.h -Source/Sentry/Private/Desktop/ -Source/Sentry/Private/Desktop/Convenience/ -Source/Sentry/Private/Desktop/Convenience/SentryInclude.h -Source/Sentry/Private/Desktop/CrashReporter/ -Source/Sentry/Private/Desktop/CrashReporter/SentryCrashContext.cpp -Source/Sentry/Private/Desktop/CrashReporter/SentryCrashContext.h -Source/Sentry/Private/Desktop/CrashReporter/SentryCrashReporter.cpp -Source/Sentry/Private/Desktop/CrashReporter/SentryCrashReporter.h -Source/Sentry/Private/Desktop/Infrastructure/ -Source/Sentry/Private/Desktop/Infrastructure/SentryConvertersDesktop.cpp -Source/Sentry/Private/Desktop/Infrastructure/SentryConvertersDesktop.h -Source/Sentry/Private/Desktop/SentryBreadcrumbDesktop.cpp -Source/Sentry/Private/Desktop/SentryBreadcrumbDesktop.h -Source/Sentry/Private/Desktop/SentryEventDesktop.cpp -Source/Sentry/Private/Desktop/SentryEventDesktop.h -Source/Sentry/Private/Desktop/SentryIdDesktop.cpp -Source/Sentry/Private/Desktop/SentryIdDesktop.h -Source/Sentry/Private/Desktop/SentryScopeDesktop.cpp -Source/Sentry/Private/Desktop/SentryScopeDesktop.h -Source/Sentry/Private/Desktop/SentrySpanDesktop.cpp -Source/Sentry/Private/Desktop/SentrySpanDesktop.h -Source/Sentry/Private/Desktop/SentrySubsystemDesktop.cpp -Source/Sentry/Private/Desktop/SentrySubsystemDesktop.h -Source/Sentry/Private/Desktop/SentryTransactionContextDesktop.cpp -Source/Sentry/Private/Desktop/SentryTransactionContextDesktop.h -Source/Sentry/Private/Desktop/SentryTransactionDesktop.cpp -Source/Sentry/Private/Desktop/SentryTransactionDesktop.h -Source/Sentry/Private/Desktop/SentryUserDesktop.cpp -Source/Sentry/Private/Desktop/SentryUserDesktop.h -Source/Sentry/Private/Desktop/SentryUserFeedbackDesktop.cpp -Source/Sentry/Private/Desktop/SentryUserFeedbackDesktop.h +Source/Sentry/Private/Core/ +Source/Sentry/Private/Core/SentryDsnUrl.h +Source/Sentry/Private/GenericPlatform/ +Source/Sentry/Private/GenericPlatform/Convenience/ +Source/Sentry/Private/GenericPlatform/Convenience/SentryInclude.h +Source/Sentry/Private/GenericPlatform/CrashReporter/ +Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.cpp +Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashContext.h +Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.cpp +Source/Sentry/Private/GenericPlatform/CrashReporter/GenericPlatformSentryCrashReporter.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryBreadcrumb.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryBreadcrumb.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryEvent.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryId.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryId.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryScope.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryScope.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySpan.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySpan.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentrySubsystem.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransaction.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransaction.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransactionContext.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryTransactionContext.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUser.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUser.h +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUserFeedback.cpp +Source/Sentry/Private/GenericPlatform/GenericPlatformSentryUserFeedback.h +Source/Sentry/Private/GenericPlatform/Infrastructure/ +Source/Sentry/Private/GenericPlatform/Infrastructure/GenericPlatformSentryConverters.cpp +Source/Sentry/Private/GenericPlatform/Infrastructure/GenericPlatformSentryConverters.h +Source/Sentry/Private/HAL/ +Source/Sentry/Private/HAL/PlatformSentryAttachment.h +Source/Sentry/Private/HAL/PlatformSentryBreadcrumb.h +Source/Sentry/Private/HAL/PlatformSentryEvent.h +Source/Sentry/Private/HAL/PlatformSentryHint.h +Source/Sentry/Private/HAL/PlatformSentryId.h +Source/Sentry/Private/HAL/PlatformSentrySamplingContext.h +Source/Sentry/Private/HAL/PlatformSentryScope.h +Source/Sentry/Private/HAL/PlatformSentrySpan.h +Source/Sentry/Private/HAL/PlatformSentrySubsystem.h +Source/Sentry/Private/HAL/PlatformSentryTransaction.h +Source/Sentry/Private/HAL/PlatformSentryTransactionContext.h +Source/Sentry/Private/HAL/PlatformSentryUser.h +Source/Sentry/Private/HAL/PlatformSentryUserFeedback.h Source/Sentry/Private/Interface/ Source/Sentry/Private/Interface/SentryAttachmentInterface.h Source/Sentry/Private/Interface/SentryBreadcrumbInterface.h @@ -134,6 +150,16 @@ Source/Sentry/Private/Interface/SentryTransactionContextInterface.h Source/Sentry/Private/Interface/SentryTransactionInterface.h Source/Sentry/Private/Interface/SentryUserFeedbackInterface.h Source/Sentry/Private/Interface/SentryUserInterface.h +Source/Sentry/Private/Linux/ +Source/Sentry/Private/Linux/LinuxSentrySubsystem.cpp +Source/Sentry/Private/Linux/LinuxSentrySubsystem.h +Source/Sentry/Private/Microsoft/ +Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.cpp +Source/Sentry/Private/Microsoft/MicrosoftSentrySubsystem.h +Source/Sentry/Private/Null/ +Source/Sentry/Private/Null/NullSentryAttachment.h +Source/Sentry/Private/Null/NullSentryHint.h +Source/Sentry/Private/Null/NullSentrySamplingContext.h Source/Sentry/Private/SentryAttachment.cpp Source/Sentry/Private/SentryBeforeSendHandler.cpp Source/Sentry/Private/SentryBreadcrumb.cpp @@ -169,6 +195,12 @@ Source/Sentry/Private/Utils/SentryLogUtils.cpp Source/Sentry/Private/Utils/SentryLogUtils.h Source/Sentry/Private/Utils/SentryScreenshotUtils.cpp Source/Sentry/Private/Utils/SentryScreenshotUtils.h +Source/Sentry/Private/Windows/ +Source/Sentry/Private/Windows/Infrastructure/ +Source/Sentry/Private/Windows/Infrastructure/WindowsSentryConverters.cpp +Source/Sentry/Private/Windows/Infrastructure/WindowsSentryConverters.h +Source/Sentry/Private/Windows/WindowsSentrySubsystem.cpp +Source/Sentry/Private/Windows/WindowsSentrySubsystem.h Source/Sentry/Public/ Source/Sentry/Public/SentryAttachment.h Source/Sentry/Public/SentryBeforeSendHandler.h @@ -177,6 +209,7 @@ Source/Sentry/Public/SentryDataTypes.h Source/Sentry/Public/SentryEvent.h Source/Sentry/Public/SentryHint.h Source/Sentry/Public/SentryId.h +Source/Sentry/Public/SentryImplWrapper.h Source/Sentry/Public/SentryLibrary.h Source/Sentry/Public/SentryModule.h Source/Sentry/Public/SentryOutputDevice.h