diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c330f64..0f66c4aaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Features +- Add API allowing to start/finish transactions and spans with explicit timings ([#715](https://github.com/getsentry/sentry-unreal/pull/715)) - Add GPU crash dump attachments ([#712](https://github.com/getsentry/sentry-unreal/pull/712)) ### Dependencies @@ -14,12 +15,9 @@ - Bump Java SDK (Android) from v7.18.1 to v7.19.0 ([#709](https://github.com/getsentry/sentry-unreal/pull/709)) - [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#7190) - [diff](https://github.com/getsentry/sentry-java/compare/7.18.1...7.19.0) -- Bump Cocoa SDK (iOS and Mac) from v8.41.0 to v8.42.0 ([#716](https://github.com/getsentry/sentry-unreal/pull/716)) - - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8420) - - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.41.0...8.42.0) -- Bump Cocoa SDK (iOS and Mac) from v8.42.0 to v8.42.1 ([#719](https://github.com/getsentry/sentry-unreal/pull/719)) +- Bump Cocoa SDK (iOS and Mac) from v8.41.0 to v8.42.1 ([#716](https://github.com/getsentry/sentry-unreal/pull/716), [#719](https://github.com/getsentry/sentry-unreal/pull/719)) - [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8421) - - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.42.0...8.42.1) + - [diff](https://github.com/getsentry/sentry-cocoa/compare/8.41.0...8.42.1) ## 0.21.1 diff --git a/plugin-dev/Source/Sentry/Private/Android/SentrySpanAndroid.cpp b/plugin-dev/Source/Sentry/Private/Android/SentrySpanAndroid.cpp index 5ef2abb2d..2c963d9d0 100644 --- a/plugin-dev/Source/Sentry/Private/Android/SentrySpanAndroid.cpp +++ b/plugin-dev/Source/Sentry/Private/Android/SentrySpanAndroid.cpp @@ -2,6 +2,8 @@ #include "SentrySpanAndroid.h" +#include "SentryDefines.h" + #include "Infrastructure/SentryConvertorsAndroid.h" #include "Infrastructure/SentryJavaClasses.h" @@ -13,6 +15,7 @@ SentrySpanAndroid::SentrySpanAndroid(jobject span) void SentrySpanAndroid::SetupClassMethods() { + StartChildMethod = GetMethod("startChild", "(Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ISpan;"); FinishMethod = GetMethod("finish", "()V"); IsFinishedMethod = GetMethod("isFinished", "()Z"); SetTagMethod = GetMethod("setTag", "(Ljava/lang/String;Ljava/lang/String;)V"); @@ -20,11 +23,29 @@ void SentrySpanAndroid::SetupClassMethods() ToSentryTraceMethod = GetMethod("toSentryTrace", "()Lio/sentry/SentryTraceHeader;"); } +TSharedPtr SentrySpanAndroid::StartChild(const FString& operation, const FString& desctiption) +{ + auto span = CallObjectMethod(StartChildMethod, *GetJString(operation), *GetJString(desctiption)); + return MakeShareable(new SentrySpanAndroid(*span)); +} + +TSharedPtr SentrySpanAndroid::StartChildWithTimestamp(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); +} + void SentrySpanAndroid::Finish() { CallMethod(FinishMethod); } +void SentrySpanAndroid::FinishWithTimestamp(int64 timestamp) +{ + UE_LOG(LogSentrySdk, Log, TEXT("Finishing span with explicit timestamp not supported on Android.")); + Finish(); +} + bool SentrySpanAndroid::IsFinished() const { return CallMethod(IsFinishedMethod);; diff --git a/plugin-dev/Source/Sentry/Private/Android/SentrySpanAndroid.h b/plugin-dev/Source/Sentry/Private/Android/SentrySpanAndroid.h index b1049d8cc..e8a10ee52 100644 --- a/plugin-dev/Source/Sentry/Private/Android/SentrySpanAndroid.h +++ b/plugin-dev/Source/Sentry/Private/Android/SentrySpanAndroid.h @@ -13,7 +13,10 @@ class SentrySpanAndroid : public ISentrySpan, public FSentryJavaObjectWrapper 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 void Finish() override; + virtual void FinishWithTimestamp(int64 timestamp) override; virtual bool IsFinished() const override; virtual void SetTag(const FString& key, const FString& value) override; virtual void RemoveTag(const FString& key) override; @@ -22,6 +25,7 @@ class SentrySpanAndroid : public ISentrySpan, public FSentryJavaObjectWrapper virtual void GetTrace(FString& name, FString& value) override; private: + FSentryJavaMethod StartChildMethod; FSentryJavaMethod FinishMethod; FSentryJavaMethod IsFinishedMethod; FSentryJavaMethod SetTagMethod; diff --git a/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.cpp b/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.cpp index 857c255ef..c90d2925e 100644 --- a/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.cpp +++ b/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.cpp @@ -274,6 +274,12 @@ TSharedPtr SentrySubsystemAndroid::StartTransactionWithConte return MakeShareable(new SentryTransactionAndroid(*transaction)); } +TSharedPtr SentrySubsystemAndroid::StartTransactionWithContextAndTimestamp(TSharedPtr context, int64 timestamp) +{ + UE_LOG(LogSentrySdk, Log, TEXT("Setting transaction timestamp explicitly not supported on Android.")); + return StartTransactionWithContext(context); +} + TSharedPtr SentrySubsystemAndroid::StartTransactionWithContextAndOptions(TSharedPtr context, const TMap& options) { TSharedPtr transactionContextAndroid = StaticCastSharedPtr(context); diff --git a/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.h b/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.h index f2ea97736..3926e049d 100644 --- a/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.h +++ b/plugin-dev/Source/Sentry/Private/Android/SentrySubsystemAndroid.h @@ -33,6 +33,7 @@ class SentrySubsystemAndroid : public ISentrySubsystem virtual void EndSession() override; virtual TSharedPtr StartTransaction(const FString& name, const FString& operation) override; virtual TSharedPtr StartTransactionWithContext(TSharedPtr context) override; + virtual TSharedPtr StartTransactionWithContextAndTimestamp(TSharedPtr context, int64 timestamp) override; virtual TSharedPtr StartTransactionWithContextAndOptions(TSharedPtr context, const TMap& options) override; virtual TSharedPtr ContinueTrace(const FString& sentryTrace, const TArray& baggageHeaders) override; }; diff --git a/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.cpp b/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.cpp index f3323b58a..7407d529e 100644 --- a/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.cpp +++ b/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.cpp @@ -3,6 +3,8 @@ #include "SentryTransactionAndroid.h" #include "SentrySpanAndroid.h" +#include "SentryDefines.h" + #include "Infrastructure/SentryConvertorsAndroid.h" #include "Infrastructure/SentryJavaClasses.h" @@ -29,11 +31,23 @@ TSharedPtr SentryTransactionAndroid::StartChild(const FString& oper return MakeShareable(new SentrySpanAndroid(*span)); } +TSharedPtr SentryTransactionAndroid::StartChildWithTimestamp(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); +} + void SentryTransactionAndroid::Finish() { CallMethod(FinishMethod); } +void SentryTransactionAndroid::FinishWithTimestamp(int64 timestamp) +{ + UE_LOG(LogSentrySdk, Log, TEXT("Finishing transaction with explicit timestamp not supported on Android.")); + Finish(); +} + bool SentryTransactionAndroid::IsFinished() const { return CallMethod(IsFinishedMethod);; diff --git a/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.h b/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.h index 284651b02..f7bb27f00 100644 --- a/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.h +++ b/plugin-dev/Source/Sentry/Private/Android/SentryTransactionAndroid.h @@ -14,7 +14,9 @@ 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 void Finish() override; + virtual void FinishWithTimestamp(int64 timestamp) override; virtual bool IsFinished() const override; virtual void SetName(const FString& name) override; virtual void SetTag(const FString& key, const FString& value) override; diff --git a/plugin-dev/Source/Sentry/Private/Apple/SentrySpanApple.cpp b/plugin-dev/Source/Sentry/Private/Apple/SentrySpanApple.cpp index ee513c8a1..b51ffa0aa 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/SentrySpanApple.cpp +++ b/plugin-dev/Source/Sentry/Private/Apple/SentrySpanApple.cpp @@ -25,11 +25,29 @@ id SentrySpanApple::GetNativeObject() return SpanApple; } +TSharedPtr SentrySpanApple::StartChild(const FString& operation, const FString& desctiption) +{ + id span = [SpanApple startChildWithOperation:operation.GetNSString() description:desctiption.GetNSString()]; + return MakeShareable(new SentrySpanApple(span)); +} + +TSharedPtr SentrySpanApple::StartChildWithTimestamp(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); +} + void SentrySpanApple::Finish() { [SpanApple finish]; } +void SentrySpanApple::FinishWithTimestamp(int64 timestamp) +{ + UE_LOG(LogSentrySdk, Log, TEXT("Finishing span with explicit timestamp not supported on Mac/iOS.")); + Finish(); +} + bool SentrySpanApple::IsFinished() const { return SpanApple.isFinished; diff --git a/plugin-dev/Source/Sentry/Private/Apple/SentrySpanApple.h b/plugin-dev/Source/Sentry/Private/Apple/SentrySpanApple.h index 514cc7229..62b2854c6 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/SentrySpanApple.h +++ b/plugin-dev/Source/Sentry/Private/Apple/SentrySpanApple.h @@ -14,7 +14,10 @@ class SentrySpanApple : public ISentrySpan 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 void Finish() override; + virtual void FinishWithTimestamp(int64 timestamp) override; virtual bool IsFinished() const override; virtual void SetTag(const FString& key, const FString& value) override; virtual void RemoveTag(const FString& key) override; diff --git a/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.cpp b/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.cpp index a5c166531..d98a99333 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.cpp +++ b/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.cpp @@ -296,6 +296,12 @@ TSharedPtr SentrySubsystemApple::StartTransactionWithContext return MakeShareable(new SentryTransactionApple(transaction)); } +TSharedPtr SentrySubsystemApple::StartTransactionWithContextAndTimestamp(TSharedPtr context, int64 timestamp) +{ + UE_LOG(LogSentrySdk, Log, TEXT("Setting transaction timestamp explicitly not supported on Mac/iOS.")); + return StartTransactionWithContext(context); +} + TSharedPtr SentrySubsystemApple::StartTransactionWithContextAndOptions(TSharedPtr context, const TMap& options) { TSharedPtr transactionContextIOS = StaticCastSharedPtr(context); diff --git a/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.h b/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.h index c57a0c2cc..ef2144025 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.h +++ b/plugin-dev/Source/Sentry/Private/Apple/SentrySubsystemApple.h @@ -33,6 +33,7 @@ class SentrySubsystemApple : public ISentrySubsystem virtual void EndSession() override; virtual TSharedPtr StartTransaction(const FString& name, const FString& operation) override; virtual TSharedPtr StartTransactionWithContext(TSharedPtr context) override; + virtual TSharedPtr StartTransactionWithContextAndTimestamp(TSharedPtr context, int64 timestamp) override; virtual TSharedPtr StartTransactionWithContextAndOptions(TSharedPtr context, const TMap& options) override; virtual TSharedPtr ContinueTrace(const FString& sentryTrace, const TArray& baggageHeaders) override; }; diff --git a/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.cpp b/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.cpp index 46770df03..7e19ecb56 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.cpp +++ b/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.cpp @@ -32,11 +32,23 @@ TSharedPtr SentryTransactionApple::StartChild(const FString& operat return MakeShareable(new SentrySpanApple(span)); } +TSharedPtr SentryTransactionApple::StartChildWithTimestamp(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); +} + void SentryTransactionApple::Finish() { [TransactionApple finish]; } +void SentryTransactionApple::FinishWithTimestamp(int64 timestamp) +{ + UE_LOG(LogSentrySdk, Log, TEXT("Finishing transaction with explicit timestamp not supported on Mac/iOS.")); + Finish(); +} + bool SentryTransactionApple::IsFinished() const { return TransactionApple.isFinished; diff --git a/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.h b/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.h index 74d3aacca..5b1307262 100644 --- a/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.h +++ b/plugin-dev/Source/Sentry/Private/Apple/SentryTransactionApple.h @@ -15,7 +15,9 @@ 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 void Finish() override; + virtual void FinishWithTimestamp(int64 timestamp) override; virtual bool IsFinished() const override; virtual void SetName(const FString& name) override; virtual void SetTag(const FString& key, const FString& value) override; diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.cpp index 1a302b4e1..7a3db5bb6 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.cpp +++ b/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.cpp @@ -28,6 +28,18 @@ 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); @@ -35,6 +47,13 @@ void SentrySpanDesktop::Finish() isFinished = true; } +void SentrySpanDesktop::FinishWithTimestamp(int64 timestamp) +{ + sentry_span_finish_ts(SpanDesktop, timestamp); + + isFinished = true; +} + bool SentrySpanDesktop::IsFinished() const { return isFinished; diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.h b/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.h index cf7862fc1..bf2f95fab 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.h +++ b/plugin-dev/Source/Sentry/Private/Desktop/SentrySpanDesktop.h @@ -18,7 +18,10 @@ class SentrySpanDesktop : public ISentrySpan 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 void Finish() override; + virtual void FinishWithTimestamp(int64 timestamp) override; virtual bool IsFinished() const override; virtual void SetTag(const FString& key, const FString& value) override; virtual void RemoveTag(const FString& key) override; diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.cpp index 6054f9f41..af7cfc798 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.cpp +++ b/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.cpp @@ -546,6 +546,15 @@ TSharedPtr SentrySubsystemDesktop::StartTransactionWithConte 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.")); diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.h b/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.h index c41a42a4b..27c3c62c6 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.h +++ b/plugin-dev/Source/Sentry/Private/Desktop/SentrySubsystemDesktop.h @@ -42,6 +42,7 @@ class SentrySubsystemDesktop : public ISentrySubsystem virtual void EndSession() override; virtual TSharedPtr StartTransaction(const FString& name, const FString& operation) override; virtual TSharedPtr StartTransactionWithContext(TSharedPtr context) override; + virtual TSharedPtr StartTransactionWithContextAndTimestamp(TSharedPtr context, int64 timestamp) override; virtual TSharedPtr StartTransactionWithContextAndOptions(TSharedPtr context, const TMap& options) override; virtual TSharedPtr ContinueTrace(const FString& sentryTrace, const TArray& baggageHeaders) override; diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.cpp b/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.cpp index 1e5c69247..b92401b1e 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.cpp +++ b/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.cpp @@ -34,6 +34,12 @@ TSharedPtr SentryTransactionDesktop::StartChild(const FString& oper 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); @@ -41,6 +47,13 @@ void SentryTransactionDesktop::Finish() isFinished = true; } +void SentryTransactionDesktop::FinishWithTimestamp(int64 timestamp) +{ + sentry_transaction_finish_ts(TransactionDesktop, timestamp); + + isFinished = true; +} + bool SentryTransactionDesktop::IsFinished() const { return isFinished; diff --git a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.h b/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.h index f226742fe..108468937 100644 --- a/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.h +++ b/plugin-dev/Source/Sentry/Private/Desktop/SentryTransactionDesktop.h @@ -19,7 +19,9 @@ class SentryTransactionDesktop : public ISentryTransaction 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 void Finish() override; + virtual void FinishWithTimestamp(int64 timestamp) override; virtual bool IsFinished() const override; virtual void SetName(const FString& name) override; virtual void SetTag(const FString& key, const FString& value) override; diff --git a/plugin-dev/Source/Sentry/Private/Interface/SentrySpanInterface.h b/plugin-dev/Source/Sentry/Private/Interface/SentrySpanInterface.h index a233d9052..a3aafdfaf 100644 --- a/plugin-dev/Source/Sentry/Private/Interface/SentrySpanInterface.h +++ b/plugin-dev/Source/Sentry/Private/Interface/SentrySpanInterface.h @@ -9,7 +9,10 @@ class ISentrySpan public: virtual ~ISentrySpan() = default; + virtual TSharedPtr StartChild(const FString& operation, const FString& desctiption) = 0; + virtual TSharedPtr StartChildWithTimestamp(const FString& operation, const FString& desctiption, int64 timestamp) = 0; virtual void Finish() = 0; + virtual void FinishWithTimestamp(int64 timestamp) = 0; virtual bool IsFinished() const = 0; virtual void SetTag(const FString& key, const FString& value) = 0; virtual void RemoveTag(const FString& key) = 0; diff --git a/plugin-dev/Source/Sentry/Private/Interface/SentrySubsystemInterface.h b/plugin-dev/Source/Sentry/Private/Interface/SentrySubsystemInterface.h index 8b471458c..b1fa26120 100644 --- a/plugin-dev/Source/Sentry/Private/Interface/SentrySubsystemInterface.h +++ b/plugin-dev/Source/Sentry/Private/Interface/SentrySubsystemInterface.h @@ -52,6 +52,7 @@ class ISentrySubsystem virtual void EndSession() = 0; virtual TSharedPtr StartTransaction(const FString& name, const FString& operation) = 0; virtual TSharedPtr StartTransactionWithContext(TSharedPtr context) = 0; + virtual TSharedPtr StartTransactionWithContextAndTimestamp(TSharedPtr context, int64 timestamp) = 0; virtual TSharedPtr StartTransactionWithContextAndOptions(TSharedPtr context, const TMap& options) = 0; virtual TSharedPtr ContinueTrace(const FString& sentryTrace, const TArray& baggageHeaders) = 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 5de43d8b1..723b38056 100644 --- a/plugin-dev/Source/Sentry/Private/Interface/SentryTransactionInterface.h +++ b/plugin-dev/Source/Sentry/Private/Interface/SentryTransactionInterface.h @@ -12,7 +12,9 @@ class ISentryTransaction 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 void Finish() = 0; + virtual void FinishWithTimestamp(int64 timestamp) = 0; virtual bool IsFinished() const = 0; virtual void SetName(const FString& name) = 0; virtual void SetTag(const FString& key, const FString& value) = 0; diff --git a/plugin-dev/Source/Sentry/Private/SentrySpan.cpp b/plugin-dev/Source/Sentry/Private/SentrySpan.cpp index e09ef5e51..b9d31a7c5 100644 --- a/plugin-dev/Source/Sentry/Private/SentrySpan.cpp +++ b/plugin-dev/Source/Sentry/Private/SentrySpan.cpp @@ -16,6 +16,32 @@ USentrySpan::USentrySpan() { } +USentrySpan* USentrySpan::StartChild(const FString& Operation, const FString& Description) +{ + if (!SentrySpanNativeImpl || SentrySpanNativeImpl->IsFinished()) + return nullptr; + + TSharedPtr spanNativeImpl = SentrySpanNativeImpl->StartChild(Operation, Description); + + USentrySpan* unrealSpan = NewObject(); + unrealSpan->InitWithNativeImpl(spanNativeImpl); + + return unrealSpan; +} + +USentrySpan* USentrySpan::StartChildWithTimestamp(const FString& Operation, const FString& Description, int64 Timestamp) +{ + if (!SentrySpanNativeImpl || SentrySpanNativeImpl->IsFinished()) + return nullptr; + + TSharedPtr spanNativeImpl = SentrySpanNativeImpl->StartChildWithTimestamp(Operation, Description, Timestamp); + + USentrySpan* unrealSpan = NewObject(); + unrealSpan->InitWithNativeImpl(spanNativeImpl); + + return unrealSpan; +} + void USentrySpan::Finish() { if (!SentrySpanNativeImpl) @@ -24,6 +50,14 @@ void USentrySpan::Finish() SentrySpanNativeImpl->Finish(); } +void USentrySpan::FinishWithTimestamp(int64 Timestamp) +{ + if (!SentrySpanNativeImpl) + return; + + SentrySpanNativeImpl->FinishWithTimestamp(Timestamp); +} + bool USentrySpan::IsFinished() const { if (!SentrySpanNativeImpl) diff --git a/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp b/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp index ce2f0d0dc..3c7e6428e 100644 --- a/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp +++ b/plugin-dev/Source/Sentry/Private/SentrySubsystem.cpp @@ -432,6 +432,19 @@ USentryTransaction* USentrySubsystem::StartTransactionWithContext(USentryTransac return unrealTransaction; } +USentryTransaction* USentrySubsystem::StartTransactionWithContextAndTimestamp(USentryTransactionContext* Context, int64 Timestamp) +{ + if (!SubsystemNativeImpl || !SubsystemNativeImpl->IsEnabled()) + return nullptr; + + TSharedPtr transactionNativeImpl = SubsystemNativeImpl->StartTransactionWithContextAndTimestamp(Context->GetNativeImpl(), Timestamp); + + USentryTransaction* unrealTransaction = NewObject(); + unrealTransaction->InitWithNativeImpl(transactionNativeImpl); + + return unrealTransaction; +} + USentryTransaction* USentrySubsystem::StartTransactionWithContextAndOptions(USentryTransactionContext* Context, const TMap& Options) { if (!SubsystemNativeImpl || !SubsystemNativeImpl->IsEnabled()) diff --git a/plugin-dev/Source/Sentry/Private/SentryTransaction.cpp b/plugin-dev/Source/Sentry/Private/SentryTransaction.cpp index 4d4f9db4d..a8f4a7ca6 100644 --- a/plugin-dev/Source/Sentry/Private/SentryTransaction.cpp +++ b/plugin-dev/Source/Sentry/Private/SentryTransaction.cpp @@ -30,6 +30,19 @@ USentrySpan* USentryTransaction::StartChild(const FString& Operation, const FStr return unrealSpan; } +USentrySpan* USentryTransaction::StartChildWithTimestamp(const FString& Operation, const FString& Description, int64 Timestamp) +{ + if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + return nullptr; + + TSharedPtr spanNativeImpl = SentryTransactionNativeImpl->StartChildWithTimestamp(Operation, Description, Timestamp); + + USentrySpan* unrealSpan = NewObject(); + unrealSpan->InitWithNativeImpl(spanNativeImpl); + + return unrealSpan; +} + void USentryTransaction::Finish() { if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) @@ -38,6 +51,14 @@ void USentryTransaction::Finish() SentryTransactionNativeImpl->Finish(); } +void USentryTransaction::FinishWithTimestamp(int64 Timestamp) +{ + if (!SentryTransactionNativeImpl || SentryTransactionNativeImpl->IsFinished()) + return; + + SentryTransactionNativeImpl->FinishWithTimestamp(Timestamp); +} + bool USentryTransaction::IsFinished() const { if (!SentryTransactionNativeImpl) diff --git a/plugin-dev/Source/Sentry/Private/Tests/SentrySubsystem.spec.cpp b/plugin-dev/Source/Sentry/Private/Tests/SentrySubsystem.spec.cpp index 6ebe1fd78..d7aa483d8 100644 --- a/plugin-dev/Source/Sentry/Private/Tests/SentrySubsystem.spec.cpp +++ b/plugin-dev/Source/Sentry/Private/Tests/SentrySubsystem.spec.cpp @@ -9,6 +9,7 @@ #include "UObject/UObjectGlobals.h" #include "Misc/AutomationTest.h" +#include "Misc/DateTime.h" #include "Engine/Engine.h" #if WITH_AUTOMATION_TESTS @@ -80,6 +81,13 @@ void SentrySubsystemSpec::Define() TestNotNull("Span is non-null", span); TestFalse("Span is not finished", span->IsFinished()); + USentrySpan* childSpan = span->StartChildWithTimestamp(TEXT("Automation child span"), TEXT("Description text"), FDateTime::UtcNow().ToUnixTimestamp()); + TestNotNull("Child span is non-null", childSpan); + TestFalse("Child span is not finished", childSpan->IsFinished()); + + childSpan->FinishWithTimestamp(FDateTime::UtcNow().ToUnixTimestamp()); + TestTrue("Child span is finished", childSpan->IsFinished()); + span->Finish(); TestTrue("Span is finished", span->IsFinished()); @@ -99,6 +107,19 @@ void SentrySubsystemSpec::Define() transaction->Finish(); TestTrue("Transaction is finished", transaction->IsFinished()); }); + + It("should be started and finished with specific context and timings", [this]() + { + USentryTransactionContext* transactionContext = NewObject(); + transactionContext->Initialize(TEXT("Automation transaction"), TEXT("Automation operation")); + + USentryTransaction* transaction = SentrySubsystem->StartTransactionWithContextAndTimestamp(transactionContext, FDateTime::UtcNow().ToUnixTimestamp()); + TestNotNull("Transaction is non-null", transaction); + TestFalse("Transaction is not finished", transaction->IsFinished()); + + transaction->FinishWithTimestamp(FDateTime::UtcNow().ToUnixTimestamp()); + TestTrue("Transaction is finished", transaction->IsFinished()); + }); }); Describe("Transaction context", [this]() diff --git a/plugin-dev/Source/Sentry/Public/SentrySpan.h b/plugin-dev/Source/Sentry/Public/SentrySpan.h index 1aa4dbd0c..7dd137365 100644 --- a/plugin-dev/Source/Sentry/Public/SentrySpan.h +++ b/plugin-dev/Source/Sentry/Public/SentrySpan.h @@ -19,9 +19,19 @@ class SENTRY_API USentrySpan : public UObject 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); + /** 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); /** Checks whether the span finished. */ UFUNCTION(BlueprintPure, Category = "Sentry") diff --git a/plugin-dev/Source/Sentry/Public/SentrySubsystem.h b/plugin-dev/Source/Sentry/Public/SentrySubsystem.h index 4a11dc8ca..d707091ec 100644 --- a/plugin-dev/Source/Sentry/Public/SentrySubsystem.h +++ b/plugin-dev/Source/Sentry/Public/SentrySubsystem.h @@ -260,6 +260,17 @@ class SENTRY_API USentrySubsystem : public UEngineSubsystem UFUNCTION(BlueprintCallable, Category = "Sentry") USentryTransaction* StartTransactionWithContext(USentryTransactionContext* Context); + /** + * Starts a new transaction with given context and timestamp. + * Currently setting the explicit transaction timings takes effect on Windows and Linux only. + * On other platforms starts transaction like regular `StartTransactionWithContext`. + * + * @param Context Transaction context. + * @param Timestamp Transaction timestamp (microseconds since the Unix epoch). + */ + UFUNCTION(BlueprintCallable, Category = "Sentry") + USentryTransaction* StartTransactionWithContextAndTimestamp(USentryTransactionContext* Context, int64 Timestamp); + /** * Starts a new transaction with given context and options. * diff --git a/plugin-dev/Source/Sentry/Public/SentryTransaction.h b/plugin-dev/Source/Sentry/Public/SentryTransaction.h index e90ca02d2..fe1539b02 100644 --- a/plugin-dev/Source/Sentry/Public/SentryTransaction.h +++ b/plugin-dev/Source/Sentry/Public/SentryTransaction.h @@ -20,13 +20,19 @@ class SENTRY_API USentryTransaction : public UObject public: USentryTransaction(); - /** . */ + /** 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); /** 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); /** Checks whether the transaction finished. */ UFUNCTION(BlueprintPure, Category = "Sentry")