Skip to content

Unreal Engine: Add event fingerprint API docs #13808

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
40 changes: 40 additions & 0 deletions docs/platforms/unreal/usage/sdk-fingerprinting/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: "SDK Fingerprinting"
description: "Learn about overriding default fingerprinting in your SDK."
sidebar_order: 30
---

All events have a fingerprint. Events with the same fingerprint are grouped together into an issue.

By default, Sentry will run one of our built-in grouping algorithms to generate a fingerprint based on information available within the event such as `stacktrace`, `exception`, and `message`. To extend the default grouping behavior or change it completely, you can use a combination of the following options:

1. In your SDK, using SDK Fingerprinting, as documented below
2. In your project, using [Fingerprint Rules](/concepts/data-management/event-grouping/fingerprint-rules/) or [Stack Trace Rules](/concepts/data-management/event-grouping/stack-trace-rules/)

In supported SDKs, you can override Sentry's default grouping that passes the fingerprint attribute as an array of strings. The length of a fingerprint's array is not restricted. This works similarly to the [fingerprint rules functionality](/concepts/data-management/event-grouping/fingerprint-rules/), which is always available and can achieve similar results.

## Basic Example

In the most basic case, values are passed directly:

<PlatformContent includePath="set-fingerprint/basic" />

You can use variable substitution to fill dynamic values into the fingerprint generally computed on the server. For instance, the value `{{ default }}` can be added to add the entire normally generated grouping hash into the fingerprint. These values are the same as for server-side fingerprinting. See [Variables](/concepts/data-management/event-grouping/fingerprint-rules/#variables) for more information.

## Group Errors With Greater Granularity

In some scenarios, you'll want to group errors more granularly.

For example, if your application queries a Remote Procedure Call Model (RPC) interface or external Application Programming Interface (API) service, the stack trace is generally the same, even if the outgoing request is very different.

The following example will split up the default group Sentry would create (represented by `{{ default }}`) further, taking some attributes on the error object into account:

<PlatformContent includePath="set-fingerprint/rpc" />

## Group Errors More Aggressively

You can also overwrite Sentry's grouping entirely.

For example, if a generic error, such as a database connection error, has many different stack traces and never groups them together, you can overwrite Sentry's grouping by omitting `{{ default }}` from the array:

<PlatformContent includePath="set-fingerprint/database-connection" />
33 changes: 33 additions & 0 deletions platform-includes/set-fingerprint/basic/unreal.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
```cpp
FHttpModule* Http = &FHttpModule::Get();
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> HttpRequest = Http->CreateRequest();

// Configure the request
HttpRequest->SetURL(URL);
HttpRequest->SetVerb("POST");
HttpRequest->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
HttpRequest->SetContentAsString(JsonString);
HttpRequest->OnProcessRequestComplete().BindLambda([=](FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
if (bWasSuccessful && Response.IsValid() && Response->GetResponseCode() != 200)
{
// Handle successful response
}
else
{
TArray<FString> Fingerprint;
Fingerprint.Add("http-request-error");
Fingerprint.Add(Request->GetURL());
Fingerprint.Add(Request->GetVerb());

// Add more context if needed

USentryEvent* Event = NewObject<USentryEvent>();
Event->Initialize();
Event->SetFingerprint(Fingerprint);

USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem<USentrySubsystem>();
SentrySubsystem->CaptureEvent(Event, ESentryLevel::Error);
}
});
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
```cpp
USentryEvent* Event = NewObject<USentryEvent>();
Event->Initialize();
Event->SetFingerprint( { "database-connection-error" } );

USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem<USentrySubsystem>();
SentrySubsystem->CaptureEvent(Event, ESentryLevel::Error);
```
22 changes: 22 additions & 0 deletions platform-includes/set-fingerprint/rpc/unreal.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
```cpp
USTRUCT()
struct FSomeRpcError
{
GENERATED_BODY()

UPROPERTY()
FString Function;
UPROPERTY()
FString Code;
}

// Some code that emits RPC error info
FSomeRpcError RpcError = /* ... */

USentryEvent* Event = NewObject<USentryEvent>();
Event->Initialize();
Event->SetFingerprint( { "{{ default }}", RpcError.Function, RpcError.Code } );

USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem<USentrySubsystem>();
SentrySubsystem->CaptureEvent(Event, ESentryLevel::Error);
```