Skip to content

Add API allowing to get/set event fingerprint #920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Features

- Add API allowing to get/set event fingerprint ([#920](https://github.com/getsentry/sentry-unreal/pull/920))

### Dependencies

- Bump Java SDK (Android) from v8.11.1 to v8.12.0 ([#911](https://github.com/getsentry/sentry-unreal/pull/911))
Expand Down
13 changes: 13 additions & 0 deletions plugin-dev/Source/Sentry/Private/Android/AndroidSentryEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ void FAndroidSentryEvent::SetupClassMethods()
GetMessageMethod = GetMethod("getMessage", "()Lio/sentry/protocol/Message;");
SetLevelMethod = GetMethod("setLevel", "(Lio/sentry/SentryLevel;)V");
GetLevelMethod = GetMethod("getLevel", "()Lio/sentry/SentryLevel;");
SetFingerprintMethod = GetMethod("setFingerprints", "(Ljava/util/List;)V");
GetFingerprintMethod = GetMethod("getFingerprints()", "()Ljava/util/List;");
IsCrashMethod = GetMethod("isCrashed", "()Z");
}

Expand Down Expand Up @@ -57,6 +59,17 @@ ESentryLevel FAndroidSentryEvent::GetLevel() const
return FAndroidSentryConverters::SentryLevelToUnreal(*level);
}

void FAndroidSentryEvent::SetFingerprint(const TArray<FString>& fingerprint)
{
CallMethod<void>(SetFingerprintMethod, FAndroidSentryConverters::StringArrayToNative(fingerprint)->GetJObject());
}

TArray<FString> FAndroidSentryEvent::GetFingerprint()
{
auto fingerprint = CallObjectMethod<jobject>(GetFingerprintMethod);
return FAndroidSentryConverters::StringListToUnreal(*fingerprint);
}

bool FAndroidSentryEvent::IsCrash() const
{
return CallMethod<bool>(IsCrashMethod);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class FAndroidSentryEvent : public ISentryEvent, public FSentryJavaObjectWrapper
virtual FString GetMessage() const override;
virtual void SetLevel(ESentryLevel level) override;
virtual ESentryLevel GetLevel() const override;
virtual void SetFingerprint(const TArray<FString>& fingerprint) override;
virtual TArray<FString> GetFingerprint() override;
virtual bool IsCrash() const override;
virtual bool IsAnr() const override;

Expand All @@ -28,6 +30,8 @@ class FAndroidSentryEvent : public ISentryEvent, public FSentryJavaObjectWrapper
FSentryJavaMethod GetMessageMethod;
FSentryJavaMethod SetLevelMethod;
FSentryJavaMethod GetLevelMethod;
FSentryJavaMethod SetFingerprintMethod;
FSentryJavaMethod GetFingerprintMethod;
FSentryJavaMethod IsCrashMethod;
};

Expand Down
10 changes: 10 additions & 0 deletions plugin-dev/Source/Sentry/Private/Apple/AppleSentryEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ ESentryLevel FAppleSentryEvent::GetLevel() const
return FAppleSentryConverters::SentryLevelToUnreal(EventApple.level);
}

void FAppleSentryEvent::SetFingerprint(const TArray<FString>& fingerprint)
{
EventApple.fingerprint = FAppleSentryConverters::StringArrayToNative(fingerprint);
}

TArray<FString> FAppleSentryEvent::GetFingerprint()
{
return FAppleSentryConverters::StringArrayToUnreal(EventApple.fingerprint);
}

bool FAppleSentryEvent::IsCrash() const
{
return EventApple.error != nullptr;
Expand Down
2 changes: 2 additions & 0 deletions plugin-dev/Source/Sentry/Private/Apple/AppleSentryEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class FAppleSentryEvent : public ISentryEvent
virtual FString GetMessage() const override;
virtual void SetLevel(ESentryLevel level) override;
virtual ESentryLevel GetLevel() const override;
virtual void SetFingerprint(const TArray<FString>& fingerprint) override;
virtual TArray<FString> GetFingerprint() override;
virtual bool IsCrash() const override;
virtual bool IsAnr() const override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ ESentryLevel FGenericPlatformSentryEvent::GetLevel() const
return FGenericPlatformSentryConverters::SentryLevelToUnreal(level);
}

void FGenericPlatformSentryEvent::SetFingerprint(const TArray<FString>& fingerprint)
{
sentry_value_set_by_key(Event, "fingerprint", FGenericPlatformSentryConverters::StringArrayToNative(fingerprint));
}

TArray<FString> FGenericPlatformSentryEvent::GetFingerprint()
{
sentry_value_t fingerprint = sentry_value_get_by_key(Event, "fingerprint");
return FGenericPlatformSentryConverters::StringArrayToUnreal(fingerprint);
}

bool FGenericPlatformSentryEvent::IsCrash() const
{
return IsCrashEvent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class FGenericPlatformSentryEvent : public ISentryEvent
virtual FString GetMessage() const override;
virtual void SetLevel(ESentryLevel level) override;
virtual ESentryLevel GetLevel() const override;
virtual void SetFingerprint(const TArray<FString>& fingerprint) override;
virtual TArray<FString> GetFingerprint() override;
virtual bool IsCrash() const override;
virtual bool IsAnr() const override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class ISentryEvent
virtual FString GetMessage() const = 0;
virtual void SetLevel(ESentryLevel level) = 0;
virtual ESentryLevel GetLevel() const = 0;
virtual void SetFingerprint(const TArray<FString>& fingerprint) = 0;
virtual TArray<FString> GetFingerprint() = 0;
virtual bool IsCrash() const = 0;
virtual bool IsAnr() const = 0;
};
17 changes: 17 additions & 0 deletions plugin-dev/Source/Sentry/Private/SentryEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "SentryEvent.h"

#include "Algo/Find.h"
#include "HAL/PlatformSentryEvent.h"
#include "Interface/SentryIdInterface.h"

Expand Down Expand Up @@ -54,6 +55,22 @@ ESentryLevel USentryEvent::GetLevel() const
return NativeImpl->GetLevel();
}

void USentryEvent::SetFingerprint(const TArray<FString>& Fingerprint)
{
if (!NativeImpl)
return;

return NativeImpl->SetFingerprint(Fingerprint);
}

TArray<FString> USentryEvent::GetFingerprint() const
{
if (!NativeImpl)
return TArray<FString>();

return NativeImpl->GetFingerprint();
}

bool USentryEvent::IsCrash() const
{
if (!NativeImpl)
Expand Down
27 changes: 27 additions & 0 deletions plugin-dev/Source/Sentry/Private/Tests/SentryEvent.spec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,33 @@ void SentryEventSpec::Define()
TestFalse("Event ID is non-empty", SentryEvent->GetId().IsEmpty());
});
});

Describe("Event fingerprint", [this]()
{
It("should persist its value", [this]()
{
TArray<FString> InFingerprint = { TEXT("F1"), TEXT("F2"), TEXT("F3") };

SentryEvent->SetFingerprint(InFingerprint);
TArray<FString> OutFingerprint = SentryEvent->GetFingerprint();

TestEqual("Fingerprint elements count", OutFingerprint.Num(), InFingerprint.Num());
TestEqual("Fingerprint first element", OutFingerprint[0], InFingerprint[0]);
TestEqual("Fingerprint second element", OutFingerprint[1], InFingerprint[1]);
TestEqual("Fingerprint third element", OutFingerprint[2], InFingerprint[2]);
});

It("can be emptry", [this]()
{
TArray<FString> InFingerprint = {};

SentryEvent->SetFingerprint(InFingerprint);
TArray<FString> OutFingerprint = SentryEvent->GetFingerprint();

TestEqual("Fingerprint elements count", OutFingerprint.Num(), InFingerprint.Num());
TestEqual("Fingerprint is empty", OutFingerprint.Num(), 0);
});
});
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ bool SentryScreenshotUtils::CaptureScreenshot(const FString& ScreenshotSavePath)

#if UE_VERSION_OLDER_THAN(5, 0, 0)
GetHighResScreenshotConfig().MergeMaskIntoAlpha(*Bitmap);
TArray<uint8> *CompressedBitmap = new TArray<uint8>();
TArray<uint8>* CompressedBitmap = new TArray<uint8>();
FImageUtils::CompressImageArray(ViewportSize.X, ViewportSize.Y, *Bitmap, *CompressedBitmap);
#else
GetHighResScreenshotConfig().MergeMaskIntoAlpha(*Bitmap, FIntRect());
Expand Down
8 changes: 8 additions & 0 deletions plugin-dev/Source/Sentry/Public/SentryEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ class SENTRY_API USentryEvent : public UObject, public TSentryImplWrapper<ISentr
UFUNCTION(BlueprintPure, Category = "Sentry")
ESentryLevel GetLevel() const;

/** Sets fingerprint of the event. */
UFUNCTION(BlueprintCallable, Category = "Sentry")
void SetFingerprint(const TArray<FString>& Fingerprint);

/** Gets fingerprint of the event. */
UFUNCTION(BlueprintCallable, Category = "Sentry")
TArray<FString> GetFingerprint() const;

/** Gets flag indicating whether the event is a crash. */
UFUNCTION(BlueprintPure, Category = "Sentry")
bool IsCrash() const;
Expand Down