Sentry logo

Backstage Sentry Plugin

Created by Spotify

Sentry is an error tracking and performance tool. It shows you where your code fails in production. It helps you spot trends and fix issues faster.

The Sentry plugin brings that signal into Backstage. It adds a summary card that surfaces recent issues for each catalog entity. You can open a full page to explore error counts, last seen times, and links back to Sentry for deep dives. This keeps triage in the same place where your teams work. It reduces context switches during incidents and daily reviews. You can sort issues, focus on a time window, and see activity across services without leaving your portal. ()

Many teams use Backstage with Sentry today. Stilingue describes their setup as centralization of metrics from Grafana, Sentry and GCP.

The plugin fits common use cases. During an incident you can jump from a failing service to its current Sentry issues. During on call handoff you can scan the most active problems for your team. During a postmortem you can review how an error trended before and after a fix. Platform teams can go further by pairing the UI with Backstage templates that create Sentry projects as part of new service scaffolding. This helps standardize monitoring from day one while keeping ownership clear.

A screenshot of the Sentry plugin. It is showing a list of errors.

Installation Instructions

These instructions apply to self-hosted Backstage only. To use this plugin on Roadie, visit the docs.

Install the frontend package

Copy
# from your Backstage root directory
yarn --cwd packages/app add @backstage-community/plugin-sentry

Add the Sentry UI to the classic frontend

Copy
// packages/app/src/components/catalog/EntityPage.tsx

import React from 'react';
import { Grid } from '@material-ui/core';
import {
  EntitySentryCard,
  EntitySentryContent,
} from '@backstage-community/plugin-sentry';

const overviewContent = (
  <Grid container spacing={3} alignItems="stretch">
    {/* other cards */}
    <Grid item xs={12} sm={6} md={4}>
      <EntitySentryCard />
    </Grid>
    {/* other cards */}
  </Grid>
);

// optional full page Sentry tab
// add inside your EntityLayout
/*
<EntityLayout.Route path="/sentry" title="Sentry">
  <EntitySentryContent />
</EntityLayout.Route>
*/

Add the Sentry UI to the new frontend system

Copy
// packages/app/src/App.tsx

import { createApp } from '@backstage/frontend-app-api';
// alpha export of the Sentry plugin
import sentryPlugin from '@backstage-community/plugin-sentry/alpha';

const app = createApp({
  features: [
    // other features
    sentryPlugin,
  ],
});

export default app.createRoot();

Configure the proxy in app config

Copy
# app-config.yaml

proxy:
  '/sentry/api':
    target: https://sentry.io/api/
    allowedMethods: ['GET']
    headers:
      Authorization: Bearer ${SENTRY_TOKEN}

sentry:
  organization: your organization slug
Copy
# set the token for local dev
export SENTRY_TOKEN=your_sentry_token

Enable the proxy in the old backend system

If your backend already serves the proxy path at /proxy you can skip this change.

Add the proxy backend package

Copy
yarn --cwd packages/backend add @backstage/plugin-proxy-backend

Wire it up

Copy
// packages/backend/src/index.ts

import { createServiceBuilder } from '@backstage/backend-common';
import { Router } from 'express';
import proxy from '@backstage/plugin-proxy-backend'; // default export in classic backend

async function main() {
  const apiRouter = Router();

  // other backend plugins
  apiRouter.use('/proxy', await proxy({ logger, config, discovery, tokenManager }));

  const service = createServiceBuilder(module)
    .setPort(7007)
    .addRouter('/api', apiRouter);

  await service.start();
}

main().catch(err => {
  process.exit(1);
});

If your project uses the plugin environment helpers, keep using them the same way where you mount other classic plugins, then mount /proxy at the api router

Copy
// example if you use plugin env helpers

import proxy from '@backstage/plugin-proxy-backend';

apiRouter.use('/proxy', await proxy(proxyEnv));

Enable the proxy in the new backend system

If your backend already includes the proxy module you can skip this change.

Add the proxy backend package

Copy
yarn --cwd packages/backend add @backstage/plugin-proxy-backend

Register the module

Copy
// packages/backend/src/index.ts

import { createBackend } from '@backstage/backend-defaults';
import { proxyModule } from '@backstage/plugin-proxy-backend';

const backend = createBackend();

// other modules
backend.add(proxyModule());

backend.start();

Create the Sentry token

  • In Sentry create an internal integration
  • Grant Issues and Events Read
  • Use that token in the SENTRY_TOKEN env var

Annotate your entities

Add the Sentry annotation to each catalog entity that should show Sentry issues. You can use only the project slug or org /project

Copy
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: my service
  annotations:
    sentry.io/project-slug: your org or project slug here
spec:
  type: service
  owner: team
  lifecycle: production

Optional mock data for local testing

Copy
// packages/app/src/apis.ts

import { createApiFactory } from '@backstage/core-plugin-api';
import {
  MockSentryApi,
  sentryApiRef,
} from '@backstage-community/plugin-sentry';

export const apis = [
  createApiFactory(sentryApiRef, new MockSentryApi()),
];

With the new frontend system you can override the api inside App.tsx

Copy
// packages/app/src/App.tsx

import { createApp } from '@backstage/frontend-app-api';
import {
  createApiFactory,
  createExtensionOverrides,
  ApiBlueprint,
} from '@backstage/frontend-plugin-api';
import {
  MockSentryApi,
  sentryApiRef,
} from '@backstage-community/plugin-sentry';
import sentryPlugin from '@backstage-community/plugin-sentry/alpha';

const sentryMockApi = ApiBlueprint.make({
  name: 'sentry',
  params: {
    factory: createApiFactory({
      api: sentryApiRef,
      deps: {},
      factory: () => new MockSentryApi(),
    }),
  },
});

const app = createApp({
  features: [
    sentryPlugin,
    createExtensionOverrides({
      extensions: [sentryMockApi],
    }),
  ],
});

export default app.createRoot();

Things to Know

The Backstage backend must have access to a SENTRY_TOKEN API key environment variable.

To get an API key, first create an internal application in the Sentry UI. Do this at the organization level, rather than the personal level.

Give your application a name and a Webhook URL, then be sure to give the ability to read issues and projects. These will be displayed in Backstage so it’s important that the plugin can access them.

Creating an internal application in the Sentry UI

Once you have an internal application, you can create a token. Run the Backstage backend with this token.

Copy
env SENTRY_TOKEN=123abc yarn start

Changelog

This changelog is produced from commits made to the Sentry plugin since a year ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.

Features

  • Hide Sentry cards when the required annotation is missing. Use the new front end system filter support. This removes empty states on entities without the annotation. #2020 10 months ago

Documentation

  • Update Sentry docs to remove app config steps. The new front end system auto discovers entity content and cards. #2020 10 months ago

Maintenance

  • Remove unused dev dependency canvas. #3565 6 months ago
  • Reduce knip false positives by using a single workspace config through repo tools update. #3018 7 months ago
  • Remove API extractor resolution from package json. No longer needed since Backstage 1.32.0. #1709 11 months ago

Breaking changes

  • None

Set up Backstage in minutes with Roadie