Getting Started

After this quick setup, you’ll have access to Performance and Discover. These tools will empower you to see everything from macro-level metrics to micro-level spans, but you’ll be able to cross-reference transactions with related issues, customize queries based on your personal needs, and substantially more.

Install and Configure an SDK

To get started with performance monitoring using Sentry’s JavaScript SDK, first install the @sentry/browser and @sentry/apm packages:

# Using yarn
$ yarn add @sentry/browser @sentry/apm

# Using npm
$ npm install @sentry/browser @sentry/apm

Alternatively, instead of npm packages, you can use our pre-built CDN bundle that combines both @sentry/browser and @sentry/apm:

<script src="https://browser.sentry-cdn.com/5.19.1/bundle.apm.min.js" integrity="sha384-qcuJnBVywcOnVTsYC4W46ENmLFtgTt1rojscXpw6pgE6BDJ+MSj3AgdT897AgysN" crossorigin="anonymous"></script>

Next, initialize the integration in your call to Sentry.init:

import * as Sentry from '@sentry/browser';
import { Integrations as ApmIntegrations } from '@sentry/apm';
Sentry.init({
  dsn: '___PUBLIC_DSN___',
  release: 'my-project-name@' + process.env.npm_package_version,
  integrations: [
    new ApmIntegrations.Tracing(),
  ],
  tracesSampleRate: 0.25, // must be present and non-zero
});

Performance data is transmitted using a new event type called “transactions,” which you can learn about in Distributed Tracing. To capture transactions, you must install the performance package and configure your SDK to set the tracesSampleRate configuration to a nonzero value. The example configuration above will transmit 25% of captured transactions.

Learn more about sampling in Using Your SDK to Filter Events.

Automatic Instrumentation

For @sentry/browser, we provide an integration called Tracing that does automatic instrumentation in the browser. The Tracing integration creates pageload and navigation transactions containing spans for XHR/fetch requests and Performance API entries such as marks, measures, and resource timings.

The Tracing integration is specific to @sentry/browser and does not work with @sentry/node.

The Tracing integration resides in the @sentry/apm package. You can add it to your Sentry.init call:

// Without CDN

import * as Sentry from '@sentry/browser';
import { Integrations as ApmIntegrations } from '@sentry/apm';

Sentry.init({
  dsn: '___PUBLIC_DSN___',
  integrations: [
    new ApmIntegrations.Tracing(),
  ],
  tracesSampleRate: 0.25,
});

// With CDN

Sentry.init({
  dsn: '___PUBLIC_DSN___',
  integrations: [
    new ApmIntegrations.Tracing(),
  ],
  tracesSampleRate: 0.25,
});

NOTE: The Tracing integration is available under Sentry.Integrations.Tracing when using the CDN bundle.

To send traces, you will need to set the tracesSampleRate to a nonzero value. The configuration above will capture 25% of your transactions.

By default, the pageload and navigation transactions set a transaction name using window.location.pathname.

You can pass many different options to the Tracing 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.

tracingOrigins Option

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.

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 ApmIntegrations.Tracing({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 this depends a lot on your setup. If you do not allow the sentry-trace header, the request might be blocked.

beforeNavigation Options

(New in version 5.18.0)

For pageload and navigation transactions, the Tracing 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 beforeNavigation option to the Tracing 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.

beforeNavigation 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.

import * as Sentry from '@sentry/browser';
import { Integrations as ApmIntegrations } from '@sentry/apm';
Sentry.init({
  dsn: '___PUBLIC_DSN___',
  integrations: [
    new ApmIntegrations.Tracing({
      beforeNavigate: location => {
        // Here we are doing some basic parameter replacements, but we recommend
        // using your UI's routing library to find the matching route template here
        return location.pathname
          .replace(/\d+/g, '<digits>')
          .replace(/[a-f0-9]{32}/g, '<hash>');
      },
    }),
  ],
  tracesSampleRate: 0.25,
});

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 Tracing integration.

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:

// 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');

  // 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.

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

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.

An example of doing this in a node.js application:

import { addGlobalEventProcessor } from '@sentry/node';

addGlobalEventProcess(event => {
  // if event is a transaction event
  if (event.type === "transaction") {
	event.transaction = sanitizeTransactionName(event.transaction);
  }
  return event;
});

For browser JavaScript applications using the Tracing integration, the beforeNavigate option can be used to better group navigation/pageload transactions together based on URL.

import * as Sentry from '@sentry/browser';
import { Integrations as ApmIntegrations } from '@sentry/apm';

Sentry.init({
	// ...
  integrations: [
    new ApmIntegrations.Tracing({
      beforeNavigate: (location) => {        
        // 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.
        return location.pathname
        .replace(/\d+/g, '<digits>')
        .replace(/[a-f0-9]{32}/g, '<hash>');
      },
    }),
  ],
});

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 otherwise it returns undefined. If you are using our Tracing integration by default we attach the Transaction to the Scope. So you could do something like this:

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.setTag splits the details of this request over several tags. This could be done over baseUrl, endpoint, parameters, in this case, resulting in three different tags:

const span = transaction.startChild({
  op: "request",
  description: "setup form"
});
span.setTag("baseUrl", baseUrl);
span.setTag("endpoint", endpoint);
span.setTag("parameters", parameters);
http.get(`${base_url}/${endpoint}/`, data=parameters);
baseUrl

https://empowerplant.io

endpoint

api/0/projects/ep/setup_form

parameters
  {
      "user_id": 314159265358979323846264338327,
      "tracking_id": "EasyAsABC123OrSimpleAsDoReMi",
      "product_name": "PlantToHumanTranslator",
      "product_id": 161803398874989484820458683436563811772030917980576,
  }

Koa

To get started with performance monitoring with Koa, first install these packages:

# Using yarn
$ yarn add @sentry/node @sentry/apm

# Using npm
$ npm install @sentry/node @sentry/apm

Creates and attach a transaction to each context

const Sentry = require('@sentry/node')
const { Span } = require('@sentry/apm')
const Koa = require('koa')
const app = new Koa()
const domain = require('domain')

Sentry.init({
  dsn: "___PUBLIC_DSN___",
  tracesSampleRate: 0.25
})

// not mandatory, but adding domains do help a lot with breadcrumbs
const requestHandler = (ctx, next) => {
  return new Promise((resolve, reject) => {
    const local = domain.create()
    local.add(ctx)
    local.on('error', (err) => {
      ctx.status = err.status || 500
      ctx.body = err.message
      ctx.app.emit('error', err, ctx)
    })
    local.run(async() => {
      Sentry.getCurrentHub().configureScope(scope =>
        scope.addEventProcessor((event) => Sentry.Handlers.parseRequest(event, ctx.request, {user: false}))
      )
      await next()
      resolve()
    })
  })
}

// 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
    if (sentryTraceId) {
      const span = Span.fromTraceparent(sentryTraceId)
      if (span) {
        traceId = span.traceId
        parentSpanId = span.parentSpanId
      }
    }
    const transaction = Sentry.startTransaction({
      name: `${ctx.method} ${ctx.url}`,
      op: 'http.server',
      parentSpanId,
      traceId,
    })
    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.setHttpStatus(ctx.status)
    transaction.finish()
}

app.use(requestHandler)
app.use(tracingMiddleWare)

// usual error handler
app.on('error', (err, ctx) => { 
  Sentry.withScope(function (scope) {
    scope.addEventProcessor(function (event) {
      return Sentry.Handlers.parseRequest(event, ctx.request)
    })
    Sentry.captureException(err)
  })
})
// the rest of your app

Subsequent manual child transactions

The following example creates a transaction for a part of the code that contains an expensive operation, and sends the result to Sentry, you will need to use the transaction stored in the context

const myMiddleware = async (ctx, next) => {
  let span
  const transaction = ctx.__sentry_transaction
  if (transaction) {
    span = transaction.startChild({
      description: route,
      op: 'myMiddleware',
    })
  }
  await myExpensiveOperation()
  if (span) {
    span.finish()
  }
  return next()
}

Node

To get started with performance monitoring with Node.js, first install these packages:

# Using yarn
$ yarn add @sentry/node @sentry/apm

# Using npm
$ npm install @sentry/node @sentry/apm

Sending Traces

To send traces, set the tracesSampleRate to a nonzero value. The following configuration will capture 25% of all your transactions:

const Sentry = require("@sentry/node");

// This is required since it patches functions on the hub
const Apm = require("@sentry/apm"); 

Sentry.init({
  dsn: "___PUBLIC_DSN___",
  tracesSampleRate: 0.25
});

Automatic Instrumentation

It’s possible to add tracing to all popular frameworks; however, we only provide pre-written handlers for Express.

const Sentry = require("@sentry/node");
const Apm = require("@sentry/apm");
const express = require("express");
const app = express();

Sentry.init({
  dsn: "___PUBLIC_DSN___",
  integrations: [
      // enable HTTP calls tracing
      new Sentry.Integrations.Http({ tracing: true }),
      // enable Express.js middleware tracing
      new Apm.Integrations.Express({ app })
  ],
  tracesSampleRate: 0.25
});

// RequestHandler creates a separate execution context using domains, so that every 
// transaction/span/breadcrumb is attached to its own Hub instance
app.use(Sentry.Handlers.requestHandler());
// TracingHandler creates a trace for every incoming request
app.use(Sentry.Handlers.tracingHandler());

// the rest of your app

app.use(Sentry.Handlers.errorHandler());
app.listen(3000);

Spans are instrumented for the following operations within a transaction:

  • HTTP requests made with request
  • get calls using native http and https modules
  • Middleware (Express.js only)

Manual Instrumentation

To manually instrument a specific region of your code, you can create a transaction to capture it.

The following example creates a transaction for a part of the code that contains an expensive operation (for example, processItem), and sends the result to Sentry:

app.use(function processItems(req, res, next) {
  const item = getFromQueue();
  const transaction = Sentry.startTransaction({
      op: "task",  
      name: item.getTransaction()
  })

  // processItem may create more spans internally (see next examples)
  processItem(item, transaction).then(() => {
      transaction.finish();
      next();
  })
});

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 otherwise it returns undefined. If you are using our Express integration by default we attach the Transaction to the Scope. So you could do something like this:

app.get("/success", function successHandler(req, res) {
  const transaction = Sentry.getCurrentHub().getScope().getTransaction();
  if (transaction) {
    let span = transaction.startChild({
      op: "encode",
      description: "parseAvatarImages"
    });
    // Do something
    span.finish();
  }
  res.status(200).end();
});

To get started with performance monitoring using Sentry’s Python SDK, first install sentry_sdk:

import sentry_sdk

Next, initialize the integration in your call to sentry_sdk.init:

sentry_sdk.init(
    "___PUBLIC_DSN___", 
    traces_sample_rate = 0.25
)

Performance data is transmitted using a new event type called “transactions,” which you can learn about in Distributed Tracing. To capture transactions, you must install and configure your SDK to set the tracesSampleRate configuration to a nonzero value. The example configuration above will transmit 25% of captured traces.

Learn more about sampling in Using Your SDK to Filter Events.

Python

To send traces, set the traces_sample_rate to a nonzero value. The following configuration will capture 25% of your transactions:

import sentry_sdk

sentry_sdk.init(
    "___PUBLIC_DSN___", 
    traces_sample_rate = 0.25
)

Automatic Instrumentation

Many integrations for popular frameworks automatically capture transactions. If you already have any of the following frameworks set up for Sentry error reporting, you will start to see traces immediately:

  • All WSGI-based web frameworks (Django, Flask, Pyramid, Falcon, Bottle)
  • Celery
  • AIOHTTP web apps
  • Redis Queue (RQ)

Spans are instrumented for the following operations within a transaction:

  • Database queries that use SQLAlchemy or the Django ORM
  • HTTP requests made with requests or the stdlib
  • Spawned subprocesses
  • Redis operations

If you want to automatically enable all relevant transactions, you can use this alternative configuration (currently in alpha):

import sentry_sdk

sentry_sdk.init(
    "___PUBLIC_DSN___",
    _experiments={"auto_enabling_integrations": True}
)

Manual Instrumentation

To manually instrument certain regions of your code, you can create a transaction to capture them.

The following example creates a transaction for a scope that contains an expensive operation (for example, process_item), and sends the result to Sentry:

from sentry_sdk import start_transaction

while True:
  item = get_from_queue()

  with start_transaction(op="task", name=item.get_transaction_name()):
      # process_item may create more spans internally (see next examples)
      process_item(item)

Adding More Spans to the Transaction

The next example contains the implementation of the hypothetical process_item function called from the code snippet in the previous section. Our SDK can determine if there is currently an open transaction and add all newly created spans as child operations to that transaction. Keep in mind that each individual span also needs to be manually finished; otherwise, spans will not show up in the transaction. When using spans and transactions as context managers, they are automatically finished at the end of the with block.

In cases where you want to attach Spans to an already ongoing Transaction you can use Hub.current.scope.transaction. This property will return a Transaction in case there is a running Transaction otherwise it returns None.

Alternatively, instead of adding to the top-level transaction, you can make a child span of the current span, if there is one. Use ``Hub.current.scope.span` in that case.

You can choose the value of op and description.

from sentry_sdk import Hub

def process_item(item):
    transaction = Hub.current.scope.transaction
    # omitted code...
    with transaction.start_child(op="http", description="GET /") as span:
        response = my_custom_http_library.request("GET", "/")
        span.set_tag("http.status_code", response.status_code)
        span.set_data("http.foobarsessionid", get_foobar_sessionid())

The alternative to make a tree of spans:

from sentry_sdk import Hub

def process_item(item):
    parent_span = Hub.current.scope.span
    # omitted code...
    with parent_span.start_child(op="http", description="GET /") as span:
        response = my_custom_http_library.request("GET", "/")
        span.set_tag("http.status_code", response.status_code)
        span.set_data("http.foobarsessionid", get_foobar_sessionid())

Retrieving a Transaction

In cases where you want to attach Spans to an already ongoing Transaction you can use Hub.current.scope.transaction. This property will return a Transaction in case there is a running Transaction otherwise it returns None.

from sentry_sdk import Hub

transaction = Hub.current.scope.transaction

if transaction is None:
    with start_transaction(name="task"):
        do_task()
else:
    transaction.name = "new name"
    with transaction.start_child(op="task"):
        do_task()

Retrieving the current Span

Started spans are stored in the scope, and can be fetched off the scope:

from sentry_sdk import Hub

span = Hub.current.scope.span

if span is None:
    # no span in progress, create new transaction
    with start_transaction(name="task"):
        do_task()
else:
    # new task span as child of current span
    with span.start_child(op="task"):
        do_task()

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 splits the details of this query over several tags. This could be done over base_url, endpoint, parameters, in this case, resulting in three different tags:

import sentry_sdk
...
with sentry_sdk.start_transaction(op="request", name="setup form") as transaction:
    transaction.set_tag("base_url", base_url)
    transaction.set_tag("endpoint", endpoint)
    transaction.set_tag("parameters", parameters)
    make_request(
        "{base_url}/{endpoint}/".format(
            base_url=base_url,
            endpoint=endpoint,
        ),
        data=parameters
    )
    ...
base_url

https://empowerplant.io

endpoint

api/0/projects/ep/setup_form

parameters
  {
      "user_id": 314159265358979323846264338327,
      "tracking_id": "EasyAsABC123OrSimpleAsDoReMi",
      "product_name": "PlantToHumanTranslator",
      "product_id": 161803398874989484820458683436563811772030917980576,
  }

React

To get started with performance monitoring using Sentry’s React SDK, first install the @sentry/react and @sentry/apm packages:

# Using yarn
$ yarn add @sentry/react @sentry/apm

# Using npm
$ npm install @sentry/react @sentry/apm

Next, initialize the integration in your call to Sentry.init. Make sure this happens before you mount your React component on the page.

import * as Sentry from '@sentry/react';
import { Integrations } from "@sentry/apm";
Sentry.init({
  dsn: '___PUBLIC_DSN___',
  release: 'my-project-name@' + process.env.npm_package_version,
  integrations: [
    new Integrations.Tracing(),
  ],
  tracesSampleRate: 0.25, // must be present and non-zero
});

// ...

ReactDOM.render(<App />, rootNode);

// Can also use with React Concurrent Mode
// ReactDOM.createRoot(rootNode).render(<App />);

withProfiler Higher-Order Component

@sentry/react exports a withProfiler higher-order component that leverages the @sentry/apm Tracing integration to add React related spans to transactions. If the Tracing integration is not enabled, the Profiler will not work.

In the example below, the withProfiler higher-order component is used to instrument an App component.

import React from 'react';
import * as Sentry from '@sentry/react';

class App extends React.Component {
  render() {
    return (
      <FancyComponent>
        <NestedComponent someProp={2} />
        <AnotherComponent />
      </FancyComponent>
    )
  }
}

export default Sentry.withProfiler(App);

The React Profiler currently generates spans with three different kinds of op-codes: react.mount, react.render, and react.update.

react.mount

The span that represents how long it took for the profiled component to mount.

react.render

The span that represents how long the profiled component was on a page. This span is only generated if the profiled component mounts and unmounts while a transaction is occurring.

react.update

The span that represents when the profiled component updated. This span is only generated if the profiled component has mounted.

The withProfiler higher-order component has a variety of options for further customization. They can be passed in as the second argument to the withProfiler function.

export default Sentry.withProfiler(App, { name: "CustomAppName" })
name (string)

The name of the component being profiled. By default, the name is taken from the component displayName property or the component name property.

includeRender (boolean)

If a react.render span should be created by the Profiler. Set as true by default.

includeUpdates (boolean)

If react.update spans should be created by the Profiler. Set as true by default. We recommend setting this prop as false for components that will experience many rerenders, such as text input components, as the resulting spans can be very noisy.

Vue.js

To get started with performance monitoring with Vue.js, first install these packages:

# Using yarn
$ yarn add @sentry/browser @sentry/integrations @sentry/apm

# Using npm
$ npm install @sentry/browser @sentry/integrations @sentry/apm

The Vue Tracing Integration allows you to track rendering performance during an initial application load.

Sentry injects a handler inside Vue’s beforeCreate mixin, providing access to a Vue component during its life cycle stages. When Sentry encounters a component named root, which is a top-level Vue instance (as in new Vue({})), we use our AM Tracing integration, and create a new activity named Vue Application Render. Once the activity has been created, it will wait until all of its child components render, and there aren’t new rendering events triggered within the configured timeout, before marking the activity as completed.

The described instrumentation functionality will give you very high-level information about the rendering performance of the Vue instance. However, the integration can also provide more fine-grained details about what actually happened during a specific activity. To do that, you need to specify which components to track and what hooks to listen to (you can find a list of all available hooks here). You can also turn on tracking for all the components. However, it may be rather noisy if your app consists of hundreds of components. We encourage being more specific. If you don’t provide hooks, Sentry will track a component’s mount and update hooks.

Note that we don’t use before and -ed pairs for hooks, and you should provide a simple verb instead. For example, update is correct. beforeUpdate and updated are incorrect.

To set up the Vue Tracing Integration, you will first need to configure the AM Tracing integration itself. For details on how to do this, see the JavaScript section above. Once you’ve configured the Tracing integration, move on to configuring the Vue integration itself. Sentry built the new tracing capabilities into the original Vue error handler integrations, so there is no need to add any new packages. You only need to provide an appropriate configuration.

The most basic configuration for tracing your Vue app, which would track only the top-level component, looks like this:

import * as Sentry from "@sentry/browser";
import { Vue as VueIntegration } from "@sentry/integrations";
import { Integrations } from "@sentry/apm";
import Vue from "vue";

Sentry.init({
  // ...
  integrations: [
    new Integrations.Tracing(),
    new VueIntegration({
      Vue,
      tracing: true
    })
  ],
  tracesSampleRate: 1
});

If you want to track child components, and see more details about the rendering process, configure the integration to track them all:

new VueIntegration({
  Vue,
  tracing: true,
  tracingOptions: {
    trackComponents: true
  }
})

Or, you can choose more granularity:

new VueIntegration({
  Vue,
  tracing: true,
  tracingOptions: {
    trackComponents: ["App", "RwvHeader", "RwvFooter", "RwvArticleList", "Pagination"]
  }
})

If you want to know if some components are, for example, removed during the initial page load, add a destroy hook to the default:

new VueIntegration({
  Vue,
  tracing: true,
  tracingOptions: {
    trackComponents: ["App", "RwvHeader", "RwvFooter", "RwvArticleList", "Pagination"],
    hooks: ['mount', 'update', 'destroy']
  }
})

You can specify how long a top-level activity should wait for the last component to render. Every new rendering cycle is debouncing the timeout, and it starts counting from the beginning. Once the timeout is reached, tracking is completed, and all the information is sent to Sentry.

new VueIntegration({
  Vue,
  tracing: true,
  tracingOptions: {
    trackComponents: true,
    timeout: 4000
  }
})

Configuration

/**
 * When set to `true`, enables tracking of components lifecycle performance.
 * Default: false
 */
tracing: boolean;
tracingOptions: {
  /**
   * Decides whether to track components by hooking into its lifecycle methods.
   * Can be either set to `boolean` to enable/disable tracking for all of them.
   * Or to an array of specific component names (case-sensitive).
   * Default: false
   */
  trackComponents: boolean | string[];
  /**
   * How long to wait (in ms) until the tracked root activity is marked as finished and sent to Sentry
   * Default: 2000
   */
  timeout: number;
  /**
   * List of hooks to keep track of during component lifecycle.
   * Available hooks: 'activate' | 'create' | 'destroy' | 'mount' | 'update'
   * Based on https://vuejs.org/v2/api/#Options-Lifecycle-Hooks
   */
  hooks: string[];
}