Performance Monitoring

Learn more about how to configure our Performance integrations to get the best experience out of it.

When integrating Sentry with an Express application, you can leverage provided middlewares to automatically instrument and monitor the performance of your application.

If you’re adopting Performance in a high-throughput environment, we recommend testing prior to deployment to ensure that your service’s performance characteristics maintain expectations.

Copied
const Sentry = require('@sentry/node');
const express = require('express');
const app = express();

Sentry.init({
  dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0',
  integrations: [
    // enable Express.js middleware tracing
    new Sentry.Integrations.Express({
      // to trace all requests to the default router
      app,
      // alternatively, you can specify the routes you want to trace:
      // router: someRouter,
    }),
  ],

  // We recommend adjusting this value in production, or using tracesSampler
  // for finer control
  tracesSampleRate: 1.0,
});

// RequestHandler creates a separate execution context, so that all
// transactions/spans/breadcrumbs are isolated across requests
app.use(Sentry.Handlers.requestHandler());
// TracingHandler creates a trace for every incoming request
app.use(Sentry.Handlers.tracingHandler());

// the rest of your app

// The Sentry error handler middleware must be registered before any other error middleware and after all controllers
app.use(Sentry.Handlers.errorHandler());

app.listen(3000);

You can also manually create transactions in your app:

Copied
const Sentry = require('@sentry/node');
const http = require('http');

const transaction = Sentry.startTransaction({
  op: 'transaction',
  name: 'My Transaction',
});

// Note that we set the transaction as the span on the scope.
// This step makes sure that if an error happens during the lifetime of the transaction
// the transaction context will be attached to the error event
Sentry.getCurrentScope().setSpan(transaction);

let request;

try {
  // this should generate an http span
  request = http.get('http://sentry.io', res => {
    console.log(`STATUS: ${res.statusCode}`);
    console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
  });

  // this error event should have trace context
  foo();
} catch (err) {
  Sentry.captureException(err);
}

request.on('close', () => {
  transaction.finish();
});

To 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:

Copied
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();
  });
});

In cases where you want to attach Spans to an already ongoing Transaction you can use Sentry.getActiveTransaction(). 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:

Copied
app.get('/success', function successHandler(req, res) {
  const transaction = Sentry.getActiveTransaction();

  if (transaction) {
    let span = transaction.startChild({
      op: 'encode',
      description: 'parseAvatarImages',
    });
    // Do something
    span.finish();
  }
  res.status(200).end();
});
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").