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
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
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
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
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
// 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
<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
<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
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
// 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
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
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
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
// the plugin expects these
{ logger, config, discovery, auth }
Optional custom queries from app config
Define queries in app-config.local.yaml
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
<EntityDqlQueryCard
title="My Custom Query Results"
queryId="custom.my-custom-query"
/>
You can use placeholders in queries. Use two dollar signs in app-config
filter backstageComponent == "$${componentNamespace}.$${componentName}"
Optional custom queries from catalog info on the entity
Add queries to the entity in catalog info
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
<EntityCatalogInfoQueryCard />
You can limit an entity query to specific environments
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
<EntityDqlQueryCard
title="Site Reliability Guardian Validations"
queryId="dynatrace.srg-validations"
/>
You can filter guardians using tags on the entity
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
LOG_QUERY=true yarn dev
Optional proxy for corporate networks
Set HTTPS proxy environment variable for backend process
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
Focus on using Backstage, rather than building and maintaining it.