Skip to content

Commit d3f0615

Browse files
committed
docs(sdks): Span Sampling
1 parent babc777 commit d3f0615

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: Spans
3+
sidebar_order: 8
4+
---
5+
6+
<PageGrid />
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---
2+
title: Span Sampling & Filtering
3+
---
4+
<Alert level="info">
5+
This document uses key words such as "MUST", "SHOULD", and "MAY" as defined in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) to indicate requirement levels.
6+
</Alert>
7+
8+
Any APIs exposed to the user to sample or filter spans must adhere to the following design principles:
9+
10+
- The APIs are optimized for trace completeness
11+
- The APIs are optimized for conclusive sampling decisions
12+
13+
## Sample root spans with `tracesSampleRate` & `tracesSampler`
14+
15+
The SDK is automatically initialized with a `tracesSampleRate` of `0`.
16+
When starting a root span, the configured rate is compared against a random number between 0 and 1 to decide if this root span will be sampled or not.
17+
18+
If the SDK is configured with a `tracesSampler`, the `tracesSampleRate` no longer applies.
19+
The `tracesSampler` callback must receive sufficient arguments from users to define their own sampling rules.
20+
This can include but is not limited to certain attributes from the root span, such as HTTP headers.
21+
The return value of the `tracesSampler` is a float between `0.0` and `1.0`.
22+
23+
```js
24+
Sentry.init({
25+
tracesSampler: ({ name, attributes, parentSampleRate }) => {
26+
// Inherit the trace parent's sample rate if there is one. Sampling is deterministic
27+
// for one trace, e.g. if the parent was sampled, all children will be sampled at the same rate.
28+
if (typeof parentSampleRate === "number") {
29+
return parentSampleRate;
30+
}
31+
32+
// Else, use a default sample rate (replacing tracesSampleRate).
33+
return 0.5;
34+
}
35+
})
36+
```
37+
38+
The `parentSampleRate` is a propagated value inside the baggage, using key `sentry-sample_rand`.
39+
The value stems from a truly random number between 0 and 1, generated when a new trace is started. If the SDK does not receive such a number in an incoming trace, a new, truly random number between 0 and 1 is generated.
40+
41+
In the following cases, the SDK must compare sample rates against this `parentSampleRate` instead of `math.random()`:
42+
43+
- When a `tracesSampler` is configured, i.e. `trace["sentry-sample_rand"] < tracesSampler()`
44+
45+
- When the SDK is the head of trace, this applies to sample decisions based on `tracesSampleRate`, e.g. `trace['sentry-sample_rand'] < config.tracesSampleRate`
46+
47+
If the `sentry-sample_rate` (`parentSampleRate`) is not available for any reason for an inbound trace, but the trace has the sampled flag set to true, the SDK injects `parentSampleRate: 1.0` into the `tracesSampler`.
48+
49+
If no `tracesSampler` is configured, a propagated sampling decision via the traceparent takes precedence over the `tracesSampleRate`. This behavior can be disabled by defining a `tracesSampler`.
50+
51+
## Parent Sampling Origins
52+
53+
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`.
54+
55+
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 parent sampling decisions applies.
56+
57+
This behavior can be disabled by setting `strictTracePropagation: false` in the SDK init call.
58+
59+
The SDK must be configurable with an optional `org: <org-id>` setting that takes precedence over the parsed value from the DSN.
60+
61+
## Filter spans with `ignoreSpans` & integration config
62+
63+
The SDK must implement a mechanism for users to filter out spans. The result must be binary (true/false).
64+
The `ignoreSpans` option accepts a glob pattern or string.
65+
The `integrations` option can perform in similar fashion or make explicit opt-out possible via a bool flag.
66+
67+
If both options are not feasible to be implemented in certain SDKs, other approaches must be explored that have the same outcome.
68+
69+
```js
70+
Sentry.init({
71+
ignoreSpans: [
72+
'GET /about',
73+
'events.signal *',
74+
],
75+
integrations: [
76+
fsIntegration: {
77+
ignoreSpans: [
78+
'fs.read',
79+
],
80+
readSpans: true,
81+
writeSpans: false,
82+
}
83+
]
84+
})
85+
```
86+
87+
## Sanitize span attributes with `beforeSendSpans`
88+
89+
This callback must not allow the removal of any spans from the span tree.
90+
It receives a deep copy of all spans in the span tree and their attributes.
91+
92+
```
93+
[
94+
{
95+
'name': 'GET /',
96+
'attributes': [
97+
'http.request.method': 'GET',
98+
'http.response.status_code': 200,
99+
]
100+
},
101+
]
102+
```
103+
104+
Users can mutate any exposed properties to perform sanitation on sensitive data or Pii.
105+
The return value `beforeSendSpans` should be merged with the original span tree prior to emission.

0 commit comments

Comments
 (0)