Dynatrace logo

Backstage Dynatrace Plugin

Created by Dynatrace

Dynatrace is an observability and security platform. It helps teams see how services behave across metrics logs traces and events. The goal is simple. Faster insight and fewer blind spots during build test and production.

The Dynatrace Backstage plugin brings that data into your Backstage catalog. It queries Dynatrace with DQL and shows results in clean tables. Each row can link back to the right Dynatrace app view for deeper analysis. Out of the box you get Kubernetes deployment overviews with direct links. You can define custom queries for logs problems and security findings. You can point queries at more than one Dynatrace environment to compare stages like development hardening and production. You can also surface Site Reliability Guardian validation results to keep quality gates visible where engineers work.

Teams already use this in the wild. Dynatrace runs it in their own Backstage portal to give developers live context. In their words Backstage is a crucial element for Dynatrace’s developer experience.

As a short summary from the product page this line captures the intent. “Provide context rich observability security and quality insights in Backstage.”

Installation Instructions

These instructions apply to self-hosted Backstage only.

Add the packages

Copy
yarn --cwd packages/app add @dynatrace/backstage-plugin-dql
yarn --cwd packages/backend add @dynatrace/backstage-plugin-dql-backend
yarn --cwd packages/backend add @dynatrace/backstage-plugin-dql-common

Configure Dynatrace connection

Create or update app-config.local.yaml

Copy
dynatrace:
  environments:
    - name: xxxxxxxx
      url: https://xxxxxxxx.apps.dynatrace.com
      tokenUrl: https://sso.dynatrace.com/sso/oauth2/token
      accountUrn: <accountUrn>
      clientId: <clientId>
      clientSecret: <clientSecret>

You can add more environments if you need

Copy
dynatrace:
  environments:
    - name: xxxxxxxx
      url: https://xxxxxxxx.apps.dynatrace.com
      tokenUrl: https://sso.dynatrace.com/sso/oauth2/token
      accountUrn: <accountUrn>
      clientId: <clientId>
      clientSecret: <clientSecret>
    - name: yyyyyyyy
      url: https://yyyyyyyy.apps.dynatrace.com
      tokenUrl: https://sso.dynatrace.com/sso/oauth2/token
      accountUrn: <accountUrn>
      clientId: <clientId>
      clientSecret: <clientSecret>

Wire up the frontend plugin

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

Import the cards

Copy
import {
  EntityDqlQueryCard,
  EntityKubernetesDeploymentsCard,
  EntityCatalogInfoQueryCard,
} from '@dynatrace/backstage-plugin-dql';

Add at least one card to an entity page so users can see the data. For example add a card to the overview content of a service page

Copy
// inside your existing EntityPage layout
<Grid item xs={12} md={6} lg={6}>
  <EntityDqlQueryCard
    title="Kubernetes Deployments"
    queryId="dynatrace.kubernetes-deployments"
  />
</Grid>

Optional Kubernetes focused card

Copy
<Grid item xs={12} md={6} lg={6}>
  <EntityKubernetesDeploymentsCard
    title="Show me my Kubernetes deployments"
    queryId="dynatrace.kubernetes-deployments"
  />
</Grid>

Optional card that renders all queries defined on the entity in catalog info

Copy
<Grid item xs={12} md={12} lg={12}>
  <EntityCatalogInfoQueryCard />
</Grid>

Register the backend with the new backend system

Open packages/backend/src/index.ts

Add the backend plugin

Copy
import { createBackend } from '@backstage/backend-defaults';

const backend = createBackend();

backend.add(import('@dynatrace/backstage-plugin-dql-backend'));

backend.start();

The plugin provides its own router and registers its endpoints during init

Copy
// internal pattern used by the plugin
env.registerInit({
  deps: { logger, config, discovery, http, auth },
  async init({ http, config, logger, discovery, auth }) {
    http.use(await createRouter({ config, logger, discovery, auth }));
  },
});

The service exposes endpoints like

Copy
GET /api/dql/catalog
GET /api/dql/custom/:queryId
GET /api/dql/dynatrace/:queryId

Register the backend with the legacy backend system

If your backend uses the old express app pattern, mount the router yourself

Create a helper file packages/backend/src/plugins/dynatraceDql.ts

Copy
import { Router } from 'express';
import { PluginEnvironment } from '../types';
import { createRouter } from '@dynatrace/backstage-plugin-dql-backend';

export default async function createDynatraceDqlPlugin(
  env: PluginEnvironment,
): Promise<Router> {
  const { logger, config, discovery, auth } = env;
  return await createRouter({ logger, config, discovery, auth });
}

Wire it in packages/backend/src/index.ts

Copy
import dynatraceDql from './plugins/dynatraceDql';

// inside your main bootstrap after app and env are created
const dynatraceDqlRouter = await dynatraceDql(env);
app.use('/api/dql', dynatraceDqlRouter);

The required dependencies for createRouter are provided by the standard backend environment

Copy
// the plugin expects these
{ logger, config, discovery, auth }

Optional custom queries from app config

Define queries in app-config.local.yaml

Copy
dynatrace:
  queries:
    - id: my-custom-query
      query: >
        fetch events | filter event.kind == "DAVIS_EVENT" | fields event.kind, timestamp

Render the result on an entity page

Copy
<EntityDqlQueryCard
  title="My Custom Query Results"
  queryId="custom.my-custom-query"
/>

You can use placeholders in queries. Use two dollar signs in app-config

Copy
filter backstageComponent == "$${componentNamespace}.$${componentName}"

Optional custom queries from catalog info on the entity

Add queries to the entity in catalog info

Copy
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: demo-backstage
  dynatrace:
    queries:
      - id: Error Logs
        description: Fetch Error Logs
        query: >
          fetch logs, from: -2d
            | filter status == "ERROR"
            | sort timestamp desc
            | fieldsAdd environment = "${environmentName}"
            | fieldsKeep timestamp, content, environment
spec:
  type: service
  owner: user:default/guest

Render all entity queries

Copy
<EntityCatalogInfoQueryCard />

You can limit an entity query to specific environments

Copy
metadata:
  dynatrace:
    queries:
      - id: Error Logs
        environments:
          - tenant1
          - tenant2
        query: >
          fetch logs, from: -2d
            | filter status == "ERROR"
            | fieldsAdd environment = "${environmentName}"
            | fieldsKeep timestamp, content, environment

Optional guardian validations

Add a card for site reliability guardian validations

Copy
<EntityDqlQueryCard
  title="Site Reliability Guardian Validations"
  queryId="dynatrace.srg-validations"
/>

You can filter guardians using tags on the entity

Copy
metadata:
  annotations:
    dynatrace.com/guardian-tags: 'service=my-service,stage=development,novalue'

Optional logging of executed DQL

Set an environment variable before starting the backend

Copy
LOG_QUERY=true yarn dev

Optional proxy for corporate networks

Set HTTPS proxy environment variable for backend process

Copy
export HTTPS_PROXY=http://proxy.example.com:8080
yarn dev

Changelog

This changelog is produced from commits made to the Dynatrace plugin since 7 months 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

  • Include SDLC guardian validations in the Site Reliability Guardian table #217 merged 10 days ago
  • Add DQL execution logging via LOG_QUERY env setting #211 merged 1 month ago
  • Use security dot events for vulnerability queries in DQL for better accuracy #208 merged 1 month ago

Bug fixes

  • Fix config schema environments to be an array to remove warnings and avoid exposing secrets in developer tools #202 merged 2 months ago
  • Revert a patch dependency batch to fix an error on the APIs page #222 merged 17 days ago

Breaking changes

  • Upgrade to React 18 across the plugin ecosystem. Host apps need React 18. Tests use the newer React Testing Library. Remove the old React Hooks testing package if present #220 merged 18 days ago
  • Upgrade Backstage to 1 dot 42 dot 5. Remove alpha imports. Use root exports. Tests update. A resolution pins opentelemetry api to 1 dot 9 dot 0 #214 merged 18 days ago
  • Upgrade Scaffolder backend to v2. Imports move to module packages. The old createRouter api is removed. Some permission flows change. Check custom actions and policies #204 merged 24 days ago
  • Upgrade tech radar plugin to v1. The plugin now fetches data from the tech radar backend. Some types move to the common package. Update imports if you use those types #172 merged 2 months ago

Security

  • Scaffolder backend v2 includes a fix for a security advisory that could leak template inputs in logs #204 merged 24 days ago
  • Update permission backend to 0 dot 6 dot 0 to address a security advisory in conditional decisions #189 merged 2 months ago
  • Bump xml crypto to 6 dot 0 dot 1. Addresses CVE 2025 29774 and CVE 2025 29775 #186 merged 3 months ago
  • Bump elliptic to 6 dot 6 dot 1 #179 merged 3 months ago

Documentation

  • Add GitHub Copilot instructions and contributor standards for the DQL plugins and shared packages #215 merged 18 days ago
  • Change a docs link to the correct intent link #181 merged 7 months ago

Maintenance

  • Update patch dependencies across Backstage packages #223 merged 13 days ago
  • Update minor dependencies across the repo #178 merged 17 days ago
  • Apply a patch dependency batch then revert it due to a runtime error #200 merged 17 days ago then reverted by #222 merged 17 days ago
  • Revert an earlier July patch dependency batch #198 merged 2 months ago that reverted #156 merged 2 months ago
  • Split Renovate PRs for Backstage dependencies #183 merged 7 months ago

Notes

  • Some maintenance PRs update many Backstage packages. If your app has custom integrations, verify local builds after updating
  • For security scope updates in Dynatrace, ensure storage security dot events read is granted as shown in the docs changes above

Set up Backstage in minutes with Roadie