diff --git a/docs/platforms/unreal/usage/sdk-fingerprinting/index.mdx b/docs/platforms/unreal/usage/sdk-fingerprinting/index.mdx new file mode 100644 index 0000000000000..9bc4a4d4b772c --- /dev/null +++ b/docs/platforms/unreal/usage/sdk-fingerprinting/index.mdx @@ -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: + + + +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: + + + +## 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: + + diff --git a/platform-includes/set-fingerprint/basic/unreal.mdx b/platform-includes/set-fingerprint/basic/unreal.mdx new file mode 100644 index 0000000000000..df59c7313828d --- /dev/null +++ b/platform-includes/set-fingerprint/basic/unreal.mdx @@ -0,0 +1,33 @@ +```cpp +FHttpModule* Http = &FHttpModule::Get(); +TSharedRef 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 Fingerprint; + Fingerprint.Add("http-request-error"); + Fingerprint.Add(Request->GetURL()); + Fingerprint.Add(Request->GetVerb()); + + // Add more context if needed + + USentryEvent* Event = NewObject(); + Event->Initialize(); + Event->SetFingerprint(Fingerprint); + + USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); + SentrySubsystem->CaptureEvent(Event, ESentryLevel::Error); + } +}); +``` diff --git a/platform-includes/set-fingerprint/database-connection/unreal.mdx b/platform-includes/set-fingerprint/database-connection/unreal.mdx new file mode 100644 index 0000000000000..124b59a6fc102 --- /dev/null +++ b/platform-includes/set-fingerprint/database-connection/unreal.mdx @@ -0,0 +1,8 @@ +```cpp +USentryEvent* Event = NewObject(); +Event->Initialize(); +Event->SetFingerprint( { "database-connection-error" } ); + +USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); +SentrySubsystem->CaptureEvent(Event, ESentryLevel::Error); +``` diff --git a/platform-includes/set-fingerprint/rpc/unreal.mdx b/platform-includes/set-fingerprint/rpc/unreal.mdx new file mode 100644 index 0000000000000..78b564eff525a --- /dev/null +++ b/platform-includes/set-fingerprint/rpc/unreal.mdx @@ -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(); +Event->Initialize(); +Event->SetFingerprint( { "{{ default }}", RpcError.Function, RpcError.Code } ); + +USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); +SentrySubsystem->CaptureEvent(Event, ESentryLevel::Error); +```