Skip to content
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

Propagated Sampling Rates #11912

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft

Propagated Sampling Rates #11912

wants to merge 2 commits into from

Conversation

cleptric
Copy link
Member

No description provided.

Copy link

vercel bot commented Nov 22, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
develop-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 22, 2024 8:22am
2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
changelog ⬜️ Ignored (Inspect) Visit Preview Nov 22, 2024 8:22am
sentry-docs ⬜️ Ignored (Inspect) Visit Preview Nov 22, 2024 8:22am

@@ -65,6 +65,21 @@ This Option replaces the non-standardized `tracingOrigins` option which was prev

</Alert>

### `strictTracePropagation`

This option disables trace continuation from unknown 3rd party services that happen to be instrumented by a Sentry SDK.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This option disables trace continuation from unknown 3rd party services that happen to be instrumented by a Sentry SDK.
This should be a boolean value. Default is `false`. This option controls trace continuation from unknown 3rd party services that happen to be instrumented by a Sentry SDK.


This option disables trace continuation from unknown 3rd party services that happen to be instrumented by a Sentry SDK.

If the SDK can parse an org ID from the configured DSN, this value must be propagated as a baggage entry with the key `sentry-org`. Given a DSN of `https://[email protected]/1`, the org ID is `1`, based on `o1`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If the SDK can parse an org ID from the configured DSN, this value must be propagated as a baggage entry with the key `sentry-org`. Given a DSN of `https://[email protected]/1`, the org ID is `1`, based on `o1`.
If the SDK can parse an org ID from the configured DSN, it must be propagated as a baggage entry with the key `sentry-org`. Given a DSN of `https://[email protected]/1`, the org ID is `1`, based on `o1`.

If the SDK can parse an org ID from the configured DSN, this value must be propagated as a baggage entry with the key `sentry-org`. Given a DSN of `https://[email protected]/1`, the org ID is `1`, based on `o1`.

On incoming traces, the SDK must compare the `sentry-org` baggage value against its own parsed value from the DSN. Only if both match, the trace is continued. If there is no match, neither the trace ID, the parent sampling decision nor the baggage should be taken into account.
The SDK should behave like it is the head of trace in this case.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence I do not understand. Can you please reword this?


This behavior can be disabled by setting `strictTracePropagation: false` in the SDK init call.
Initially, SDKs should introduce the this option with a default values of `false`.
Once the majority of SDKs introduced this option, we will make it opt-out in a major version.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Once the majority of SDKs introduced this option, we will make it opt-out in a major version.
Once the majority of SDKs introduced this option, we will change the default value to `true` (in a major version bump) making it opt-out.

@@ -185,6 +201,35 @@ Depending on the platform, other default data may be included. (For example, for

A transaction's sampling decision should be passed to all of its children, including across service boundaries. This can be accomplished in the `startChild` method for same-service children and using the `senry-trace` header for children in a different service.

### Propagated Sampling Rates

To increase the chance of capturing complete traces when users return a new sample rate from the `tracesSampler` in backend services, we propagate the generated random value used by the SDK for computing the sampling decision instead of creating a new random value in every service. Therefore, across a trace every SDK uses the same random value.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To increase the chance of capturing complete traces when users return a new sample rate from the `tracesSampler` in backend services, we propagate the generated random value used by the SDK for computing the sampling decision instead of creating a new random value in every service. Therefore, across a trace every SDK uses the same random value.
To increase the chance of capturing complete traces when users return a new sample rate from the `tracesSampler` in backend services, we propagate the generated random value used by the SDK for making the sampling decision instead of creating a new random value in every service. Therefore, across a trace every SDK uses the same random value.


The behavior of the static `tracesSampleRate` without the use of `tracesSampler` does not change. We continue to fully inherit sampling decisions for propagated traces and create a new one for started traces. In the future, we might change the default behavior of `tracesSampleRate`, too.

Once the SDK starts a new trace, `sentry-sample_rand` is filled with a truly random number. This also applies when the `tracesSampleRate` is set to `1.0`. If the SDK receives an incoming trace, containing a `sentry-sample_rand` entry in the baggage, this value should overwrite the currently stored number. For incoming traces without a `sentry-sample_rand` baggage entry (from old SDKs), the SDK inserts a new truly random number on-the-fly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Once the SDK starts a new trace, `sentry-sample_rand` is filled with a truly random number. This also applies when the `tracesSampleRate` is set to `1.0`. If the SDK receives an incoming trace, containing a `sentry-sample_rand` entry in the baggage, this value should overwrite the currently stored number. For incoming traces without a `sentry-sample_rand` baggage entry (from old SDKs), the SDK inserts a new truly random number on-the-fly.
When a new trace is started by the SDK, `sentry-sample_rand` is filled with a truly random number. This also applies when the `tracesSampleRate` is set to `1.0`. If the SDK receives an incoming trace, containing a `sentry-sample_rand` entry in the baggage, this value should overwrite the currently stored number. For incoming traces without a `sentry-sample_rand` baggage entry (from old SDKs), the SDK inserts a new truly random number on-the-fly.

- When the `tracesSampler` is invoked, this also applies to the return value of traces sampler. i.e. `trace["sentry-sample_rand"] < tracesSampler(context)`
- Otherwise, when the SDK is the head of a trace, this applies to sample decisions based on `tracesSampleRate` , i.e. `trace["sentry-sample_rand"] < config.tracesSampleRate`

When using a `tracesSampler`, the most correct way to inherit parent sampling decisions is now to return the parent's sample rate instead of the decision as float (1.0). This way, we can still extrapolate counts correctly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When using a `tracesSampler`, the most correct way to inherit parent sampling decisions is now to return the parent's sample rate instead of the decision as float (1.0). This way, we can still extrapolate counts correctly.
When using a `tracesSampler`, the correct way to inherit parent sampling decisions is now to return the parent's sample rate instead of the decision as float (1.0). This way, we can still extrapolate counts correctly.

@@ -60,6 +61,8 @@ The rest of the context attributes, `trace_id`, `public_key`, and `sample_rate`,
| `release` | string | The release name as specified in client options. | `[email protected]`, `1.2.3`, `2025.4.107` | required |
| `environment` | string | The environment name as specified in client options. | `production`, `staging` | required |
| `transaction` | string | The transaction name set on the scope. **Only include** if name has [good quality](#note-on-good-quality-transaction-names). | `/login`, `myApp.myController.login` | required (if known and good quality) |
| `org` | string | The org ID parsed from the DSN or received by a downstream SDK. | `1` | required |
| `sample_rand` | string | A trully random number originating from the head of trace SDK. | `0.5` | required |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `sample_rand` | string | A trully random number originating from the head of trace SDK. | `0.5` | required |
| `sample_rand` | string | A truly random number originating from the head of trace SDK. | `0.5` | required |

@@ -60,6 +61,8 @@ The rest of the context attributes, `trace_id`, `public_key`, and `sample_rate`,
| `release` | string | The release name as specified in client options. | `[email protected]`, `1.2.3`, `2025.4.107` | required |
| `environment` | string | The environment name as specified in client options. | `production`, `staging` | required |
| `transaction` | string | The transaction name set on the scope. **Only include** if name has [good quality](#note-on-good-quality-transaction-names). | `/login`, `myApp.myController.login` | required (if known and good quality) |
| `org` | string | The org ID parsed from the DSN or received by a downstream SDK. | `1` | required |
| `sample_rand` | string | A trully random number originating from the head of trace SDK. | `0.5` | required |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it have to be a true random number? (I guess not all systems can create a true random number)

The SDK should behave like it is the head of trace in this case.

This behavior can be disabled by setting `strictTracePropagation: false` in the SDK init call.
Initially, SDKs should introduce the this option with a default values of `false`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Initially, SDKs should introduce the this option with a default values of `false`.
Initially, SDKs should introduce the this option with a default value of `false`.

Initially, SDKs should introduce the this option with a default values of `false`.
Once the majority of SDKs introduced this option, we will make it opt-out in a major version.

The SDK must be configurable with an optional `org: <org-id>` setting that takes precedence over the parsed value from the DSN. This option should be set when running a self-hosted version of Sentry or if a none standard Sentry DSN is used, such as when using a local Relay.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The SDK must be configurable with an optional `org: <org-id>` setting that takes precedence over the parsed value from the DSN. This option should be set when running a self-hosted version of Sentry or if a none standard Sentry DSN is used, such as when using a local Relay.
The SDK must be configurable with an optional `org: <org-id>` setting that takes precedence over the parsed value from the DSN. This option should be set when running a self-hosted version of Sentry or if a non-standard Sentry DSN is used, such as when using a local Relay.

@@ -49,7 +49,8 @@ To align DSC propagation over all our SDKs, we defined a [unified propagation me
All of the attributes in the table below are required (non-optional) in a sense, that when they are known to an SDK at the time an envelope with an event (transaction or error) is sent to Sentry, or at the time a baggage header is propagated, they must also be included in said envelope or baggage.

At the moment, only `release`, `environment` and `transaction` are used by the product for dynamic sampling functionality.
The rest of the context attributes, `trace_id`, `public_key`, and `sample_rate`, are used by Relay for internal decisions (like transaction sample rate smoothing).
The rest of the context attributes, `trace_id`, `public_key`, `sampled` and `sample_rate`, are used by Relay for internal decisions (like transaction sample rate smoothing).
Additional entries such as `replay_id`, `org` and `sample_rand` are only using the DSC as a mean of transport.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Additional entries such as `replay_id`, `org` and `sample_rand` are only using the DSC as a mean of transport.
Additional entries such as `replay_id`, `org` and `sample_rand` are only using the DSC as a means of transport.


The behavior of the static `tracesSampleRate` without the use of `tracesSampler` does not change. We continue to fully inherit sampling decisions for propagated traces and create a new one for started traces. In the future, we might change the default behavior of `tracesSampleRate`, too.

Once the SDK starts a new trace, `sentry-sample_rand` is filled with a truly random number. This also applies when the `tracesSampleRate` is set to `1.0`. If the SDK receives an incoming trace, containing a `sentry-sample_rand` entry in the baggage, this value should overwrite the currently stored number. For incoming traces without a `sentry-sample_rand` baggage entry (from old SDKs), the SDK inserts a new truly random number on-the-fly.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Once the SDK starts a new trace, `sentry-sample_rand` is filled with a truly random number. This also applies when the `tracesSampleRate` is set to `1.0`. If the SDK receives an incoming trace, containing a `sentry-sample_rand` entry in the baggage, this value should overwrite the currently stored number. For incoming traces without a `sentry-sample_rand` baggage entry (from old SDKs), the SDK inserts a new truly random number on-the-fly.
Once the SDK starts a new trace, `sentry-sample_rand` is filled with a truly random number. This also applies when the `tracesSampleRate` is set to `1.0`. If the SDK receives an incoming trace, containing a `sentry-sample_rand` entry in the baggage, this value should overwrite the currently stored number. For incoming traces without a `sentry-sample_rand` baggage entry (from old SDKs), the SDK inserts a new truly random number on the fly.


### `tracesSampler`

This should be a callback, called when a transaction is started, which will be given a `samplingContext` object and which should return a sample rate between `0.0` and `1.0` _for the transaction in question_. This sample rate should behave the same way as the `tracesSampleRate` above, with the difference that it only applies to the newly-created transaction, such that different transactions can be sampled at different rates. Returning `0.0` should force the transaction to be dropped (set to `sampled = false`) and returning `1.0` should force the transaction to be sent (set `sampled = true`).

Optionally, the `tracesSampler` callback can also return a boolean to force a sampling decision (with `false` equivalent to `0.0` and `true` equivalent to `1.0`). If returning two different datatypes isn't an option in the implementing language, this possibility can safely be omitted.
Historically, the `tracesSampler` callback could have also returned a boolean to force a sampling decision (with `false` equivalent to `0.0` and `true` equivalent to `1.0`). This behavior is now **deprecated** and should be removed from all SDKs.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why deprecate this and not just keep treating true as 1.0 and false as 0.0?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants