From 65c3aa01ccda63e33d6a16e373ba207985ad2e08 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sat, 26 Sep 2020 07:39:17 -0700 Subject: [PATCH 01/13] add tracesSampler to default comment in code snippets --- .../javascript/common/install/cdn.mdx | 4 +++- .../javascript/common/performance/index.mdx | 20 ++++++++++++---- .../javascript/guides/angular/index.mdx | 4 +++- .../javascript/guides/react/index.mdx | 4 +++- .../react/integrations/react-router.mdx | 23 ++++++++++++------- src/platforms/javascript/guides/vue/index.mdx | 4 +++- .../guides/vue/integrations/components.mdx | 4 +++- src/platforms/javascript/index.mdx | 4 +++- .../node/common/performance/index.mdx | 4 +++- src/platforms/node/guides/express/index.mdx | 4 +++- src/platforms/node/guides/koa/index.mdx | 4 +++- src/platforms/node/index.mdx | 8 +++++-- src/wizard/javascript/angular.md | 2 ++ src/wizard/javascript/index.md | 2 ++ src/wizard/javascript/react.md | 2 ++ src/wizard/javascript/vue.md | 8 +++++-- src/wizard/node/express.md | 2 ++ src/wizard/node/index.md | 2 ++ 18 files changed, 79 insertions(+), 26 deletions(-) diff --git a/src/platforms/javascript/common/install/cdn.mdx b/src/platforms/javascript/common/install/cdn.mdx index 02f9507c4c5e4..db216eb12d94d 100644 --- a/src/platforms/javascript/common/install/cdn.mdx +++ b/src/platforms/javascript/common/install/cdn.mdx @@ -40,7 +40,9 @@ Sentry.init({ dsn: "___PUBLIC_DSN___", release: "my-project-name@" + process.env.npm_package_version, integrations: [new Sentry.Integrations.BrowserTracing()], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/common/performance/index.mdx b/src/platforms/javascript/common/performance/index.mdx index 35ce2c3e5d3b7..fd02eeefe0f8b 100644 --- a/src/platforms/javascript/common/performance/index.mdx +++ b/src/platforms/javascript/common/performance/index.mdx @@ -18,7 +18,9 @@ import { Integrations as TracingIntegrations } from "@sentry/tracing"; Sentry.init({ dsn: "___PUBLIC_DSN___", integrations: [new TracingIntegrations.BrowserTracing()], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` @@ -26,7 +28,9 @@ Sentry.init({ Sentry.init({ dsn: "___PUBLIC_DSN___", integrations: [new Sentry.Integrations.BrowserTracing()], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` @@ -46,7 +50,9 @@ Sentry.init({ tracingOrigins: ["localhost", "my-site-url.com"], }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` @@ -117,7 +123,9 @@ Sentry.init({ }, }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` @@ -141,7 +149,9 @@ Sentry.init({ }, }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/angular/index.mdx b/src/platforms/javascript/guides/angular/index.mdx index 26e3b58611bc4..45b09fdabe7cc 100644 --- a/src/platforms/javascript/guides/angular/index.mdx +++ b/src/platforms/javascript/guides/angular/index.mdx @@ -104,7 +104,9 @@ Sentry.init({ routingInstrumentation: Sentry.routingInstrumentation, }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/react/index.mdx b/src/platforms/javascript/guides/react/index.mdx index bb7d1c57f27c8..c1fadc7c04d16 100644 --- a/src/platforms/javascript/guides/react/index.mdx +++ b/src/platforms/javascript/guides/react/index.mdx @@ -144,7 +144,9 @@ Sentry.init({ dsn: "___PUBLIC_DSN___", release: "my-project-name@" + process.env.npm_package_version, integrations: [new Integrations.BrowserTracing()], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/react/integrations/react-router.mdx b/src/platforms/javascript/guides/react/integrations/react-router.mdx index 9e9769f0fcfa0..0993b10421948 100644 --- a/src/platforms/javascript/guides/react/integrations/react-router.mdx +++ b/src/platforms/javascript/guides/react/integrations/react-router.mdx @@ -29,14 +29,15 @@ import { Integrations } from '@sentry/tracing'; const history = createBrowserHistory(); Sentry.init({ - tracesSampleRate: 1, integrations: [ new Integrations.BrowserTracing({ // Can also use reactRouterV4Instrumentation routingInstrumentation: Sentry.reactRouterV5Instrumentation(history), }); ], - // ... + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); // ... @@ -75,12 +76,14 @@ const history = createBrowserHistory(); const routes = [{ path: '/users/:userid' }, { path: '/users' }, { path: '/' }]; Sentry.init({ - tracesSampleRate: 1, integrations: [ new Integrations.BrowserTracing({ routingInstrumentation: Sentry.reactRouterV5Instrumentation(history, routes, matchPath), }); - ] + ], + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); // In your App render: @@ -114,12 +117,14 @@ const SentryRoute = Sentry.withSentryRouting(Route); const history = createBrowserHistory(); Sentry.init({ - tracesSampleRate: 1, integrations: [ new Integrations.BrowserTracing({ routingInstrumentation: Sentry.reactRouterV5Instrumentation(history), }); - ] + ], + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); render() { @@ -156,7 +161,6 @@ const routes = ( ); Sentry.init({ - tracesSampleRate: 1, integrations: [ new Integrations.BrowserTracing({ routingInstrumentation: Sentry.reactRouterV3Instrumentation( @@ -166,7 +170,10 @@ Sentry.init({ Router.match, ), }); - ] + ], + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/vue/index.mdx b/src/platforms/javascript/guides/vue/index.mdx index ef7a5371c0e64..cbeaf5f0f4e3a 100644 --- a/src/platforms/javascript/guides/vue/index.mdx +++ b/src/platforms/javascript/guides/vue/index.mdx @@ -100,7 +100,9 @@ Sentry.init({ tracing: true, }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/vue/integrations/components.mdx b/src/platforms/javascript/guides/vue/integrations/components.mdx index 348c490486c6b..cc1fe0fd8dc80 100644 --- a/src/platforms/javascript/guides/vue/integrations/components.mdx +++ b/src/platforms/javascript/guides/vue/integrations/components.mdx @@ -34,7 +34,9 @@ Sentry.init({ tracing: true, }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/index.mdx b/src/platforms/javascript/index.mdx index af9454f25955d..a7b1547140d94 100644 --- a/src/platforms/javascript/index.mdx +++ b/src/platforms/javascript/index.mdx @@ -118,7 +118,9 @@ Sentry.init({ dsn: "___PUBLIC_DSN___", release: "my-project-name@" + process.env.npm_package_version, integrations: [new Integrations.BrowserTracing()], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/node/common/performance/index.mdx b/src/platforms/node/common/performance/index.mdx index af489e8ec4422..ffdc1d1290158 100644 --- a/src/platforms/node/common/performance/index.mdx +++ b/src/platforms/node/common/performance/index.mdx @@ -13,11 +13,13 @@ const http = require("http"); Sentry.init({ dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, integrations: [ // enable HTTP calls tracing new Sentry.Integrations.Http({ tracing: true }), ], + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); const transaction = Sentry.startTransaction({ diff --git a/src/platforms/node/guides/express/index.mdx b/src/platforms/node/guides/express/index.mdx index 261018439a787..2895108e5882b 100644 --- a/src/platforms/node/guides/express/index.mdx +++ b/src/platforms/node/guides/express/index.mdx @@ -166,7 +166,9 @@ Sentry.init({ // enable Express.js middleware tracing new Tracing.Integrations.Express({ app }), ], - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); // RequestHandler creates a separate execution context using domains, so that every diff --git a/src/platforms/node/guides/koa/index.mdx b/src/platforms/node/guides/koa/index.mdx index 315ac26f7151d..0e066e9dba2d9 100644 --- a/src/platforms/node/guides/koa/index.mdx +++ b/src/platforms/node/guides/koa/index.mdx @@ -62,7 +62,9 @@ const domain = require("domain"); Sentry.init({ dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); // not mandatory, but adding domains does help a lot with breadcrumbs diff --git a/src/platforms/node/index.mdx b/src/platforms/node/index.mdx index 7ef1acf3053e8..6276f25a322f5 100644 --- a/src/platforms/node/index.mdx +++ b/src/platforms/node/index.mdx @@ -70,7 +70,9 @@ const Tracing = require("@sentry/tracing"); Sentry.init({ dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` @@ -80,7 +82,9 @@ import * as Tracing from "@sentry/tracing"; Sentry.init({ dsn: "___PUBLIC_DSN___", - tracesSampleRate: 1.0, // Be sure to lower this in production + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/wizard/javascript/angular.md b/src/wizard/javascript/angular.md index 13bf9b6237936..515a0b25e5de9 100644 --- a/src/wizard/javascript/angular.md +++ b/src/wizard/javascript/angular.md @@ -35,6 +35,8 @@ Sentry.init({ routingInstrumentation: Sentry.routingInstrumentation, }), ], + + // Be sure to lower this in production, or use tracesSampler for finer control tracesSampleRate: 1.0, }); diff --git a/src/wizard/javascript/index.md b/src/wizard/javascript/index.md index 7ab5c1791a57f..7f41547787893 100644 --- a/src/wizard/javascript/index.md +++ b/src/wizard/javascript/index.md @@ -26,6 +26,8 @@ Sentry.init({ integrations: [ new Integrations.BrowserTracing(), ], + + // Be sure to lower this in production, or use tracesSampler for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/wizard/javascript/react.md b/src/wizard/javascript/react.md index 72af152fc05ea..d6f1c226ddd5a 100644 --- a/src/wizard/javascript/react.md +++ b/src/wizard/javascript/react.md @@ -36,6 +36,8 @@ Sentry.init({ integrations: [ new Integrations.BrowserTracing(), ], + + // Be sure to lower this in production, or use tracesSampler for finer control tracesSampleRate: 1.0, }); diff --git a/src/wizard/javascript/vue.md b/src/wizard/javascript/vue.md index abf32c6a166c9..ae8f73a32f5fe 100644 --- a/src/wizard/javascript/vue.md +++ b/src/wizard/javascript/vue.md @@ -44,7 +44,9 @@ Sentry.init({ }), new Integrations.BrowserTracing(), ], - tracesSampleRate: 1, + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` @@ -79,7 +81,9 @@ Sentry.init({ }), new Sentry.Integrations.BrowserTracing(), ], - tracesSampleRate: 1, + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, }); ``` diff --git a/src/wizard/node/express.md b/src/wizard/node/express.md index 5f0ad6c0a3cd3..fb39247db6e8a 100644 --- a/src/wizard/node/express.md +++ b/src/wizard/node/express.md @@ -37,6 +37,8 @@ Sentry.init({ // enable Express.js middleware tracing new Tracing.Integrations.Express({ app }), ], + + // Be sure to lower this in production, or use tracesSampler for finer control tracesSampleRate: 1.0, }); diff --git a/src/wizard/node/index.md b/src/wizard/node/index.md index ecd5568b08480..67905cd8df7d9 100644 --- a/src/wizard/node/index.md +++ b/src/wizard/node/index.md @@ -28,6 +28,8 @@ const Tracing = require("@sentry/tracing"); Sentry.init({ dsn: "___PUBLIC_DSN___", + + // Be sure to lower this in production, or use tracesSampler for finer control tracesSampleRate: 1.0, }); From f59376e5d0a109026885e0b08cecb44126f1f2d4 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sat, 26 Sep 2020 07:40:35 -0700 Subject: [PATCH 02/13] fix koa code snippet --- src/platforms/node/guides/koa/index.mdx | 39 ++++++++++++------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/platforms/node/guides/koa/index.mdx b/src/platforms/node/guides/koa/index.mdx index 0e066e9dba2d9..baef11188c886 100644 --- a/src/platforms/node/guides/koa/index.mdx +++ b/src/platforms/node/guides/koa/index.mdx @@ -51,11 +51,15 @@ $ npm install --save @sentry/node @sentry/tracing $ yarn add @sentry/node @sentry/tracing ``` -Creates and attaches a transaction to each context +Create and attach a transaction to each request: ```javascript const Sentry = require("@sentry/node"); -const { Span } = require("@sentry/tracing"); +const { + extractTraceparentData, + Span, + stripUrlQueryAndFragment, +} = require("@sentry/tracing"); const Koa = require("koa"); const app = new Koa(); const domain = require("domain"); @@ -91,33 +95,28 @@ const requestHandler = (ctx, next) => { // this tracing middleware creates a transaction per request const tracingMiddleWare = async (ctx, next) => { - // captures span of upstream app - const sentryTraceId = ctx.request.get("sentry-trace"); - let traceId; - let parentSpanId; - let sampled; - if (sentryTraceId) { - const span = Span.fromTraceparent(sentryTraceId); - if (span) { - traceId = span.traceId; - parentSpanId = span.parentSpanId; - sampled = span.sampled; - } + const reqMethod = (ctx.method || "").toUpperCase(); + const reqUrl = ctx.url && stripUrlQueryAndFragment(ctx.url); + + // connect to trace of upstream app + let traceparentData; + if (ctx.request.get("sentry-trace")) { + traceparentData = extractTraceparentData(ctx.request.get("sentry-trace")); } - const transaction = Sentry.startTransaction({ - name: `${ctx.method} ${ctx.url}`, + + const transaction = startTransaction({ + name: `${reqMethod} ${reqUrl}`, op: "http.server", - parentSpanId, - traceId, - sampled, + ...traceparentData, }); + ctx.__sentry_transaction = transaction; await next(); // if using koa router, a nicer way to capture transaction using the matched route if (ctx._matchedRoute) { const mountPath = ctx.mountPath || ""; - transaction.setName(`${ctx.method} ${mountPath}${ctx._matchedRoute}`); + transaction.setName(`${reqMethod} ${mountPath}${ctx._matchedRoute}`); } transaction.setHttpStatus(ctx.status); transaction.finish(); From 91013d5c134caed76a824f5bb95db4a01517afc7 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Sat, 26 Sep 2020 07:43:04 -0700 Subject: [PATCH 03/13] add tracesSampleRate and tracesSampler to config options --- src/platforms/common/configuration/options.mdx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/platforms/common/configuration/options.mdx b/src/platforms/common/configuration/options.mdx index f085c879d4b87..d62231ce23f0b 100644 --- a/src/platforms/common/configuration/options.mdx +++ b/src/platforms/common/configuration/options.mdx @@ -208,3 +208,15 @@ Controls how many seconds to wait before shutting down. Sentry SDKs send events + +## Tracing Options + + + +A number between 0 and 1, controlling the percentage chance a given transaction will be sent to Sentry. (0 represents 0% while 1 represents 100%.) Applies equally to all transactions created in the app. Either this or `tracesSampler` must be defined to enable tracing. + + + + +A function responsible for determining the percentage chance a given transaction will be sent to Sentry. It will automatically be passed information about the transaction and the context in which it's being created, and must return a number between 0 (0% chance of being sent) and 1 (100% chance of being sent). Can also be used for filtering transactions, by returning 0 for those that are unwanted. Either this or `tracesSampleRate` must be defined to enable tracing. + From 0b0685095c6a26a7335bf27e07147ecc8cbf466e Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 28 Sep 2020 11:40:19 -0700 Subject: [PATCH 04/13] move autocapture and manual capture to their own pages --- .../common/performance/automatic.mdx | 139 ++++++++++++++++++ .../javascript/common/performance/index.mdx | 137 ----------------- .../javascript/common/performance/manual.mdx | 71 +++++++++ 3 files changed, 210 insertions(+), 137 deletions(-) create mode 100644 src/platforms/javascript/common/performance/automatic.mdx create mode 100644 src/platforms/javascript/common/performance/manual.mdx diff --git a/src/platforms/javascript/common/performance/automatic.mdx b/src/platforms/javascript/common/performance/automatic.mdx new file mode 100644 index 0000000000000..623770dd102f2 --- /dev/null +++ b/src/platforms/javascript/common/performance/automatic.mdx @@ -0,0 +1,139 @@ +--- +title: Capturing Transactions Automatically +sidebar_order: 20 +description: "Learn how to configure what performance data is automatically captured." +--- + +The `@sentry/tracing` package provides a `BrowserTracing` integration to add automatic instrumentation for monitoring the performance of browser applications. By default, this integration will create a new transaction for each pageload and navigation event, and will create a child span for every `XMLHttpRequest` or `fetch` request which occurs while those transactions are open. + +To enable this automatic tracing, include the `BrowserTracing` integration in your SDK configuration options. (Note that when using ESM modules, the main `@sentry/*` import must come before the `@sentry/tracing` import.) + +```javascript {tabTitle: ESM} +// If you're using one of our integration packages, like `@sentry/react` or `@sentry/angular`, +// substitute its name for `@sentry/browser` here +import * as Sentry from "@sentry/browser"; +import { Integrations as TracingIntegrations } from "@sentry/tracing"; // Must import second + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + + integrations: [ + new Integrations.BrowserTracing({ + tracingOrigins: ["localhost", "my-site-url.com", /^\//], + // ... other options + }), + ], + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, +}); +``` + +```javascript {tabTitle: CDN} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + + integrations: [ + new Sentry.Integrations.BrowserTracing({ + tracingOrigins: ["localhost", "my-site-url.com", /^\//], + // ... other options + }), + ], + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, +}); +``` + +After configuration, you should see both `pageload` and `navigation` transactions show up in your Sentry UI. + +## Options + +You can pass many different options to the `BrowserTracing` integration (as an object of the form `{optionName: value}`), but it comes with reasonable defaults out of the box. For all possible options, see [TypeDocs](https://getsentry.github.io/sentry-javascript/interfaces/tracing.browsertracingoptions.html). + +### tracingOrigins + +Usage: + +```javascript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [ + new Integrations.BrowserTracing({ + tracingOrigins: ["localhost", "my-site-url.com"], + }), + ], + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, +}); +``` + +The default value of `tracingOrigins` is `['localhost', /^\//]`. The JavaScript SDK will attach the `sentry-trace` header to all outgoing XHR/fetch requests whose destination contains a string in the list or matches a regex in the list. If your frontend is making requests to a different domain, you will need to add it there to propagate the `sentry-trace` header to the backend services, which is required to link transactions together as part of a single trace. **One important thing to note is that the `tracingOrigins` option matches against the whole request URL, not just the domain. Using stricter regex to match certain parts of the URL can help make sure that requests do not unnecessarily have the `sentry-trace` header attached.** + +_Example:_ + +- A frontend application is served from `example.com` +- A backend service is served from `api.example.com` +- The frontend application makes API calls to the backend +- Therefore, the option needs to be configured like this: `new Integrations.BrowserTracing({tracingOrigins: ['api.example.com']})` +- Now outgoing XHR/fetch requests to `api.example.com` will get the `sentry-trace` header attached + +_NOTE:_ You need to make sure your web server CORS is configured to allow the `sentry-trace` header. The configuration might look like `"Access-Control-Allow-Headers: sentry-trace"`, but the configuration depends on your set up. If you do not allow the `sentry-trace` header, the request might be blocked. + +### beforeNavigate + +For `pageload` and `navigation` transactions, the `BrowserTracing` integration uses the browser's `window.location` API to generate a transaction name. To customize the name of the `pageload` and `navigation` transactions, you can supply a `beforeNavigate` option to the `BrowserTracing` integration. This option allows you to modify the transaction name to make it more generic, so that, for example, transactions named `GET /users/12312012` and `GET /users/11212012` can both be renamed `GET /users/:userid`, so that they'll group together. + +```javascript +import * as Sentry from "@sentry/browser"; +import { Integrations } from "@sentry/tracing"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [ + new Integrations.BrowserTracing({ + beforeNavigate: context => { + return { + ...context, + // You could use your UI's routing library to find the matching + // route template here. We don't have one right now, so do some basic + // parameter replacements. + name: location.pathname + .replace(/\d+/g, "") + .replace(/[a-f0-9]{32}/g, ""), + }; + }, + }), + ], + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, +}); +``` + +### shouldCreateSpanForRequest + +This function can be used to filter our unwanted Spans like XHR's running health checks or something similar. By default `shouldCreateSpanForRequest` is already filtering out what was defined in `tracingOrigins`. + +```javascript +import * as Sentry from "@sentry/browser"; +import { Integrations } from "@sentry/tracing"; +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [ + new Integrations.BrowserTracing({ + shouldCreateSpanForRequest: url => { + // Example of filter out spans that contain `health` + if (url.match(/health/)) { + return false; + } + return true; + }, + }), + ], + + // Be sure to lower this in production, or use tracesSampler for finer control + tracesSampleRate: 1.0, +}); +``` diff --git a/src/platforms/javascript/common/performance/index.mdx b/src/platforms/javascript/common/performance/index.mdx index fd02eeefe0f8b..1422f35491c3e 100644 --- a/src/platforms/javascript/common/performance/index.mdx +++ b/src/platforms/javascript/common/performance/index.mdx @@ -6,7 +6,6 @@ redirect_from: - /platforms/javascript/performance/apm-to-tracing/ --- -The `@sentry/tracing` package provides a `BrowserTracing` integration to add automatic instrumentation for monitoring the performance of browser applications. ```javascript {tabTitle: ESM} // Substitude `@sentry/browser` for the integration you're using (if applicable) @@ -34,39 +33,11 @@ Sentry.init({ }); ``` -After configuration, you should see both `pageload` and `navigation` transactions show up in your Sentry UI. -You can pass many different options to the `BrowserTracing` integration (as an object of the form `{optionName: value}`), but it comes with reasonable defaults out of the box. For all possible options, see [TypeDocs](https://getsentry.github.io/sentry-javascript/interfaces/tracing.browsertracingoptions.html). -### tracingOrigins -Usage: -```javascript -Sentry.init({ - dsn: "___PUBLIC_DSN___", - integrations: [ - new Integrations.BrowserTracing({ - tracingOrigins: ["localhost", "my-site-url.com"], - }), - ], - - // Be sure to lower this in production, or use tracesSampler for finer control - tracesSampleRate: 1.0, -}); -``` -The default value of `tracingOrigins` is `['localhost', /^\//]`. The JavaScript SDK will attach the `sentry-trace` header to all outgoing XHR/fetch requests whose destination contains a string in the list or matches a regex in the list. If your frontend is making requests to a different domain, you will need to add it there to propagate the `sentry-trace` header to the backend services, which is required to link transactions together as part of a single trace. **One important thing to note is that the `tracingOrigins` option matches against the whole request URL, not just the domain. Using stricter regex to match certain parts of the URL can help make sure that requests do not unnecessarily have the `sentry-trace` header attached.** - -_Example:_ - -- A frontend application is served from `example.com` -- A backend service is served from `api.example.com` -- The frontend application makes API calls to the backend -- Therefore, the option needs to be configured like this: `new Integrations.BrowserTracing({tracingOrigins: ['api.example.com']})` -- Now outgoing XHR/fetch requests to `api.example.com` will get the `sentry-trace` header attached - -_NOTE:_ You need to make sure your web server CORS is configured to allow the `sentry-trace` header. The configuration might look like `"Access-Control-Allow-Headers: sentry-trace"`, but the configuration depends on your set up. If you do not allow the `sentry-trace` header, the request might be blocked. ### Connecting Backend and Frontend Transactions @@ -96,130 +67,22 @@ JavaScript code running on a browser cannot read the response headers of the cur -### beforeNavigate -For `pageload` and `navigation` transactions, the `BrowserTracing` integration uses the browser's `window.location` API to generate a transaction name. To customize the name of the `pageload` and `navigation` transactions, you can supply a `beforeNavigate` option to the `BrowserTracing` integration. This option allows you to pass in a function that takes in the location at the time of navigation and returns a new transaction name. -`beforeNavigate` is useful if you would like to leverage the routes from a custom routing library like `React Router` or if you want to reduce the cardinality of particular transactions. ```javascript -import * as Sentry from "@sentry/browser"; -import { Integrations } from "@sentry/tracing"; - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - integrations: [ - new Integrations.BrowserTracing({ - beforeNavigate: context => { - return { - ...context, - // You could use your UI's routing library to find the matching - // route template here. We don't have one right now, so do some basic - // parameter replacements. - name: location.pathname - .replace(/\d+/g, "") - .replace(/[a-f0-9]{32}/g, ""), - }; - }, - }), - ], - - // Be sure to lower this in production, or use tracesSampler for finer control - tracesSampleRate: 1.0, -}); ``` -### shouldCreateSpanForRequest -This function can be used to filter our unwanted Spans like XHR's running health checks or something similar. By default `shouldCreateSpanForRequest` is already filtering out what was defined in `tracingOrigins`. -```javascript -import * as Sentry from "@sentry/browser"; -import { Integrations } from "@sentry/tracing"; -Sentry.init({ - dsn: "___PUBLIC_DSN___", - integrations: [ - new Integrations.BrowserTracing({ - shouldCreateSpanForRequest: url => { - // Example of filter out spans that contain `health` - if (url.match(/health/)) { - return false; - } - return true; - }, - }), - ], - - // Be sure to lower this in production, or use tracesSampler for finer control - tracesSampleRate: 1.0, -}); -``` -### Manual Instrumentation -To manually instrument certain regions of your code, you can create a transaction to capture them. -This is valid for both JavaScript Browser and Node and works independently of the `BrowserTracing` integration. -```javascript -const transaction = Sentry.startTransaction({ name: "test-transaction" }); -const span = transaction.startChild({ op: "functionX" }); // This function returns a Span -// functionCallX -span.finish(); // Remember that only finished spans will be sent with the transaction -transaction.finish(); // Finishing the transaction will send it to Sentry -``` -Here is a different example. If you want to create a transaction for a user interaction on your page, you need to do the following: ```javascript -// Let's say this function is invoked when a user clicks on the checkout button of your shop -shopCheckout() { - // This will create a new Transaction for you - const transaction = Sentry.startTransaction('shopCheckout'); - // set the transaction on the scope so it picks up any errors - hub.configureScope(scope => scope.setSpan(transaction)); - - // Assume this function makes an xhr/fetch call - const result = validateShoppingCartOnServer(); - - const span = transaction.startChild({ - data: { - result - }, - op: 'task', - description: `processing shopping cart result`, - }); - processAndValidateShoppingCart(result); - span.finish(); - - transaction.finish(); -} -``` - -This example will send a transaction `shopCheckout` to Sentry. The transaction will contain a `task` span that measures how long `processAndValidateShoppingCart` took. Finally, the call to `transaction.finish()` will finish the transaction and send it to Sentry. - -#### Adding Additional Spans to the Transaction -The next example contains the implementation of the hypothetical `processItem` function called from the code snippet in the previous section. Our SDK can determine if there is currently an open transaction and add to it all newly created spans as child operations. Keep in mind that each individual span needs to be manually finished; otherwise, that span will not show up in the transaction. -```javascript -function processItem(item, transaction) { - const span = transaction.startChild({ - op: "http", - description: "GET /", - }); - - return new Promise((resolve, reject) => { - http.get(`/items/${item.id}`, response => { - response.on("data", () => {}); - response.on("end", () => { - span.setTag("http.status_code", response.statusCode); - span.setData("http.foobarsessionid", getFoobarSessionid(response)); - span.finish(); - resolve(response); - }); - }); - }); -} ``` ### Grouping Transactions diff --git a/src/platforms/javascript/common/performance/manual.mdx b/src/platforms/javascript/common/performance/manual.mdx new file mode 100644 index 0000000000000..66c5dc042257f --- /dev/null +++ b/src/platforms/javascript/common/performance/manual.mdx @@ -0,0 +1,71 @@ +--- +title: Capturing Transactions Manually +sidebar_order: 20 +description: "Learn how to capture performance data on any action in your app." +--- + +### Manual Instrumentation + +To manually instrument certain regions of your code, you can create transactions to capture them. This is valid for all JavaScript SDKs (both backend and frontend) and works independently of the `Express`, `Http`, and `BrowserTracing` integrations. + +```javascript +const transaction = Sentry.startTransaction({ name: "test-transaction" }); +const span = transaction.startChild({ op: "functionX" }); // This function returns a Span +// functionCallX +span.finish(); // Remember that only finished spans will be sent with the transaction +transaction.finish(); // Finishing the transaction will send it to Sentry +``` + +Here is a different example. If you want to create a transaction for a user interaction on your page, you need to do the following: + +```javascript +// Let's say this function is invoked when a user clicks on the checkout button of your shop +shopCheckout() { + // This will create a new Transaction for you + const transaction = Sentry.startTransaction('shopCheckout'); + // set the transaction on the scope so it picks up any errors + hub.configureScope(scope => scope.setSpan(transaction)); + + // Assume this function makes an xhr/fetch call + const result = validateShoppingCartOnServer(); + + const span = transaction.startChild({ + data: { + result + }, + op: 'task', + description: `processing shopping cart result`, + }); + processAndValidateShoppingCart(result); + span.finish(); + + transaction.finish(); +} +``` + +This example will send a transaction `shopCheckout` to Sentry. The transaction will contain a `task` span that measures how long `processAndValidateShoppingCart` took. Finally, the call to `transaction.finish()` will finish the transaction and send it to Sentry. + +#### Adding Additional Spans to the Transaction + +The next example contains the implementation of the hypothetical `processItem` function called from the code snippet in the previous section. Our SDK can determine if there is currently an open transaction and add to it all newly created spans as child operations. Keep in mind that each individual span needs to be manually finished; otherwise, that span will not show up in the transaction. + +```javascript +function processItem(item, transaction) { + const span = transaction.startChild({ + op: "http", + description: "GET /", + }); + + return new Promise((resolve, reject) => { + http.get(`/items/${item.id}`, response => { + response.on("data", () => {}); + response.on("end", () => { + span.setTag("http.status_code", response.statusCode); + span.setData("http.foobarsessionid", getFoobarSessionid(response)); + span.finish(); + resolve(response); + }); + }); + }); +} +``` From 87cc9f63136dfc9996f03ced416d206f93f4860b Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 28 Sep 2020 11:41:45 -0700 Subject: [PATCH 05/13] change order of sections on index page --- .../javascript/common/performance/index.mdx | 99 ++++++++----------- 1 file changed, 41 insertions(+), 58 deletions(-) diff --git a/src/platforms/javascript/common/performance/index.mdx b/src/platforms/javascript/common/performance/index.mdx index 1422f35491c3e..0711b429f4dc9 100644 --- a/src/platforms/javascript/common/performance/index.mdx +++ b/src/platforms/javascript/common/performance/index.mdx @@ -68,24 +68,64 @@ JavaScript code running on a browser cannot read the response headers of the cur +## Retrieving an Active Transaction +In cases where you want to attach Spans to an already ongoing transaction you can use `Sentry.getCurrentHub().getScope().getTransaction()`. This function will return a `Transaction` object when there is a running transaction on the scope, otherwise it returns `undefined`. If you are using our BrowserTracing integration, by default we attach the transaction to the Scope, so you could do something like this: ```javascript +function myJsFunction() { + const transaction = Sentry.getCurrentHub() + .getScope() + .getTransaction(); + if (transaction) { + let span = transaction.startChild({ + op: "encode", + description: "parseAvatarImages", + }); + // Do something + span.finish(); + } +} ``` +## Adding Query Information and Parameters to Spans +Currently, every tag has a maximum character limit of 200 characters. Tags over the 200 character limit will become truncated, losing potentially important information. To retain this data, you can split data over several tags instead. +For example, a 200+ character tagged request: +`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=161803398874989484820458683436563811772030917980576` +The 200+ character request above will become truncated to: +`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=1618033988749894848` +Instead, using `span.set_tag` and `span.set_data` preserves the details of this query using structured metadata. This could be done over `baseUrl`, `endpoint`, and `parameters`: ```javascript +const baseUrl = "https://empowerplant.io"; +const endpoint = "/api/0/projects/ep/setup_form"; +const parameters = { + user_id: 314159265358979323846264338327, + tracking_id: "EasyAsABC123OrSimpleAsDoReMi", + product_name: PlantToHumanTranslator, + product_id: 161803398874989484820458683436563811772030917980576, +}; +const span = transaction.startChild({ + op: "request", + description: "setup form", +}); +span.setTag("baseUrl", baseUrl); +span.setTag("endpoint", endpoint); +span.setData("parameters", parameters); +// you may also find some parameters to be valuable as tags +span.setData("user_id", parameters.user_id); +http.get(`${base_url}/${endpoint}/`, (data = parameters)); ``` -### Grouping Transactions +## Grouping Transactions When Sentry captures transactions, they are assigned a transaction name. This name is generally auto-generated by the Sentry SDK based on the framework integrations you are using. If you can't leverage the automatic transaction generation (or want to customize how transaction names are generated) you can use a global event processor that is registered when you initialize the SDK with your configuration. @@ -128,60 +168,3 @@ Sentry.init({ ], }); ``` - -### Retrieving a Transaction - -In cases where you want to attach Spans to an already ongoing Transaction you can use `Sentry.getCurrentHub().getScope().getTransaction()`. This function will return a `Transaction` in case there is a running Transaction on the scope, otherwise it returns `undefined`. If you are using our BrowserTracing integration by default we attach the Transaction to the Scope. So you could do something like this: - -```javascript -function myJsFunction() { - const transaction = Sentry.getCurrentHub() - .getScope() - .getTransaction(); - if (transaction) { - let span = transaction.startChild({ - op: "encode", - description: "parseAvatarImages", - }); - // Do something - span.finish(); - } -} -``` - -### Adding Query Information and Parameters to Spans - -Currently, every tag has a maximum character limit of 200 characters. Tags over the 200 character limit will become truncated, losing potentially important information. To retain this data, you can split data over several tags instead. - -For example, a 200+ character tagged request: - -`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=161803398874989484820458683436563811772030917980576` - -The 200+ character request above will become truncated to: - -`https://empowerplant.io/api/0/projects/ep/setup_form/?user_id=314159265358979323846264338327&tracking_id=EasyAsABC123OrSimpleAsDoReMi&product_name=PlantToHumanTranslator&product_id=1618033988749894848` - -Instead, using `span.set_tag` and `span.set_data` preserves the details of this query using structured metadata. This could be done over `baseUrl`, `endpoint`, and `parameters`: - -```javascript -const baseUrl = "https://empowerplant.io"; -const endpoint = "/api/0/projects/ep/setup_form"; -const parameters = { - user_id: 314159265358979323846264338327, - tracking_id: "EasyAsABC123OrSimpleAsDoReMi", - product_name: PlantToHumanTranslator, - product_id: 161803398874989484820458683436563811772030917980576, -}; - -const span = transaction.startChild({ - op: "request", - description: "setup form", -}); - -span.setTag("baseUrl", baseUrl); -span.setTag("endpoint", endpoint); -span.setData("parameters", parameters); -// you may also find some parameters to be valuable as tags -span.setData("user_id", parameters.user_id); -http.get(`${base_url}/${endpoint}/`, (data = parameters)); -``` From f430e2290d4cf70228cd835fb9ce4bd608e53692 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 28 Sep 2020 11:42:35 -0700 Subject: [PATCH 06/13] add enablement intro section --- .../javascript/common/performance/index.mdx | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/platforms/javascript/common/performance/index.mdx b/src/platforms/javascript/common/performance/index.mdx index 0711b429f4dc9..68a2ff57728b6 100644 --- a/src/platforms/javascript/common/performance/index.mdx +++ b/src/platforms/javascript/common/performance/index.mdx @@ -6,6 +6,39 @@ redirect_from: - /platforms/javascript/performance/apm-to-tracing/ --- +Sentry allows you to monitor the performance of your application, showing you how latency in one service may affect another service, and letting you pinpoint exactly which parts of a given operation may be responsible. To do this, it captures distributed traces consisting of transactions and spans, which measure individual services and individual operations within those services, respectively. You can learn more about this model in our [Distributed Tracing](/product/performance/distributed-tracing/) docs. + +Once tracing is enabled, certain types of operations will be measured automatically, and you can also choose to manually measure any operation you like. To learn more, see [Capturing Transactions Automatically](/platforms/javascript/performance/automatic/) and [Capturing Transactions Manually](/platforms/javascript/performance/manual/). + +## Enabling Tracing + +The first step is to install the tracing package, if you haven't done so already: + +```bash {tabTitle: ESM} +# Using yarn +$ yarn add @sentry/tracing + +# Using npm +$ npm install @sentry/tracing +``` + +```html {tabTitle: CDN} + +``` + +Once you've installed the package, there are two ways to enable tracing in your app: + +- Set a uniform sample rate for all transactions, by setting the `tracesSampleRate` option in your SDK config to a number between `0` and `1`. (For example, to send 20% of transactions, set `tracesSampleRate` to `0.2`.) +- Control the sample rate dynamically, based on the transaction itself and the context in which it's captured, by providing a function to the `tracesSampler` config option. ```javascript {tabTitle: ESM} // Substitude `@sentry/browser` for the integration you're using (if applicable) @@ -33,11 +66,17 @@ Sentry.init({ }); ``` +If either of these options is set, tracing will be enabled in your app. (They are meant to be mutually exclusive, but if you do set both, `tracesSampler` will take precedence.) You can learn more about how they work in [Sampling Transactions](/platforms/javascript/performance/sampling/). + +When you first enable tracing, the easiest thing to do to test it is to set `tracesSampleRate` to `1.0`, because that guarantees that every transaction will be sent to Sentry for you to see. +Once you're done with testing, however, we recommend that you either **lower your `tracesSampleRate` value, or switch to using `tracesSampler` to dynamically sample and filter your transactions**. +Without sampling, our atomatic instrumenation will send a transaction any time any user loads any page or navigates anywhere in your app. That's a lot of transactions! Sampling allows you to get representative data without overwhelming either your system or your Sentry transaction quota. + ### Connecting Backend and Frontend Transactions From e6fa5c5044187c97d2e7ad0d3d21755f725b9dd8 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 28 Sep 2020 11:43:35 -0700 Subject: [PATCH 07/13] add page on sampling and associated includes --- .../custom-sampling-context/javascript.mdx | 20 +++ .../custom-sampling-context/node.mdx | 22 +++ .../default-sampling-context/javascript.mdx | 14 ++ .../default-sampling-context/node.mdx | 13 ++ .../common/performance/sampling.mdx | 140 ++++++++++++++++++ 5 files changed, 209 insertions(+) create mode 100644 src/includes/performance/custom-sampling-context/javascript.mdx create mode 100644 src/includes/performance/custom-sampling-context/node.mdx create mode 100644 src/includes/performance/default-sampling-context/javascript.mdx create mode 100644 src/includes/performance/default-sampling-context/node.mdx create mode 100644 src/platforms/javascript/common/performance/sampling.mdx diff --git a/src/includes/performance/custom-sampling-context/javascript.mdx b/src/includes/performance/custom-sampling-context/javascript.mdx new file mode 100644 index 0000000000000..788b6bef31120 --- /dev/null +++ b/src/includes/performance/custom-sampling-context/javascript.mdx @@ -0,0 +1,20 @@ +```javascript +Sentry.startTransaction( + { + // `transactionContext` - will be recorded on transaction + name: 'Search from navbar', + op: 'search', + tags: { + testGroup: 'A3', + treatmentName: 'eager load', + }, + }, + // `customSamplingContext` - won't be recorded + { + // PII + userId: '12312012', + // too big to send + resultsFromLastSearch: { ... } + }, +); +``` diff --git a/src/includes/performance/custom-sampling-context/node.mdx b/src/includes/performance/custom-sampling-context/node.mdx new file mode 100644 index 0000000000000..6e5747a87bb76 --- /dev/null +++ b/src/includes/performance/custom-sampling-context/node.mdx @@ -0,0 +1,22 @@ +```javascript +Sentry.startTransaction( + { + // `transactionContext` - will be recorded on transaction + name: 'GET /search', + op: 'search', + data: { + queryParams: { + animal: "dog", + type: "very good" + } + }, + }, + // `customSamplingContext` - won't be recorded + { + // PII + userId: '12312012', + // too big to send + searchResults: { ... } + }, +); +``` diff --git a/src/includes/performance/default-sampling-context/javascript.mdx b/src/includes/performance/default-sampling-context/javascript.mdx new file mode 100644 index 0000000000000..8a01199a60541 --- /dev/null +++ b/src/includes/performance/default-sampling-context/javascript.mdx @@ -0,0 +1,14 @@ +For browser-based SDKs, it includes the following: + +```javascript +// contents of `samplingContext` +{ + transactionContext: { + name: string; // human-readable identifier, like "GET /users" + op: string; // short descriptor of transaction type, like "pageload" + } + parentSampled: boolean; // if this transaction has a parent, its sampling decision + location: Location | WorkerLocation; // the window.location or self.location object + ... // custom context as passed to `startTransaction` +} +``` diff --git a/src/includes/performance/default-sampling-context/node.mdx b/src/includes/performance/default-sampling-context/node.mdx new file mode 100644 index 0000000000000..39c0277ba96df --- /dev/null +++ b/src/includes/performance/default-sampling-context/node.mdx @@ -0,0 +1,13 @@ +The information contained in the `samplingContext` object passed to the `tracesSampler` when a transaction is created varies by platform. For node-based SDKs, it includes the following: + +```javascript +{ + transactionContext: { + name: string; // human-readable identifier, like "GET /users" + op: string; // short descriptor of transaction type, like "pageload" + } + parentSampled: boolean; // if this transaction has a parent, its sampling decision + request: object // in server contexts, information about the incoming request + ... // custom context as passed to `startTransaction` +} +``` diff --git a/src/platforms/javascript/common/performance/sampling.mdx b/src/platforms/javascript/common/performance/sampling.mdx new file mode 100644 index 0000000000000..94d3e27db9fab --- /dev/null +++ b/src/platforms/javascript/common/performance/sampling.mdx @@ -0,0 +1,140 @@ +--- +title: Sampling Transactions +sidebar_order: 20 +description: "Learn how to configure the volume of transactions sent to Sentry." +--- + +There are two ways to control the volume of transactions sent to Sentry. + +## Uniform Sample Rate + +Setting a uniform sample rate is a good option if you want an even cross-section of transactions, no matter where in your app or under what circumstances they occur, and are happy with the default inheritance and precedence behavior described below. + +To do this, set the `tracesSampleRate` option in your `Sentry.init()` to a number between 0 and 1, and every transaction created will have that percentage chance of being sent to Sentry. (So, for example, if you set `tracesSampleRate` to `0.2`, approximately 20% of your transactions will get recorded and sent.) That looks like this: + +```javascript {tabTitle: ESM} +// If you're using one of our integration packages, like `@sentry/react` or `@sentry/angular`, +// substitute its name for `@sentry/browser` here +import * as Sentry from "@sentry/browser"; + +// If taking advantage of automatic instrumentation (highly recommended) +import { Integrations as TracingIntegrations } from "@sentry/tracing"; +// Or, if only doing manual tracing +// import * as _ from "@sentry/tracing" +// Note: You MUST import the package in some way for tracing to work + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + + // This enables automatic instrumentation (highly recommeneded), but is not + // necessary for purely manual usage + integrations: [new TracingIntegrations.BrowserTracing()], + + // Each transaction has a 20% chance of being sent to Sentry + tracesSampleRate: 0.2, +}); +``` + +```javascript {tabTitle: CDN} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + + // This enables automatic instrumentation (highly recommeneded), but is not + // necessary for purely manual usage + integrations: [new Sentry.Integrations.BrowserTracing()], + + // Each transaction has a 20% chance of being sent to Sentry + tracesSampleRate: 0.2, +}); +``` + +## Dynamic Sampling Function + +Providing a sampling function is a good option if you + +- want to sample different transactions at different rates +- want to filer out some transactions entirely +- want to modify the default precedence and inheritance behavior described below + +To sample dynamically, set the `tracesSampler` option in your `Sentry.init()` to a function which will accept a `samplingContext` object and return a sample rate between 0 and 1. For example: + +```javascript +tracesSampler: samplingContext => { + // Examine provided context data (including parent decision, if any) along with anything + // in the global namespace to compute the sample rate or sampling decision for this transaction. + + if ("...") { + return 0.5; // These are important - take a big sample + } else if ("...") { + return 0.01; // These are less important or happen much more frequently - only take 1% of them + } else if ("...") { + return 0; // These aren't something worth tracking - drop all transactions like this + } else { + return 0.1; // Default sample rate + } +}; +``` + +For convenience, the function can also return a boolean. Returning `true` is equivalent to returning `1`, and will guarantee the transaction will be sent to Sentry. Returning `false` is equivalent to returning `0` and will guarantee the transaction witll **not** be sent to Sentry. + +### Default Sampling Context Data + +The information contained in the `samplingContext` object passed to the `tracesSampler` when a transaction is created varies by platform. + + + +### Custom Sampling Context Data + +When manually creating a transaction, you can add data to the `samplingContext` by passing it as an optional second argument to `startTransaction()`. This is useful if there's data to which you want the sampler to have access but which you don't want to attach to the transaction as `tags` or `data`, such as information that's sensitive or that’s too large to send with the transaction. For example: + + + +## Inheritance + +Whatever a transaction's sampling decision, that decision will be passed to its child spans and from there to any transactions they subsequently cause in other services. (See [Connecting Backend and Frontend Transactions](/platforms/javascript/performance/) for more about how that propogation is done.) + +If the transaction currently being created is one of those subsequent transactions (in other words, if it has a parent transaction), the upstream (parent) sampling decision will always be included in the sampling context data, so that your `tracesSampler` can choose whether and when to inherit that decision. (In most cases, inheritance is the right choice, so that you don't end up with partial traces.) + +For convenience, the `tracesSampler` function can return a boolean, so that a parent's decision can be returned directly if that's the desired behavior. + +```javascript +tracesSampler: samplingContext => { + // always inherit + if (samplingContext.parentSampled !== undefined) { + return samplingContext.parentSampled + } + + ... + // rest of sampling logic here +} +``` + +If you're using a `tracesSampleRate` rather than a `tracesSampler`, the decision will always be inherited. + +## Forcing a Sampling Decision + +If you know at transaction creation time whether or not you want the transaction sent to Sentry, you also have the option of passing a sampling decision directly to the transaction in the `transactionContext` object (note, not the `customSamplingContext` object). If you do that, the transaction won't be subject to the `tracesSampleRate`, nor will `tracesSampler` be run, so you can count on the decision that's passed not to be overwritten. + +```javascript +Sentry.startTransaction({ + name: "Search from navbar", + sampled: true, +}); +``` + +## Precedence + +There are multiple ways for a transaction to end up with a sampling decision. + +- Random sampling according to a static sample rate set in `tracesSampleRate` +- Random sampling according to a dynamic sample rate returned by `tracesSampler` +- Absolute decision (100% chance or 0% chance) returned by `tracesSampler` +- If the transaction has a parent, inheriting its parent's sampling decision +- Absolute decision passed to `startTransaction` + +When there's the potential for more than one of these to come into play, the decision is resolved according to the following precedence rules: + +1. If a sampling decision is passed to `startTransaction` (`startTransaction({name: "my transaction", sampled: true})`), that decision will be used, regardlesss of anything else +2. If `tracesSampleRate` is defined, its decision will be used. It can choose to keep or ignore any parent sampling decision, or use the sampling context data to make its own decision or choose a sample rate for the transaction. +3. If `tracesSampler` is not defined, but there's a parent sampling decision, it will be used. +4. If `tracesSampler` is not defined and there's no parent sampling decision, `tracesSampleRate` will be used. From da8a13a8b7012bb4710fb53b20a4210aec5d28ae Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 28 Sep 2020 11:45:06 -0700 Subject: [PATCH 08/13] update main JS page --- src/platforms/javascript/index.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platforms/javascript/index.mdx b/src/platforms/javascript/index.mdx index a7b1547140d94..9ad948b804519 100644 --- a/src/platforms/javascript/index.mdx +++ b/src/platforms/javascript/index.mdx @@ -124,9 +124,9 @@ Sentry.init({ }); ``` -Performance data is transmitted using a new event type called “transactions”, which you can learn about in [Distributed Tracing](/product/performance/distributed-tracing/). To capture transactions, install the performance package and configure your SDK to set the `tracesSampleRate` configuration to a nonzero value. The example configuration above will transmit 100% of captured transactions; lower this value in production to avoid consuming your quota too quickly. +Performance data is transmitted using a new event type called “transactions,” which you can learn about in [Distributed Tracing](/product/performance/distributed-tracing/). To begin capturing transactions, install the tracing package and set either `tracesSampleRate` or `tracesSampler` in your [SDK configuration](/platforms/javascript/configuration/options/#common-options). These determine what percentage of potential transactions get sent to Sentry; we recommend capturing only a sample to avoid consuming your quota too quickly. -Learn more about sampling in [Filtering Events Reported to Sentry](configuration/filtering). +Learn more about `tracesSampleRate` and `tracesSampler` in [Sampling Transactions](/performance/sampling). ## Next Steps From 0ae4b8fe0f7f849eeb4050f1f88882e2f721cd83 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 28 Sep 2020 11:46:04 -0700 Subject: [PATCH 09/13] edit connecting front to back section and add sentry-trace header to it --- .../javascript/common/performance/index.mdx | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/platforms/javascript/common/performance/index.mdx b/src/platforms/javascript/common/performance/index.mdx index 68a2ff57728b6..e4c1659c4b10b 100644 --- a/src/platforms/javascript/common/performance/index.mdx +++ b/src/platforms/javascript/common/performance/index.mdx @@ -78,34 +78,36 @@ Without sampling, our atomatic instrumenation will send a transaction any time a -### Connecting Backend and Frontend Transactions +## Connecting Backend and Frontend Transactions -When instrumenting both frontend and backend with Sentry, you can connect the -`pageload` transaction on the frontend with the request transaction that rendered the page on the backend. +To connect backend and frontend transactions into a single choherent trace, Sentry uses a `trace_id` value which is propagated between frontend and backend. Depending on the circumstance, this id is transmitted either in a request/response header or in an HTML `` tag. Linking transactions in this way makes it possible for you to navigate between them in the Sentry UI, so you can better understand how the different parts of your system are affecting each other. -Once connected, the backend and frontend transactions will share the same `trace_id`, allowing you to navigate from one transaction to the other in Sentry. +### Pageload -In your backend code, include a `` tag in the `` of the rendered HTML document as in this example: +When enabling tracing in both frontend and backend and taking advantage of the automatic frontend instrumentation, you can connect the automatically-generated `pageload` transaction on the frontend with the request transaction that serves the page on the backend. Because JavaScript code running in a browser cannot read the response headers of the current page, the `trace_id` must be transmitted in the response itself, specifically in a `` tag in the `` of the HTML sent from your backend. ```html - - - + + + + + ``` -The `name` attribute must be the string `"sentry-trace"` and the `content` attribute must be generated by your backend's Sentry SDK using `span.toTraceparent()` (or equivalent, depending on the backend platform). +The `name` attribute must be the string `"sentry-trace"` and the `content` attribute must be generated by your backend's Sentry SDK using `span.toTraceparent()` (or equivalent, depending on the backend platform). This guarantees that a new and unique value will be generated for each request. -The `span` reference is either the transaction that rendered the page or any of its child spans. It defines the parent of the `pageload` transaction. +The `span` reference is either the transaction that serves the HTML, or any of its child spans. It defines the parent of the `pageload` transaction. -For the correct association of transactions in a trace, make sure your backend will render a new and unique value for the `content` attribute for every request. Reusing the same value will cause unrelated traces to incorrectly share the same `trace_id`. +Once the data is included in the `` tag, our `BrowserTracing` integration will pick it up automatically and link it to the transaction generated on pageload. (Note that it will not get linked to automatically-generated `navigation` transactions, that is, those which don't require a full page reload. Each of those will be the result of a different request transaction on the backend, and therefore should have a unique `trace_id`.) - +### Navigation and Other XHR Requests -JavaScript code running on a browser cannot read the response headers of the current page. Therefore, the `` tag is used to propagate tracing metadata from the backend instead of the `sentry-trace` HTTP header described earlier. +Once a page is loaded, any requests it makes and any responses your backend generates as a result are linked through a request/response header. - +As is the case with the `` tag discussed above, the header's name is `sentry-trace` and its value is obtained by calling `span.toTraceparent()` (or the equivalent), where `span` is either the relevant transaction or any of its children. +All of Sentry's tracing-related integrations (`BrowserTracing`, `Http`, and `Express`) either generate or pick up and propagate this header automatically as appropriate, for all transactions and spans which they generate. You can also attach and read the header yourself, in any case in which you've manually created either a transaction or a span and it makes sense to do so. ## Retrieving an Active Transaction From abb8582aa47fa11d46cff805fa82c0926b3b2feb Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 28 Sep 2020 11:47:28 -0700 Subject: [PATCH 10/13] reorganize filtering page and add transaction sampling --- .../common/configuration/filtering.mdx | 80 +++++++++++++------ .../common/configuration/options.mdx | 2 +- 2 files changed, 56 insertions(+), 26 deletions(-) diff --git a/src/platforms/common/configuration/filtering.mdx b/src/platforms/common/configuration/filtering.mdx index 1f055a164b60d..1005177677455 100644 --- a/src/platforms/common/configuration/filtering.mdx +++ b/src/platforms/common/configuration/filtering.mdx @@ -1,20 +1,22 @@ --- -title: Filtering Events +title: Filtering and Sampling Events sidebar_order: 5 -description: "Learn more about how to filter events reported to Sentry, using either the SDK, product filtering options, or both." +description: "Learn more about how to configure your SDK to filter and sample events reported to Sentry." notSupported: - perl --- -While sending all application errors to Sentry ensures you’ll be notified in real-time when errors occur in your code, often applications generate many errors, thus many notifications. The Sentry SDKs have several configuration options you can use to filter unwanted errors from leaving your application’s runtime. In addition, sentry.io also [offers methods to filter events](/product/error-monitoring/filtering/). +There are many reasons you might want to send every possible event to Sentry. While sending all errors ensures you’ll be notified in real-time when problems occur in your code, often applications generate many errors, and thus many notifications. Similarly, while transaction events give you a detailed look into every user's experience (not just those with problems), they also get sent by **every user**, and thus can pile up and eat through your quota very quickly. -## Configure your SDK to Filter Events +To help with those problems, the Sentry SDKs have several configuration options you can use to prevent unwanted events from getting sent to Sentry, as well as ways to send only a representative sample of those you do want.. (The Sentry UI also offers methods to filter events, which you can read more about [here](/product/error-monitoring/filtering/).) -Configure your SDK to filter events by using the `beforeSend` callback method and configuring, enabling, or disabling integrations. +## Filtering Error Events -### Using `before-send` +Configure your SDK to filter error events by using the `beforeSend` callback method and configuring, enabling, or disabling integrations. -All Sentry SDKs support the `beforeSend` callback method. `before-send` is called immediately before the event is sent to the server, so it’s the final place where you can edit its data. It receives the event object as a parameter, so you can use that to modify the event’s data or drop it completely (by returning `null`) based on custom logic and the data available on the event. +### Using `beforeSend` + +All Sentry SDKs support the `beforeSend` callback method. `beforeSend` is called immediately before the event is sent to the server, so it’s the final place where you can edit its data. It receives the event object as a parameter, so you can use that to modify the event’s data or drop it completely (by returning `null`) based on custom logic and the data available on the event. @@ -30,24 +32,6 @@ Typically a `hint` holds the original exception so that additional data can be e When the SDK creates an event or breadcrumb for transmission, that transmission is typically created from some sort of source object. For instance, an error event is typically created from a log record or exception instance. For better customization, SDKs send these objects to certain callbacks (`before-send`, `before-breadcrumb` or the event processor system in the SDK). -#### Sampling - -If a sample rate is defined for the SDK, the SDK evaluates whether this event should be sent as a representative fraction of events. - - - -The SDK sample rate is not dynamic; changing it requires re-deployment. In addition, setting an SDK sample rate limits visibility into the source of events. Setting a rate limit for your project may better suit your needs. - - - -When you enable sampling in your SDK, you choose a percentage of collected errors to send to Sentry. For example, to sample 25% of your events: - - - -For Sentry's Performance Monitoring, we recommend sampling your data for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, by enabling sampling you’ll more easily prevent yourself from exceeding your organization’s [event quota](/product/accounts/quotas/). - -When choosing a sampling rate, the goal is not to collect *too* much data, but to collect sufficient data so you can draw meaningful conclusions. If you’re not sure what rate to choose, start with a low value and gradually increase it as you learn more about your traffic patterns and volume, until you’ve found a rate that balances performance and cost concerns with data accuracy. - ### Using Hints Hints are available in two places: @@ -98,3 +82,49 @@ In this example, the fingerprint is forced to a common value if an exception of : For breadcrumbs created from HTTP requests done via the legacy `XMLHttpRequest` API. This holds the original xhr object. + +## Sampling Error Events + +To send a representative sample of your errors to Sentry, set the `sampleRate` option in your SDK configuration to a number between `0` (0% of errors sent) and `1` (100% of errors sent). This is a static rate, which will apply equally to all errors. For example, to sample 25% of your errors: + + + + + +The error sample rate is not dynamic; changing it requires re-deployment. In addition, setting an SDK sample rate limits visibility into the source of events. Setting a rate limit for your project (which only drops events when volume is high) may better suit your needs. + + + + + +## Filtering Transaction Events + +To prevent certain transactions from being reported to Sentry, use the `tracesSampler` configuration option, which allows you to provide a function to evaluate the current transaction and drop it if it's not one you want. (It also allows you to sample different transactions at different rates.) In its simplest form, used just for filtering, it looks like this: + +```javascript +tracesSampler: samplingContext => { + if ("...") { + return 0; // Drop this transaction, by setting its sample rate to 0% + } else { + return 0.2; // Default sample rate for all others (replaces tracesSampleRate ) + } +}; +``` + + + +The `tracesSampler` and `tracesSampleRate` config options are mutually exclusive. If you define a `tracesSampler` in order to filter out certain transactions, you must also handle the case of non-filtered transactions, by returning the rate at which you'd like them sampled. + + + +To learn more about the `tracesSampler` option, please see [Sampling Transactions](/platforms/javascript/performance/sampling/). + + + +## Sampling Transaction Events + +For Sentry's Performance Monitoring, we recommend sampling your data for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, by enabling sampling you’ll more easily prevent yourself from exceeding your organization’s [event quota](/accounts/quotas/). + +When choosing a sampling rate, the goal is not to collect *too* much data, but to collect sufficient data so you can draw meaningful conclusions. If you’re not sure what rate to choose, start with a low value and gradually increase it as you learn more about your traffic patterns and volume, until you’ve found a rate that balances performance and cost concerns with data accuracy. + +To set a sample rate for your transactions, provide a number between `0` (0% of transactions sent) and `1` (100% of transactions sent) to the `tracesSampleRate` configuration option. For example, including `tracesSampleRate: 0.2` in your SDK config will cause the SDK to only send 20% of possible transaction events. diff --git a/src/platforms/common/configuration/options.mdx b/src/platforms/common/configuration/options.mdx index d62231ce23f0b..f848e27e9a8f1 100644 --- a/src/platforms/common/configuration/options.mdx +++ b/src/platforms/common/configuration/options.mdx @@ -53,7 +53,7 @@ By default all types of errors are be reported (equivalent to `E_ALL`). -Configures the sample rate as a percentage of events to be sent in the range of `0.0` to `1.0`. The default is `1.0` which means that 100% of events are sent. If set to `0.1` only 10% of events will be sent. Events are picked randomly. +Configures the sample rate for error events, in the range of `0.0` to `1.0`. The default is `1.0` which means that 100% of error events are sent. If set to `0.1` only 10% of error events will be sent. Events are picked randomly. From 0197e0786fb8a094a2ebf5d6995452ba6b6d3261 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 28 Sep 2020 11:47:58 -0700 Subject: [PATCH 11/13] general language-fixing --- src/components/platformSidebar.tsx | 2 +- .../configuration/decluttering/javascript.mdx | 2 +- .../javascript/common/performance/index.mdx | 30 ++++++++++++++----- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/components/platformSidebar.tsx b/src/components/platformSidebar.tsx index 02a78aa1bf8d2..863f8efcfaec2 100644 --- a/src/components/platformSidebar.tsx +++ b/src/components/platformSidebar.tsx @@ -83,7 +83,7 @@ export const PlatformSidebar = ({ diff --git a/src/includes/configuration/decluttering/javascript.mdx b/src/includes/configuration/decluttering/javascript.mdx index 36af79a822cd3..f4da6c8608d0a 100644 --- a/src/includes/configuration/decluttering/javascript.mdx +++ b/src/includes/configuration/decluttering/javascript.mdx @@ -6,7 +6,7 @@ You can also use `denyUrls` if you want to block specific URLs forever. -Prior to version 5.17.0, `allowUrls` and `denyUrls` were called `whitelistUrls` and `blacklistUrls` respectively. These options are still supported due to backward compatibility reasons; however, they will be removed in version 6.0. For more information, please see our [Inclusive Language Policy](https://develop.sentry.dev/inclusion/). +Prior to version 5.17.0, `allowUrls` and `denyUrls` were called `whitelistUrls` and `blacklistUrls` respectively. These options are still supported for backwards compatibility reasons, but they will be removed in version 6.0. For more information, please see our [Inclusive Language Policy](https://develop.sentry.dev/inclusion/). diff --git a/src/platforms/javascript/common/performance/index.mdx b/src/platforms/javascript/common/performance/index.mdx index e4c1659c4b10b..1dd344960d03a 100644 --- a/src/platforms/javascript/common/performance/index.mdx +++ b/src/platforms/javascript/common/performance/index.mdx @@ -1,7 +1,7 @@ --- title: Performance Monitoring sidebar_order: 20 -description: "Learn more about how to configure our Performance integrations to get the best experience out of it." +description: "Learn how to enable performance monitoring in your app." redirect_from: - /platforms/javascript/performance/apm-to-tracing/ --- @@ -41,28 +41,44 @@ Once you've installed the package, there are two ways to enable tracing in your - Control the sample rate dynamically, based on the transaction itself and the context in which it's captured, by providing a function to the `tracesSampler` config option. ```javascript {tabTitle: ESM} -// Substitude `@sentry/browser` for the integration you're using (if applicable) +// If you're using one of our integration packages, like `@sentry/react` or +// `@sentry/angular`, substitute its name for `@sentry/browser` here import * as Sentry from "@sentry/browser"; -// Pull in the additional tracing integration +// If taking advantage of automatic instrumentation (highly recommended) import { Integrations as TracingIntegrations } from "@sentry/tracing"; +// Or, if only doing manual tracing +// import * as _ from "@sentry/tracing" +// Note: You MUST import the package in some way for tracing to work Sentry.init({ dsn: "___PUBLIC_DSN___", + + // This enables automatic instrumentation (highly recommeneded), but is not + // necessary for purely manual usage integrations: [new TracingIntegrations.BrowserTracing()], - // Be sure to lower this in production, or use tracesSampler for finer control - tracesSampleRate: 1.0, + // To set a uniform sample rate + tracesSampleRate: 0.2 + + // Alternatively, to control sampling dynamically + tracesSampler: samplingContext => { ... } }); ``` ```javascript {tabTitle: CDN} Sentry.init({ dsn: "___PUBLIC_DSN___", + + // This enables automatic instrumentation (highly recommeneded), but is not + // necessary for purely manual usage integrations: [new Sentry.Integrations.BrowserTracing()], - // Be sure to lower this in production, or use tracesSampler for finer control - tracesSampleRate: 1.0, + // To set a uniform sample rate + tracesSampleRate: 0.2 + + // Alternatively, to control sampling dynamically + tracesSampler: samplingContext => { ... } }); ``` From 315f828631f5fe77b610c781c25eba78ae96dd29 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Mon, 28 Sep 2020 16:53:35 -0700 Subject: [PATCH 12/13] reword tracesSampleRate comment in code snippets --- src/platforms/javascript/common/install/cdn.mdx | 3 ++- .../javascript/common/performance/automatic.mdx | 15 ++++++++++----- src/platforms/javascript/guides/angular/index.mdx | 3 ++- src/platforms/javascript/guides/react/index.mdx | 3 ++- .../guides/react/integrations/react-router.mdx | 12 ++++++++---- src/platforms/javascript/guides/vue/index.mdx | 3 ++- .../guides/vue/integrations/components.mdx | 3 ++- src/platforms/javascript/index.mdx | 3 ++- src/platforms/node/common/performance/index.mdx | 3 ++- src/platforms/node/guides/express/index.mdx | 3 ++- src/platforms/node/guides/koa/index.mdx | 3 ++- src/platforms/node/index.mdx | 6 ++++-- src/wizard/javascript/angular.md | 3 ++- src/wizard/javascript/index.md | 3 ++- src/wizard/javascript/react.md | 3 ++- src/wizard/javascript/vue.md | 6 ++++-- src/wizard/node/express.md | 3 ++- src/wizard/node/index.md | 3 ++- 18 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/platforms/javascript/common/install/cdn.mdx b/src/platforms/javascript/common/install/cdn.mdx index db216eb12d94d..1cd80bda5601b 100644 --- a/src/platforms/javascript/common/install/cdn.mdx +++ b/src/platforms/javascript/common/install/cdn.mdx @@ -41,7 +41,8 @@ Sentry.init({ release: "my-project-name@" + process.env.npm_package_version, integrations: [new Sentry.Integrations.BrowserTracing()], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/common/performance/automatic.mdx b/src/platforms/javascript/common/performance/automatic.mdx index 623770dd102f2..72d1048a57c5d 100644 --- a/src/platforms/javascript/common/performance/automatic.mdx +++ b/src/platforms/javascript/common/performance/automatic.mdx @@ -24,7 +24,8 @@ Sentry.init({ }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` @@ -40,7 +41,8 @@ Sentry.init({ }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` @@ -64,7 +66,8 @@ Sentry.init({ }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` @@ -107,7 +110,8 @@ Sentry.init({ }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` @@ -133,7 +137,8 @@ Sentry.init({ }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/angular/index.mdx b/src/platforms/javascript/guides/angular/index.mdx index 45b09fdabe7cc..3f70713451056 100644 --- a/src/platforms/javascript/guides/angular/index.mdx +++ b/src/platforms/javascript/guides/angular/index.mdx @@ -105,7 +105,8 @@ Sentry.init({ }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/react/index.mdx b/src/platforms/javascript/guides/react/index.mdx index c1fadc7c04d16..ff677e5978a61 100644 --- a/src/platforms/javascript/guides/react/index.mdx +++ b/src/platforms/javascript/guides/react/index.mdx @@ -145,7 +145,8 @@ Sentry.init({ release: "my-project-name@" + process.env.npm_package_version, integrations: [new Integrations.BrowserTracing()], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/react/integrations/react-router.mdx b/src/platforms/javascript/guides/react/integrations/react-router.mdx index 0993b10421948..df2cb0f6d1ba9 100644 --- a/src/platforms/javascript/guides/react/integrations/react-router.mdx +++ b/src/platforms/javascript/guides/react/integrations/react-router.mdx @@ -36,7 +36,8 @@ Sentry.init({ }); ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); @@ -82,7 +83,8 @@ Sentry.init({ }); ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); @@ -123,7 +125,8 @@ Sentry.init({ }); ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); @@ -172,7 +175,8 @@ Sentry.init({ }); ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/vue/index.mdx b/src/platforms/javascript/guides/vue/index.mdx index cbeaf5f0f4e3a..42ab6cdc6a4b8 100644 --- a/src/platforms/javascript/guides/vue/index.mdx +++ b/src/platforms/javascript/guides/vue/index.mdx @@ -101,7 +101,8 @@ Sentry.init({ }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/guides/vue/integrations/components.mdx b/src/platforms/javascript/guides/vue/integrations/components.mdx index cc1fe0fd8dc80..bc8ec32b2ad97 100644 --- a/src/platforms/javascript/guides/vue/integrations/components.mdx +++ b/src/platforms/javascript/guides/vue/integrations/components.mdx @@ -35,7 +35,8 @@ Sentry.init({ }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/javascript/index.mdx b/src/platforms/javascript/index.mdx index 9ad948b804519..1341e5f0aea1a 100644 --- a/src/platforms/javascript/index.mdx +++ b/src/platforms/javascript/index.mdx @@ -119,7 +119,8 @@ Sentry.init({ release: "my-project-name@" + process.env.npm_package_version, integrations: [new Integrations.BrowserTracing()], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/platforms/node/common/performance/index.mdx b/src/platforms/node/common/performance/index.mdx index ffdc1d1290158..b6326bdd3746b 100644 --- a/src/platforms/node/common/performance/index.mdx +++ b/src/platforms/node/common/performance/index.mdx @@ -18,7 +18,8 @@ Sentry.init({ new Sentry.Integrations.Http({ tracing: true }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); diff --git a/src/platforms/node/guides/express/index.mdx b/src/platforms/node/guides/express/index.mdx index 2895108e5882b..f7aad34a95439 100644 --- a/src/platforms/node/guides/express/index.mdx +++ b/src/platforms/node/guides/express/index.mdx @@ -167,7 +167,8 @@ Sentry.init({ new Tracing.Integrations.Express({ app }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); diff --git a/src/platforms/node/guides/koa/index.mdx b/src/platforms/node/guides/koa/index.mdx index baef11188c886..cb72b484197ba 100644 --- a/src/platforms/node/guides/koa/index.mdx +++ b/src/platforms/node/guides/koa/index.mdx @@ -67,7 +67,8 @@ const domain = require("domain"); Sentry.init({ dsn: "___PUBLIC_DSN___", - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); diff --git a/src/platforms/node/index.mdx b/src/platforms/node/index.mdx index 6276f25a322f5..a5d8ef89b4403 100644 --- a/src/platforms/node/index.mdx +++ b/src/platforms/node/index.mdx @@ -71,7 +71,8 @@ const Tracing = require("@sentry/tracing"); Sentry.init({ dsn: "___PUBLIC_DSN___", - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` @@ -83,7 +84,8 @@ import * as Tracing from "@sentry/tracing"; Sentry.init({ dsn: "___PUBLIC_DSN___", - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/wizard/javascript/angular.md b/src/wizard/javascript/angular.md index 515a0b25e5de9..47a95592e6b3a 100644 --- a/src/wizard/javascript/angular.md +++ b/src/wizard/javascript/angular.md @@ -36,7 +36,8 @@ Sentry.init({ }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); diff --git a/src/wizard/javascript/index.md b/src/wizard/javascript/index.md index 7f41547787893..596d91764416f 100644 --- a/src/wizard/javascript/index.md +++ b/src/wizard/javascript/index.md @@ -27,7 +27,8 @@ Sentry.init({ new Integrations.BrowserTracing(), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/wizard/javascript/react.md b/src/wizard/javascript/react.md index d6f1c226ddd5a..8be3dd94df14a 100644 --- a/src/wizard/javascript/react.md +++ b/src/wizard/javascript/react.md @@ -37,7 +37,8 @@ Sentry.init({ new Integrations.BrowserTracing(), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); diff --git a/src/wizard/javascript/vue.md b/src/wizard/javascript/vue.md index ae8f73a32f5fe..3c442db4362dd 100644 --- a/src/wizard/javascript/vue.md +++ b/src/wizard/javascript/vue.md @@ -45,7 +45,8 @@ Sentry.init({ new Integrations.BrowserTracing(), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` @@ -82,7 +83,8 @@ Sentry.init({ new Sentry.Integrations.BrowserTracing(), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); ``` diff --git a/src/wizard/node/express.md b/src/wizard/node/express.md index fb39247db6e8a..b50d79b8c23ed 100644 --- a/src/wizard/node/express.md +++ b/src/wizard/node/express.md @@ -38,7 +38,8 @@ Sentry.init({ new Tracing.Integrations.Express({ app }), ], - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); diff --git a/src/wizard/node/index.md b/src/wizard/node/index.md index 67905cd8df7d9..ef50cdefcf6ed 100644 --- a/src/wizard/node/index.md +++ b/src/wizard/node/index.md @@ -29,7 +29,8 @@ const Tracing = require("@sentry/tracing"); Sentry.init({ dsn: "___PUBLIC_DSN___", - // Be sure to lower this in production, or use tracesSampler for finer control + // We recommend adjusting this value in production, or using tracesSampler + // for finer control tracesSampleRate: 1.0, }); From b5c826cce7d476aa012b8b3cf75cf8cb7c9a647b Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Wed, 30 Sep 2020 13:53:38 -0700 Subject: [PATCH 13/13] respond to PR comments --- src/components/platformSidebar.tsx | 4 ++- .../performance/distributed-tracing.mdx | 4 +-- .../default-sampling-context/javascript.mdx | 2 +- .../default-sampling-context/node.mdx | 2 +- .../common/configuration/filtering.mdx | 30 ++++++++----------- .../common/performance/automatic.mdx | 9 ++---- .../javascript/common/performance/manual.mdx | 8 ++--- .../common/performance/sampling.mdx | 14 ++++----- src/platforms/javascript/index.mdx | 2 +- 9 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/components/platformSidebar.tsx b/src/components/platformSidebar.tsx index 863f8efcfaec2..ca9012103f52f 100644 --- a/src/components/platformSidebar.tsx +++ b/src/components/platformSidebar.tsx @@ -83,7 +83,9 @@ export const PlatformSidebar = ({ diff --git a/src/docs/product/performance/distributed-tracing.mdx b/src/docs/product/performance/distributed-tracing.mdx index 7dd2cc70b47f5..361d5d6756140 100644 --- a/src/docs/product/performance/distributed-tracing.mdx +++ b/src/docs/product/performance/distributed-tracing.mdx @@ -233,9 +233,9 @@ Individual spans aren't sent to Sentry; rather, the entire transaction is sent a When you enable sampling in your tracing setup, you choose a percentage of collected transactions to send to Sentry. For example, if you had an endpoint that received 1000 requests per minute, a sampling rate of `0.25` would result in approximately 250 transactions (25%) being sent to Sentry each minute. (The number is approximate because each request is either tracked or not, independently and pseudorandomly, with a 25% probability. So in the same way that 100 fair coins, when flipped, result in approximately 50 heads, the SDK will "decide" to collect a trace in approximately 250 cases.) Because you know the sampling percentage, you can then extrapolate your total traffic volume. -When collecting traces, we **strongly recommend** sampling your data, for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, by enabling sampling you'll more easily prevent yourself from exceeding your organization's [event quota](/product/accounts/quotas/), which will help you manage costs. +When collecting traces, we recommend sampling your data, for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, enabling sampling allows you to better manage the number of events sent to Sentry, so you can tailor it to your organization's needs. -When choosing a sampling rate, the goal is to not collect _too_ much data (given the reasons above) but also to collect enough data that you are able to draw meaningful conclusions. If you're not sure what rate to choose, we recommend starting with a low value and gradually increasing it as you learn more about your traffic patterns and volume, until you've found a rate which lets you balance performance and cost concerns with data accuracy. +When choosing a sampling rate, the goal is to not collect _too_ much data (given the reasons above) but also to collect enough data that you are able to draw meaningful conclusions. If you're not sure what rate to choose, we recommend starting with a low value and gradually increasing it as you learn more about your traffic patterns and volume, until you've found a rate which lets you balance performance and volume concerns with data accuracy. ### Consistency Within a Trace diff --git a/src/includes/performance/default-sampling-context/javascript.mdx b/src/includes/performance/default-sampling-context/javascript.mdx index 8a01199a60541..368d778963dd3 100644 --- a/src/includes/performance/default-sampling-context/javascript.mdx +++ b/src/includes/performance/default-sampling-context/javascript.mdx @@ -5,7 +5,7 @@ For browser-based SDKs, it includes the following: { transactionContext: { name: string; // human-readable identifier, like "GET /users" - op: string; // short descriptor of transaction type, like "pageload" + op: string; // short description of transaction type, like "pageload" } parentSampled: boolean; // if this transaction has a parent, its sampling decision location: Location | WorkerLocation; // the window.location or self.location object diff --git a/src/includes/performance/default-sampling-context/node.mdx b/src/includes/performance/default-sampling-context/node.mdx index 39c0277ba96df..d2b2f17fbf29a 100644 --- a/src/includes/performance/default-sampling-context/node.mdx +++ b/src/includes/performance/default-sampling-context/node.mdx @@ -4,7 +4,7 @@ The information contained in the `samplingContext` object passed to the `tracesS { transactionContext: { name: string; // human-readable identifier, like "GET /users" - op: string; // short descriptor of transaction type, like "pageload" + op: string; // short description of transaction type, like "pageload" } parentSampled: boolean; // if this transaction has a parent, its sampling decision request: object // in server contexts, information about the incoming request diff --git a/src/platforms/common/configuration/filtering.mdx b/src/platforms/common/configuration/filtering.mdx index 1005177677455..96a142bb1c3d2 100644 --- a/src/platforms/common/configuration/filtering.mdx +++ b/src/platforms/common/configuration/filtering.mdx @@ -6,9 +6,11 @@ notSupported: - perl --- -There are many reasons you might want to send every possible event to Sentry. While sending all errors ensures you’ll be notified in real-time when problems occur in your code, often applications generate many errors, and thus many notifications. Similarly, while transaction events give you a detailed look into every user's experience (not just those with problems), they also get sent by **every user**, and thus can pile up and eat through your quota very quickly. +Adding Sentry to your app gives you a great deal of very valuable information about errors and performance you wouldn't otherwise get. And lots of information is good -- as long as it's the right information, at a reasonable volume. -To help with those problems, the Sentry SDKs have several configuration options you can use to prevent unwanted events from getting sent to Sentry, as well as ways to send only a representative sample of those you do want.. (The Sentry UI also offers methods to filter events, which you can read more about [here](/product/error-monitoring/filtering/).) +The Sentry SDKs have several configuration options to help you control this, allowing you to both filter out events you don't want and to take a representative sample of those you do. + +**Note:**: The Sentry UI also offers methods to filter events, by using [Inbound Filters](/product/error-monitoring/filtering/). We recommend filtering at the client level though, because it removes the overhead of sending events you don't actually want. ## Filtering Error Events @@ -30,7 +32,7 @@ Typically a `hint` holds the original exception so that additional data can be e -When the SDK creates an event or breadcrumb for transmission, that transmission is typically created from some sort of source object. For instance, an error event is typically created from a log record or exception instance. For better customization, SDKs send these objects to certain callbacks (`before-send`, `before-breadcrumb` or the event processor system in the SDK). +When the SDK creates an event or breadcrumb for transmission, that transmission is typically created from some sort of source object. For instance, an error event is typically created from a log record or exception instance. For better customization, SDKs send these objects to certain callbacks (`beforeSend`, `beforeBreadcrumb` or the event processor system in the SDK). ### Using Hints @@ -89,17 +91,17 @@ To send a representative sample of your errors to Sentry, set the `sampleRate` o - - -The error sample rate is not dynamic; changing it requires re-deployment. In addition, setting an SDK sample rate limits visibility into the source of events. Setting a rate limit for your project (which only drops events when volume is high) may better suit your needs. - - +**Note:** The error sample rate is not dynamic; changing it requires re-deployment. In addition, setting an SDK sample rate limits visibility into the source of events. Setting a rate limit for your project (which only drops events when volume is high) may better suit your needs. ## Filtering Transaction Events -To prevent certain transactions from being reported to Sentry, use the `tracesSampler` configuration option, which allows you to provide a function to evaluate the current transaction and drop it if it's not one you want. (It also allows you to sample different transactions at different rates.) In its simplest form, used just for filtering, it looks like this: +To prevent certain transactions from being reported to Sentry, use the `tracesSampler` configuration option, which allows you to provide a function to evaluate the current transaction and drop it if it's not one you want. (It also allows you to sample different transactions at different rates.) + +**Note:** The `tracesSampler` and `tracesSampleRate` config options are mutually exclusive. If you define a `tracesSampler` to filter out certain transactions, you must also handle the case of non-filtered transactions by returning the rate at which you'd like them sampled. + +In its simplest form, used just for filtering, it looks like this: ```javascript tracesSampler: samplingContext => { @@ -111,20 +113,14 @@ tracesSampler: samplingContext => { }; ``` - - -The `tracesSampler` and `tracesSampleRate` config options are mutually exclusive. If you define a `tracesSampler` in order to filter out certain transactions, you must also handle the case of non-filtered transactions, by returning the rate at which you'd like them sampled. - - - To learn more about the `tracesSampler` option, please see [Sampling Transactions](/platforms/javascript/performance/sampling/). ## Sampling Transaction Events -For Sentry's Performance Monitoring, we recommend sampling your data for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, by enabling sampling you’ll more easily prevent yourself from exceeding your organization’s [event quota](/accounts/quotas/). +For Sentry's Performance Monitoring, we recommend sampling your data for two reasons. First, though capturing a single trace involves minimal overhead, capturing traces for every single page load, or every single API request, has the potential to add an undesirable amount of load to your system. Second, enabling sampling allows you to better manage the number of events sent to Sentry, so you can tailor it to your organization's needs. -When choosing a sampling rate, the goal is not to collect *too* much data, but to collect sufficient data so you can draw meaningful conclusions. If you’re not sure what rate to choose, start with a low value and gradually increase it as you learn more about your traffic patterns and volume, until you’ve found a rate that balances performance and cost concerns with data accuracy. +When choosing a sampling rate, the goal is not to collect *too* much data, but to collect sufficient data so you can draw meaningful conclusions. If you’re not sure what rate to choose, start with a low value and gradually increase it as you learn more about your traffic patterns and volume, until you’ve found a rate that balances performance and volume concerns with data accuracy. To set a sample rate for your transactions, provide a number between `0` (0% of transactions sent) and `1` (100% of transactions sent) to the `tracesSampleRate` configuration option. For example, including `tracesSampleRate: 0.2` in your SDK config will cause the SDK to only send 20% of possible transaction events. diff --git a/src/platforms/javascript/common/performance/automatic.mdx b/src/platforms/javascript/common/performance/automatic.mdx index 72d1048a57c5d..b30e3907c841c 100644 --- a/src/platforms/javascript/common/performance/automatic.mdx +++ b/src/platforms/javascript/common/performance/automatic.mdx @@ -118,7 +118,7 @@ Sentry.init({ ### shouldCreateSpanForRequest -This function can be used to filter our unwanted Spans like XHR's running health checks or something similar. By default `shouldCreateSpanForRequest` is already filtering out what was defined in `tracingOrigins`. +This function can be used to filter out unwanted spans such as XHR's running health checks or something similar. By default `shouldCreateSpanForRequest` already filters out everything but what was defined in `tracingOrigins`. ```javascript import * as Sentry from "@sentry/browser"; @@ -128,11 +128,8 @@ Sentry.init({ integrations: [ new Integrations.BrowserTracing({ shouldCreateSpanForRequest: url => { - // Example of filter out spans that contain `health` - if (url.match(/health/)) { - return false; - } - return true; + // Do not create spans for outgoing requests to a `/health/` endpoint + return !url.match(/\/health\/?$/); }, }), ], diff --git a/src/platforms/javascript/common/performance/manual.mdx b/src/platforms/javascript/common/performance/manual.mdx index 66c5dc042257f..da51e1b104d7e 100644 --- a/src/platforms/javascript/common/performance/manual.mdx +++ b/src/platforms/javascript/common/performance/manual.mdx @@ -16,7 +16,7 @@ span.finish(); // Remember that only finished spans will be sent with the transa transaction.finish(); // Finishing the transaction will send it to Sentry ``` -Here is a different example. If you want to create a transaction for a user interaction on your page, you need to do the following: +For example, if you want to create a transaction for a user interaction on your page, you can do this: ```javascript // Let's say this function is invoked when a user clicks on the checkout button of your shop @@ -45,15 +45,15 @@ shopCheckout() { This example will send a transaction `shopCheckout` to Sentry. The transaction will contain a `task` span that measures how long `processAndValidateShoppingCart` took. Finally, the call to `transaction.finish()` will finish the transaction and send it to Sentry. -#### Adding Additional Spans to the Transaction +You can also take advantage of promises when creating spans for async operations. Keep in mind, though, that a span must finish before `transaction.finish()` is called in order to be included in the transaction. -The next example contains the implementation of the hypothetical `processItem` function called from the code snippet in the previous section. Our SDK can determine if there is currently an open transaction and add to it all newly created spans as child operations. Keep in mind that each individual span needs to be manually finished; otherwise, that span will not show up in the transaction. +For example: ```javascript function processItem(item, transaction) { const span = transaction.startChild({ op: "http", - description: "GET /", + description: `GET /items/:item-id`, }); return new Promise((resolve, reject) => { diff --git a/src/platforms/javascript/common/performance/sampling.mdx b/src/platforms/javascript/common/performance/sampling.mdx index 94d3e27db9fab..8d7cdb17951da 100644 --- a/src/platforms/javascript/common/performance/sampling.mdx +++ b/src/platforms/javascript/common/performance/sampling.mdx @@ -4,13 +4,13 @@ sidebar_order: 20 description: "Learn how to configure the volume of transactions sent to Sentry." --- -There are two ways to control the volume of transactions sent to Sentry. +You can control the volume of transactions sent to Sentry in two ways. ## Uniform Sample Rate Setting a uniform sample rate is a good option if you want an even cross-section of transactions, no matter where in your app or under what circumstances they occur, and are happy with the default inheritance and precedence behavior described below. -To do this, set the `tracesSampleRate` option in your `Sentry.init()` to a number between 0 and 1, and every transaction created will have that percentage chance of being sent to Sentry. (So, for example, if you set `tracesSampleRate` to `0.2`, approximately 20% of your transactions will get recorded and sent.) That looks like this: +To do this, set the `tracesSampleRate` option in your `Sentry.init()` to a number between 0 and 1. With this option set, every transaction created will have that percentage chance of being sent to Sentry. (So, for example, if you set `tracesSampleRate` to `0.2`, approximately 20% of your transactions will get recorded and sent.) That looks like this: ```javascript {tabTitle: ESM} // If you're using one of our integration packages, like `@sentry/react` or `@sentry/angular`, @@ -50,13 +50,13 @@ Sentry.init({ ## Dynamic Sampling Function -Providing a sampling function is a good option if you +Providing a sampling function is a good option if you: - want to sample different transactions at different rates - want to filer out some transactions entirely - want to modify the default precedence and inheritance behavior described below -To sample dynamically, set the `tracesSampler` option in your `Sentry.init()` to a function which will accept a `samplingContext` object and return a sample rate between 0 and 1. For example: +To sample dynamically, set the `tracesSampler` option in your `Sentry.init()` to a function that will accept a `samplingContext` object and return a sample rate between 0 and 1. For example: ```javascript tracesSampler: samplingContext => { @@ -75,7 +75,7 @@ tracesSampler: samplingContext => { }; ``` -For convenience, the function can also return a boolean. Returning `true` is equivalent to returning `1`, and will guarantee the transaction will be sent to Sentry. Returning `false` is equivalent to returning `0` and will guarantee the transaction witll **not** be sent to Sentry. +For convenience, the function can also return a boolean. Returning `true` is equivalent to returning `1`, and will guarantee the transaction will be sent to Sentry. Returning `false` is equivalent to returning `0` and will guarantee the transaction will **not** be sent to Sentry. ### Default Sampling Context Data @@ -132,9 +132,9 @@ There are multiple ways for a transaction to end up with a sampling decision. - If the transaction has a parent, inheriting its parent's sampling decision - Absolute decision passed to `startTransaction` -When there's the potential for more than one of these to come into play, the decision is resolved according to the following precedence rules: +When there's the potential for more than one of these to come into play, the following precedence rules apply: 1. If a sampling decision is passed to `startTransaction` (`startTransaction({name: "my transaction", sampled: true})`), that decision will be used, regardlesss of anything else 2. If `tracesSampleRate` is defined, its decision will be used. It can choose to keep or ignore any parent sampling decision, or use the sampling context data to make its own decision or choose a sample rate for the transaction. -3. If `tracesSampler` is not defined, but there's a parent sampling decision, it will be used. +3. If `tracesSampler` is not defined, but there's a parent sampling decision, the parent sampling decision will be used. 4. If `tracesSampler` is not defined and there's no parent sampling decision, `tracesSampleRate` will be used. diff --git a/src/platforms/javascript/index.mdx b/src/platforms/javascript/index.mdx index 1341e5f0aea1a..a29652cc486a8 100644 --- a/src/platforms/javascript/index.mdx +++ b/src/platforms/javascript/index.mdx @@ -125,7 +125,7 @@ Sentry.init({ }); ``` -Performance data is transmitted using a new event type called “transactions,” which you can learn about in [Distributed Tracing](/product/performance/distributed-tracing/). To begin capturing transactions, install the tracing package and set either `tracesSampleRate` or `tracesSampler` in your [SDK configuration](/platforms/javascript/configuration/options/#common-options). These determine what percentage of potential transactions get sent to Sentry; we recommend capturing only a sample to avoid consuming your quota too quickly. +Performance data is transmitted using a new event type called “transactions,” which you can learn about in [Distributed Tracing](/product/performance/distributed-tracing/). To begin capturing transactions, install the tracing package and set either `tracesSampleRate` or `tracesSampler` in your [SDK configuration](/platforms/javascript/configuration/options/#common-options). These determine what percentage of potential transactions get sent to Sentry; we recommend capturing only a sample, as one way to adjust your overall Sentry volume to meet your needs. Learn more about `tracesSampleRate` and `tracesSampler` in [Sampling Transactions](/performance/sampling).