Serverless Cloud

Add @sentry/node as a dependency:

Copied
cloud install @sentry/node

Sentry should be initialized as early in your app as possible:

Copied
import api from "@serverless/cloud";
import * as Sentry from "@sentry/node";

// or using CommonJS
// const api = require("@serverless/cloud");
// const Sentry = require('@sentry/node');

Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  // or pull from params
  // dsn: params.SENTRY_DSN,
  environment: params.INSTANCE_NAME,
});

// The request handler must be the first middleware on the app
api.use(Sentry.Handlers.requestHandler());

// All controllers should live here
api.get("/", function rootHandler(req, res) {
  res.end("Hello world!");
});

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

// Optional fallthrough error handler
api.use(function onError(err, req, res, next) {
  // The error id is attached to `res.sentry` to be returned
  // and optionally displayed to the user for support.
  res.statusCode = 500;
  res.end(res.sentry + "\n");
});

You can verify the Sentry integration by creating a route that will throw an error:

Copied
api.get("/debug-sentry", function mainHandler(req, res) {
  throw new Error("My first Sentry error!");
});

requestHandler accepts some options that let you decide what data should be included in the event sent to Sentry.

Possible options are:

Copied
// keys to be extracted from req
request?: boolean | string[]; // default: true = ['cookies', 'data', 'headers', 'method', 'query_string', 'url']

// server name
serverName?: boolean; // default: true

// generate transaction name
//   path == request.path (eg. "/foo")
//   methodPath == request.method + request.path (eg. "GET|/foo")
//   handler == function name (eg. "fooHandler")
transaction?: boolean | 'path' | 'methodPath' | 'handler'; // default: true = 'methodPath'

// keys to be extracted from req.user
user?: boolean | string[]; // default: true = ['id', 'username', 'email']

// client ip address
ip?: boolean; // default: false

// node version
version?: boolean; // default: true

// timeout for fatal route errors to be delivered
flushTimeout?: number; // default: undefined

For example, if you want to skip the server name and add just user, you would use requestHandler like this:

Copied
api.use(
  Sentry.Handlers.requestHandler({
    serverName: false,
    user: ["email"],
  })
);

By default, errorHandler will capture only errors with a status code of 500 or higher. If you want to change it, provide it with the shouldHandleError callback, which accepts middleware errors as its argument and decides, whether an error should be sent or not, by returning an appropriate boolean value.

Copied
api.use(
  Sentry.Handlers.errorHandler({
    shouldHandleError(error) {
      // Capture all 404 and 500 errors
      if (error.status === 404 || error.status === 500) {
        return true;
      }
      return false;
    },
  })
);

Monitor Performance

Copied
const Sentry = require("@sentry/node");
const api = require("@serverless/cloud");

Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  // or pull from params
  // dsn: params.SENTRY_DSN,
  integrations: [
    // enable HTTP calls tracing
    new Sentry.Integrations.Http({ tracing: true }),
    // enable Express.js middleware tracing
    new Sentry.Integrations.Express({
      // to trace all requests to the default router
      api,
      // alternatively, you can specify the routes you want to trace:
      // router: someRouter,
    }),
    // Automatically instrument Node.js libraries and frameworks
    ...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(),
  ],

  // We recommend adjusting this value in production, or using tracesSampler
  // for finer control
  tracesSampleRate: 1.0,
  // or pull from params
  // tracesSampleRate: parseFloat(params.SENTRY_TRACES_SAMPLE_RATE),
});

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

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)
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) to suggesting an update ("yeah, this would be better").