Skip to content
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
38 changes: 38 additions & 0 deletions docs/platforms/godot/configuration/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,44 @@ This option currently only affects Web exports; other platforms always use the s

</SdkOption>

<SdkOption name="trace_propagation_targets" type="Array" defaultValue={'[".*"]'} availableSince="2.2.0">

Controls which downstream services can receive tracing headers.

When you pass a URL to `SentrySpan.get_trace_headers(url)`, the SDK returns headers only if that URL matches one of the targets.

- A `String` matches when it appears anywhere in the URL. The special string `".*"` matches every URL and is the only entry by default.
- A `RegEx` searches the complete URL. Use an anchored expression to match a specific origin.
- An empty array blocks headers for all URLs passed to `get_trace_headers(url)`.

Omitting the URL when calling `get_trace_headers()` bypasses this option, including an empty target list. This option doesn't attach headers automatically.

In **Project Settings > Sentry > Options**, **Trace Propagation Targets** accepts strings only. Add `RegEx` entries in your initialization callback. See <PlatformLink to="/tracing/distributed-tracing/limiting-trace-propagation/">Limiting Trace Propagation</PlatformLink> for an example.

</SdkOption>

<SdkOption name="propagate_traceparent" type="bool" defaultValue="false" availableSince="2.2.0">

Controls whether outgoing tracing headers include the W3C `traceparent` header alongside `sentry-trace` and `baggage`.

Set this option to `true` when your backend uses OpenTelemetry or another W3C Trace Context-compatible library to continue traces. `SentrySpan.get_trace_headers()` then includes `traceparent` in the returned headers.

[`trace_propagation_targets`](#trace_propagation_targets) controls where this header is allowed when you pass a URL. For Web exports, also <PlatformLink to="/tracing/distributed-tracing/dealing-with-cors-issues/">allow `traceparent` in your backend's CORS configuration</PlatformLink>.

<Include name="platforms/configuration/options/propagate-traceparent-tail-sampling.mdx" />

</SdkOption>

<SdkOption name="org_id" type="String" defaultValue={'""'} availableSince="2.2.0">

The organization ID for your Sentry project.

The SDK tries to extract the ID from your DSN. If it can't be found, or you need to override it when using self-hosted Sentry or a local Relay, set it with this option.

The ID is included as `sentry-org_id` in the outgoing `baggage` header. Downstream services can use it to check whether an incoming trace belongs to the same organization before continuing it.

</SdkOption>

## GUI-only Options

These options are only available in the **Project Settings** window.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: Custom Trace Propagation
description: "Learn how to attach trace headers to requests and start separate traces in your Godot game."
sidebar_order: 10
---

To follow an operation from your game into a backend service, attach the span's trace headers to the outgoing request. First, <PlatformLink to="/tracing/distributed-tracing/">set up distributed tracing</PlatformLink> in both your game and backend.

## Add Trace Headers to Requests

`SentrySpan.get_trace_headers(url)` returns a `PackedStringArray` of `Name: Value` strings. You can pass these directly to `HTTPRequest.request()`, `HTTPClient.request()`, or `WebSocketPeer.handshake_headers`. Pass the destination URL so the SDK applies your <PlatformLink to="/tracing/distributed-tracing/limiting-trace-propagation/">trace propagation targets</PlatformLink>.

This example measures a leaderboard request and adds tracing headers:

```GDScript {filename:leaderboard.gd}
extends Node

func fetch_scores() -> void:
var url := "https://api.example.com/scores"

# Add the request node to the scene tree and limit how long it can wait.
var request := HTTPRequest.new()
request.timeout = 10.0
add_child(request)

# Start an inactive span to measure the request, using the active span as its parent if available.
var span := SentrySDK.start_span(
"GET /scores",
{"sentry.op": "http.client"},
SentrySDK.get_active_span(),
false, # Keep it inactive so telemetry captured while it runs isn't associated with it.
)

# Get trace headers to connect the backend operation to this span.
# Passing the URL applies the configured trace propagation targets.
var headers := span.get_trace_headers(url)

var error := request.request(url, headers)
if error != OK:
# The request couldn't start, so end the span and clean up immediately.
span.set_status(SentrySpan.SPAN_STATUS_ERROR)
span.set_attribute("error.message", error_string(error))
span.end()
request.queue_free()
return

# Keep the span open until the request completes or fails.
var response: Array = await request.request_completed
var result: int = response[0]
var status_code: int = response[1]
# Record the HTTP status and check for both network and HTTP errors.
span.set_attribute("http.response.status_code", status_code)
if result == HTTPRequest.RESULT_SUCCESS and status_code < 400:
span.set_status(SentrySpan.SPAN_STATUS_OK)
else:
span.set_status(SentrySpan.SPAN_STATUS_ERROR)
# Finish measuring the request and remove the temporary request node.
span.end()
request.queue_free()
```

The span is <PlatformLink to="/tracing/instrumentation/#start-an-inactive-span">inactive</PlatformLink>, so telemetry captured while it runs isn't associated with it. Its trace headers still connect the backend operation to the span.

Read the headers before ending the span and from the thread that created it. An ended span or a call from another thread returns an empty array and reports an error.

## Start a New Trace

Start a separate trace when one piece of work ends and unrelated work begins. For example, call `SentrySDK.start_new_trace()` before each match so its spans and events are grouped separately from earlier matches:

```GDScript
func prepare_match(match_id: String) -> void:
SentrySDK.start_new_trace()
SentrySDK.with_span("prepare_match", func(span: SentrySpan) -> void:
span.set_attribute("match.id", match_id)
_load_arena()
_spawn_players()
)
```

Existing spans keep the trace they started on, as does telemetry captured while they are active. End the previous operation's spans before starting a new trace if you want subsequent work to use only the new trace.

## Verify

Run the request with a sample rate of `1.0`. Inspect the outgoing headers using your backend's request logging or, for Web exports, the browser's network tools. Confirm that `sentry-trace` and `baggage` reach the backend, along with `traceparent` if enabled.

Then check Sentry for the game span and backend operation in the same trace. Headers alone confirm that the game sent the context; the connected trace confirms that the backend continued it. If a Web request is blocked, check <PlatformLink to="/tracing/distributed-tracing/dealing-with-cors-issues/">CORS configuration</PlatformLink>.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: Dealing with CORS Issues
description: "Learn how to allow Sentry trace headers on requests from Godot Web exports to your backend."
sidebar_order: 80
---

If your Web game calls a backend on another origin, adding tracing headers can cause the browser to block the request unless the backend allows them. For example, a game at `https://game.example.com` calling `https://api.example.com` needs the backend's permission to make that cross-origin request.

## Allow Trace Headers on Your Backend

Configure your backend's CORS headers to allow `sentry-trace` and `baggage`:

```http
Access-Control-Allow-Headers: sentry-trace, baggage
```

The exact server configuration depends on your setup.

If you enable <PlatformLink to="/configuration/options/#propagate_traceparent">`propagate_traceparent`</PlatformLink>, also allow that header:

```http
Access-Control-Allow-Headers: sentry-trace, baggage, traceparent
```

## Check the SDK Targets Too

If you've restricted <PlatformLink to="/tracing/distributed-tracing/limiting-trace-propagation/">trace propagation targets</PlatformLink>, make sure they include your backend URL so `get_trace_headers(url)` returns tracing headers for it.
43 changes: 43 additions & 0 deletions docs/platforms/godot/tracing/distributed-tracing/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: Set Up Distributed Tracing
description: "Learn how to connect operations in your Godot game with requests to your backend services."
sidebar_order: 30
---

<AvailableSince version="2.2.0" />

Distributed tracing connects work in your game with work in your backend. For example, a trace can show how much time a leaderboard request spends in the game, your API, and its database.

## Connect Your Game and Backend

The Godot SDK provides trace headers that you attach to outgoing requests manually. It doesn't instrument HTTP requests automatically.

1. <PlatformLink to="/tracing/">Enable tracing</PlatformLink> in your game.
2. Set up the [Sentry SDK](/platforms/) for your backend and enable its distributed tracing support.
3. Follow <PlatformLink to="/tracing/distributed-tracing/custom-trace-propagation/">Custom Trace Propagation</PlatformLink> to attach headers from a span to your request.

The receiving service uses these headers to continue the same trace:

- `sentry-trace` identifies the trace, the sending span, and its sampling decision.
- `baggage` carries additional trace metadata, such as the sample rate and organization ID.
- `traceparent` provides the W3C trace context when you enable <PlatformLink to="/configuration/options/#propagate_traceparent">`propagate_traceparent`</PlatformLink>.

Restrict headers to your own services with <PlatformLink to="/tracing/distributed-tracing/limiting-trace-propagation/">Limiting Trace Propagation</PlatformLink>. For Web exports, also configure your backend to <PlatformLink to="/tracing/distributed-tracing/dealing-with-cors-issues/">allow the headers through CORS</PlatformLink>.

Make sure any proxies, gateways, or firewalls between your game and backend preserve the tracing headers.

## Trace Duration

The SDK starts a trace when it initializes. Spans and events share that trace until you start a new one. Ending a span finishes only that operation; it doesn't start a new trace.

To separate unrelated work, such as game matches, <PlatformLink to="/tracing/distributed-tracing/custom-trace-propagation/#start-a-new-trace">start a new trace</PlatformLink> before starting the next operation.

## How Sampling Propagates

The outgoing `sentry-trace` header carries the span's sampling decision so downstream services can honor it. With <PlatformLink to="/configuration/options/#traces_sample_rate">`traces_sample_rate`</PlatformLink> set to its default of `0.0`, the SDK still provides trace headers, but the span isn't sent and the headers mark the trace as unsampled.

Use a sample rate of `1.0` in your game and backend while verifying the connection, then adjust it for production.

## Next Steps

<PageGrid />
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
title: Limiting Trace Propagation
description: "Learn how to restrict outgoing trace headers to trusted backend services in your Godot game."
sidebar_order: 100
---

By default, the SDK returns tracing headers for any destination URL. To restrict propagation to specific services, configure <PlatformLink to="/configuration/options/#trace_propagation_targets">`trace_propagation_targets`</PlatformLink>:

```GDScript {filename:ProjectMainLoop.gd}
class_name ProjectMainLoop
extends SceneTree

func _initialize() -> void:
SentrySDK.init(func(options: SentryOptions) -> void:
options.trace_propagation_targets = [
RegEx.create_from_string("^https://api\\.example\\.com/"),
]
)
```

This matches URLs such as `https://api.example.com/scores`. See <PlatformLink to="/configuration/options/#programmatic-configuration">Programmatic Configuration</PlatformLink> for the manual initialization setup.

Pass the destination URL to `get_trace_headers(url)` to apply these targets. Unmatched URLs receive no tracing headers; an empty target list blocks all URLs. Calling `get_trace_headers()` without a URL bypasses filtering. You still need to <PlatformLink to="/tracing/distributed-tracing/custom-trace-propagation/">attach the returned headers to your request</PlatformLink>.

The <PlatformLink to="/configuration/options/#trace_propagation_targets">option reference</PlatformLink> explains string and regular expression matching and configuration through Project Settings.
4 changes: 4 additions & 0 deletions docs/platforms/godot/tracing/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ Web exports can also stream completed spans instead of holding them until the ro

Create and end a span around a known operation, then run the game and confirm that the trace appears in Sentry. The SDK for Godot Engine doesn't create spans automatically yet, so continue with <PlatformLink to="/tracing/instrumentation/">Instrumentation</PlatformLink> to add one.

## Distributed Tracing

To follow a request from your game into your backend, <PlatformLink to="/tracing/distributed-tracing/">set up distributed tracing</PlatformLink> and attach the span's trace headers to the request.

## Next Steps

<PageGrid />
6 changes: 6 additions & 0 deletions docs/platforms/godot/tracing/instrumentation/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ child_span.end()

Pass `null` as `parent_span` to force a new root span. Call `SentrySDK.get_active_span()` when lower-level code needs to read the span attached to the current scope.

Starting a span doesn't start a new trace. To start a separate trace—for example, for a new match—call `SentrySDK.start_new_trace()`. See <PlatformLink to="/tracing/distributed-tracing/custom-trace-propagation/#start-a-new-trace">Start a New Trace</PlatformLink>.

## Start an Inactive Span

Use an inactive span when work should be grouped under a parent but remain independent of the currently active span. Because it doesn't become active, it doesn't affect `SentrySDK.get_active_span()`, make new spans its children automatically, or add its trace context to telemetry captured alongside it.
Expand Down Expand Up @@ -179,3 +181,7 @@ A span without an explicit status is treated as successful.
## Spans and Threads

Spans belong to the thread that created them. Call their methods only from that thread. If work moves to another thread, start and end its spans inside that threaded function instead of passing a span across threads.

## Distributed Tracing

To connect a span with work in a backend service, <PlatformLink to="/tracing/distributed-tracing/custom-trace-propagation/">attach its trace headers to the outgoing request</PlatformLink>.
Loading