Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ sidebar_order: 30

Sentry's tracing functionality helps you monitor application performance by capturing distributed traces, attaching attributes, and span performance across your application. However, Capturing traces for every transaction can generate significant volumes of data. Sampling allows you to control the amount of spans that are sent to Sentry from your application.

<PlatformSection notSupported={["javascript.cordova"]}>
<Alert>

If you're using stream mode, sampling works the same way as described in this guide but applies to service spans instead of transactions. See <PlatformLink to="/tracing/new-spans/">New Spans</PlatformLink> for more information.

</Alert>
</PlatformSection>

The JavaScript SDK provides two main options for controlling the sampling rate:

1. [Uniform Sample Rate](#uniform-sample-rate-tracessamplerate) (recommended)
Expand Down Expand Up @@ -62,39 +70,39 @@ tracesSampler: (samplingContext) => {
const { name, attributes, inheritOrSampleWith } = samplingContext;

// Sample all checkout transactions
if (name.includes('/checkout') || attributes?.flow === 'checkout') {
if (name.includes("/checkout") || attributes?.flow === "checkout") {
return 1.0;
}

// Sample 50% of login transactions
if (name.includes('/login') || attributes?.flow === 'login') {
if (name.includes("/login") || attributes?.flow === "login") {
return 0.5;
}

// Sample 10% of everything else
return inheritOrSampleWith(0.1);
}
};
```

2. Handling Different Environments

```javascript
tracesSampler: (samplingContext) => {
const { inheritOrSampleWith } = samplingContext;
const { inheritOrSampleWith } = samplingContext;

// Sample all transactions in development
if (process.env.NODE_ENV === 'development') {
if (process.env.NODE_ENV === "development") {
return 1.0;
}

// Sample 5% in production
if (process.env.NODE_ENV === 'production') {
if (process.env.NODE_ENV === "production") {
return 0.05;
}

// Sample 20% in staging
return inheritOrSampleWith(0.2);
}
};
```

3. Controlling Sampling Based on User or Transaction Properties
Expand All @@ -104,7 +112,7 @@ tracesSampler: (samplingContext) => {
const { attributes, inheritOrSampleWith } = samplingContext;

// Always sample for premium users
if (attributes?.userTier === 'premium') {
if (attributes?.userTier === "premium") {
return 1.0;
}

Expand All @@ -114,13 +122,13 @@ tracesSampler: (samplingContext) => {
}

// Sample less for high-volume, low-value paths
if (attributes?.path?.includes('/api/metrics')) {
if (attributes?.path?.includes("/api/metrics")) {
return 0.01;
}

// Default sampling rate
return inheritOrSampleWith(0.2);
}
};
```

## Sampling Decision Precedence
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,23 @@ Capturing spans requires that you first <PlatformLink to="/tracing/">set up trac

<PlatformContent includePath="performance/automatic-instrumentation-intro" />

<Alert>

If you're using stream mode, sampling works the same way as described in this guide but applies to service spans instead of transactions. See <PlatformLink to="/tracing/new-spans/">New Spans</PlatformLink> for more information.

</Alert>

## What's Captured Automatically

Once you enable tracing, the SDK automatically captures performance data without additional code:

| What | Description | Metrics |
|------|-------------|---------|
| **Page loads** | Full page load performance | LCP, CLS, TTFB |
| **Navigations** | Client-side route changes | Duration, Web Vitals |
| **HTTP requests** | All fetch/XHR calls | Duration, status, URL |
| **User interactions** | Clicks, inputs that trigger work | INP (responsiveness) |
| **Long tasks** | Main thread blocking > 50ms | Duration, attribution |
| What | Description | Metrics |
| --------------------- | -------------------------------- | --------------------- |
| **Page loads** | Full page load performance | LCP, CLS, TTFB |
| **Navigations** | Client-side route changes | Duration, Web Vitals |
| **HTTP requests** | All fetch/XHR calls | Duration, status, URL |
| **User interactions** | Clicks, inputs that trigger work | INP (responsiveness) |
| **Long tasks** | Main thread blocking > 50ms | Duration, attribution |

<PlatformContent includePath="performance/what-instrumentation-provides" />

Expand Down Expand Up @@ -236,7 +242,7 @@ Ignore specific resource span categories by their `op` (e.g., `resource.script`,
Sentry.init({
integrations: [
Sentry.browserTracingIntegration({
ignoreResourceSpans: ['resource.css', 'resource.script'],
ignoreResourceSpans: ["resource.css", "resource.script"],
}),
],
});
Expand All @@ -252,7 +258,7 @@ Ignore spans created from `performance.mark()` and `performance.measure()`:
Sentry.init({
integrations: [
Sentry.browserTracingIntegration({
ignorePerformanceApiSpans: ['myMeasurement', /myMark/],
ignorePerformanceApiSpans: ["myMeasurement", /myMark/],
}),
],
});
Expand Down Expand Up @@ -285,7 +291,11 @@ Sentry.init({
}),
],
tracesSampleRate: 1.0,
tracePropagationTargets: ["localhost", /^\//, /^https:\/\/yourserver\.io\/api/],
tracePropagationTargets: [
"localhost",
/^\//,
/^https:\/\/yourserver\.io\/api/,
],
});
```

Expand Down
78 changes: 46 additions & 32 deletions docs/platforms/javascript/common/tracing/instrumentation/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ This will revert to use the full hierarchy behavior, where spans are children of

The following options can be used for all span starting functions:

| Option | Type | Description |
| ------------------ | --------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `name` | `string` | The name of the span. |
| `op` | `string` | The operation of the span. |
| `startTime` | `number` | The start time of the span. |
| `attributes` | `Record<string, Primitive>` | Attributes to attach to the span. |
| `parentSpan` | `Span` | If set, make the span a child of the specified span. Otherwise, the span will be a child of the currently active span. |
| `onlyIfParent` | `boolean` | If true, ignore the span if there is no active parent span. |
| `forceTransaction` | `boolean` | If true, ensure this span shows up as transaction in the Sentry UI. |
| Option | Type | Description |
| ------------------ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name` | `string` | The name of the span. |
| `op` | `string` | The operation of the span. |
| `startTime` | `number` | The start time of the span. |
| `attributes` | `Record<string, Primitive>` | Attributes to attach to the span. |
| `parentSpan` | `Span` | If set, make the span a child of the specified span. Otherwise, the span will be a child of the currently active span. |
| `onlyIfParent` | `boolean` | If true, ignore the span if there is no active parent span. |
| `forceTransaction` | `boolean` | If true, ensure this span shows up as transaction in the Sentry UI. Not available in <PlatformLink to="/tracing/new-spans/">stream mode</PlatformLink>. Use `parentSpan: null` instead to ensure this span shows up as service span. |

Only `name` is required, all other options are optional.

Expand All @@ -102,41 +102,40 @@ Sometimes, you do not want the span to be ended automatically when the callback

To add spans that aren't active, you can create independent spans. This is useful when you have work that is grouped together under a single parent span, but is independent from the currently active span. However, in most cases you'll want to create and use the [startSpan](#starting-an-active-span-startspan) API from above.


<PlatformContent includePath="performance/start-inactive-span" />

<PlatformCategorySection supported={['browser']}>

### Setting an inactive span active (browser only)
### Setting an inactive span active (browser only)

<AvailableSince version="10.15.0" />
<AvailableSince version="10.15.0" />

In browser environments, you might run into use cases, where the callback-based span APIs are not sufficient.
In such cases (see example below), you can use `startInactiveSpan` to start an initially inactive span and then
set it active until you manually end the span.
In browser environments, you might run into use cases, where the callback-based span APIs are not sufficient.
In such cases (see example below), you can use `startInactiveSpan` to start an initially inactive span and then
set it active until you manually end the span.

```javascript
let checkoutSpan;
```javascript
let checkoutSpan;

on('startCheckout', () => {
checkoutSpan = Sentry.startInactiveSpan({name: 'checkout-flow'});
Sentry.setActiveSpanInBrowser(checkoutSpan);
})
on("startCheckout", () => {
checkoutSpan = Sentry.startInactiveSpan({ name: "checkout-flow" });
Sentry.setActiveSpanInBrowser(checkoutSpan);
});

doSomeWork();
doSomeWork();

on('endCheckout', () => {
// Ending the span automatically removes it as the active span
checkoutSpan.end();
})
```
on("endCheckout", () => {
// Ending the span automatically removes it as the active span
checkoutSpan.end();
});
```

Using `startInactiveSpan` in combination with `setActiveSpanInBrowser` allows you to create an inactive span that can be made active until you manually end it. In contrast, [`startSpanManual`](#starting-an-active-span-with-manual-end-startspanmanual) allows you to end the span manually at any point, but it only remains active within the callback.
Using `startInactiveSpan` in combination with `setActiveSpanInBrowser` allows you to create an inactive span that can be made active until you manually end it. In contrast, [`startSpanManual`](#starting-an-active-span-with-manual-end-startspanmanual) allows you to end the span manually at any point, but it only remains active within the callback.

<Alert>

Note that `setActiveSpanInBrowser` is only available in browser environments! If you're running code in the server
(for example for server-side rendering), make sure to guard this call to only run in the browser.
Note that `setActiveSpanInBrowser` is only available in browser environments! If you're running code in the server
(for example for server-side rendering), make sure to guard this call to only run in the browser.

</Alert>

Expand Down Expand Up @@ -205,9 +204,10 @@ if (span) {

### Adding attributes to all spans

To add an attribute to all spans, use the `beforeSendSpan` callback:
To add an attribute to all spans, use the `beforeSendSpan` callback.
Note that the property names differ between transaction mode (the default) and <PlatformLink to="/tracing/new-spans/">stream mode</PlatformLink>:

```javascript
```javascript {tabTitle:Transaction Mode (Default)}
Sentry.init({
// dsn, ...
beforeSendSpan(span) {
Expand All @@ -221,6 +221,20 @@ Sentry.init({
});
```

```javascript {tabTitle:Stream Mode}
Sentry.init({
// dsn, ...
beforeSendSpan(span) {
span.attributes = {
...span.attributes,
"environment.region": "us-west-2",
};

return span;
},
});
```

### Adding Span Operations ("op")

Spans can have an operation associated with them, which help Sentry identify additional context about the span. For example, database related spans have the `db` span operation associated with them. The Sentry product offers additional controls, visualizations, and filters for spans with known operations.
Expand Down
19 changes: 17 additions & 2 deletions docs/platforms/javascript/common/tracing/span-metrics/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ For detailed examples of how to implement span metrics in common scenarios, see

## Adding Metrics to All Spans

To consistently add metrics across all spans in your application, you can use the `beforeSendSpan` callback:
To consistently add metrics across all spans in your application, you can use the `beforeSendSpan` callback.
Note that the property names differ between transaction mode (the default) and <PlatformLink to="/tracing/new-spans/">stream mode</PlatformLink>:

```javascript
```javascript {tabTitle:Transaction Mode (Default)}
Sentry.init({
beforeSendSpan(span) {
span.data = {
Expand All @@ -86,6 +87,20 @@ Sentry.init({
});
```

```javascript {tabTitle:Stream Mode}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm liking these additions!

Sentry.init({
beforeSendSpan(span) {
span.attributes = {
...span.attributes,
"app.version": "1.2.3",
"environment.region": "us-west-2",
};

return span;
},
});
```

For detailed examples of how to implement span metrics in common scenarios, see our <PlatformLink to="/tracing/span-metrics/examples/">Span Metrics Examples</PlatformLink> guide.

## Span Metrics vs. Measurements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: "Learn how to troubleshoot your tracing setup."
sidebar_order: 9000
---

If you need help managing transactions, you can read more here. If you need additional help, you can ask on GitHub. Customers on a paid plan may also contact support.
If you need help managing transactions or spans, start with this page. If you need additional help, you can ask on GitHub. Customers on a paid plan may also contact support.

## Group Transactions

Expand All @@ -27,3 +27,18 @@ For example, a 200+ character tag like this:
`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=1618033988749894848`

<PlatformContent includePath="performance/control-data-truncation" />

<PlatformSection notSupported={["javascript.cordova"]}>
## Traces Miss Spans, High Memory Usage, or Data Loss After Crashes

If you're hitting the 1,000-span limit, experiencing high memory usage from long-running processes, or losing span data when your process crashes, consider enabling stream mode. Stream mode sends spans to Sentry in batches as they finish rather than holding them in memory until the transaction ends.

See <PlatformLink to="/tracing/new-spans/">New Spans</PlatformLink> for more information.

## `ignoreSpans` Rules No Longer Work As Expected After Migrating to Stream Mode

In <PlatformLink to="/tracing/new-spans">stream mode</PlatformLink>, `ignoreSpans` is evaluated at span start rather than transaction end. If your current rules match on attributes that are added or updated while the span is active, they may no longer work as expected after migrating to stream mode.

If you're auto-instrumenting and don't know what the initial name of a span is when it starts, enable SDK debug logging during development by setting <PlatformLink to="/configuration/options/#debug">`debug: true`</PlatformLink> when initializing the SDK.

</PlatformSection>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Automatic Instrumentation
description: "Learn what transactions are captured after tracing is enabled."
description: "Learn what spans are captured after tracing is enabled."
---

<Include name="node-automatic-instrumentation" />
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Distributed tracing will be set up automatically if you've <PlatformLink to="/tr
<PlatformContent includePath="distributed-tracing/explanation" />
</Expandable>

When tracing is enabled, the Sentry SDK will not only create spans for pageloads and transactions but also propagate trace information to other systems. This allows you to connect multiple systems and see how they interact with each other.
When tracing is enabled, the Sentry SDK will not only create spans for pageloads but also propagate trace information to other systems. This allows you to connect multiple systems and see how they interact with each other.

By default, outgoing HTTP requests will automatically be instrumented for you. For other cases where you may want to continue traces (for example when working with websockets), you can manually extract and inject tracing information.

Expand Down Expand Up @@ -54,7 +54,7 @@ To learn more about distributed tracing, see our <PlatformLink to="/tracing/trac

If you have a server that renders your application's HTML (server-side rendering) and is also running a Sentry SDK, you can connect your backend to your backend via tracing.

To do this, have your server render HTML `<meta>` tags with the Sentry trace information. In your frontend, extract that tracing information when the page is loading and use it to create new transactions connected to that incoming backend trace.
To do this, have your server render HTML `<meta>` tags with the Sentry trace information. In your frontend, extract that tracing information when the page is loading and use it to create new transactions (or service spans if you're using <PlatformLink to="/tracing/new-spans">stream mode</PlatformLink>) connected to that incoming backend trace.

Some Sentry backend SDKs provide a built-in way to inject these `<meta>` tags into rendered HTML. For example:

Expand Down
Loading
Loading