dynatrace/dt-migration
Migrate Dynatrace classic and Gen2 entity-based DQL to Smartscape equivalents. Covers three scenarios. (1) mass data queries filtered by classic entity conditions — migrate to direct dimension filters first, Smartscape only as fallback; (2) mass data queries using entity subqueries for filtering — same dimension-first strategy; (3) pure entity list queries — migrate fetch dt.entity.* to smartscapeNodes. Also handles entityName, entityAttr, classicEntitySelector, and classic relationship patterns.
npx skills add https://github.com/Dynatrace/dynatrace-for-ai --skill dt-migration
This skill migrates Dynatrace classic and Gen2 entity-based DQL queries and query patterns to Smartscape-based equivalents.
Load the dt-dql-essentials skill before writing final DQL so the translated query also follows current DQL syntax rules.
This skill focuses on Smartscape-oriented DQL migration only. It does not cover asset-level migration workflows.
Start here. The correct migration strategy depends on what the query is actually trying to do — not just which classic constructs it uses.
There are three distinct situations:
| # | Situation | Classic anti-pattern | Migration strategy |
| --- | --- | --- | --- |
| 1 | Mass data query filtered by entity conditions | classicEntitySelector(...) inline in filter: of a timeseries, logs, or metrics query | Resolve entity conditions to raw data dimensions first. Smartscape is a fallback, not the default. |
| 2 | Mass data query using entity subquery for filtering | fetch dt.entity.* inside in [...], lookup [...], or join [...] to filter the outer mass data query | Same dimension-first strategy. Rewrite as raw dimension filter or in [smartscapeNodes ...] subquery. |
| 3 | Pure entity list query | fetch dt.entity.* used standalone or as the primary result source | smartscapeNodes is the only valid path. No raw dimension alternative exists. |
Decision:
fieldsSnapshot gates — they determine which approach is viable. Only fall back to the Migration Workflow below when the entity-type mapping or relationship traversal is needed to complete a Smartscape subquery.> Note: Situation 3 has a sub-case where classicEntitySelector is used to filter the entities returned by fetch dt.entity.*. This is rare and follows the same smartscapeNodes path — resolve the selector conditions using references/mass-data-filtering-strategy.md Step 1B, then apply them as node filters in smartscapeNodes.
Follow this order for Situation 3 (pure entity list queries) and for constructing Smartscape subqueries in Situations 1 and 2:
fetch dt.entity.*classicEntitySelector(...)belongs_to[...], runs[...], instance_of[...]dt.entity.*smartscapeNodessmartscapeEdgestraversereferencesgetNodeName()getNodeField()For the full migration process and output expectations, load references/migration-workflow.md.
Use this compact table first for common migrations. For the full mapping set, load references/type-mappings.md.
| Classic / Gen2 entity | Smartscape field | Smartscape node type | Notes |
| --- | --- | --- | --- |
| dt.entity.host | dt.smartscape.host | HOST | Standard host mapping |
| dt.entity.service | dt.smartscape.service | SERVICE | Standard service mapping |
| dt.entity.process_group_instance | dt.smartscape.process | PROCESS | Process instance maps directly |
| dt.entity.container_group_instance | dt.smartscape.container | CONTAINER | Container-group instance maps directly |
| dt.entity.kubernetes_cluster | dt.smartscape.k8s_cluster | K8S_CLUSTER | Kubernetes cluster |
| dt.entity.kubernetes_node | dt.smartscape.k8s_node | K8S_NODE | Kubernetes node |
| dt.entity.kubernetes_service | dt.smartscape.k8s_service | K8S_SERVICE | Kubernetes service |
| dt.entity.cloud_application | multiple workload fields | multiple K8S workload node types | Maps to multiple workload types; load the cloud-application guide |
| dt.entity.cloud_application_instance | dt.smartscape.k8s_pod | K8S_POD | Classic cloud app instance becomes pod |
| dt.entity.cloud_application_namespace | dt.smartscape.k8s_namespace | K8S_NAMESPACE | Namespace mapping |
| dt.entity.application | dt.smartscape.frontend | FRONTEND | Frontend application mapping |
| dt.entity.aws_lambda_function | dt.smartscape.aws.lambda_function | AWS_LAMBDA_FUNCTION | Cloud-function entity mapping |
These classic constructs usually need explicit rewriting:
| Classic construct | Typical Smartscape replacement | Notes |
| --- | --- | --- |
| entityName(x) | name or getNodeName(x) | Prefer name when querying nodes directly |
| entityAttr(x, "...") | direct node field or getNodeField(x, "...") | Prefer direct fields when available |
| classicEntitySelector(...) | node filters plus traverse | Start from the constrained side; for mass data queries see mass-data-filtering-strategy.md first |
| dt.entity.* in signal queries | dt.smartscape.* | Applies to by, filter, fieldsAdd, expand, and related clauses |
| belongs_to[...], runs[...], instance_of[...] | traverse or references[...] | references works only for static edges |
| classic entity ID filters | Smartscape id | Do not reuse classic IDs blindly |
| affected_entity_ids and affected_entity_types | smartscape.affected_entity.ids and smartscape.affected_entity.types | Use Smartscape event fields |
For the detailed function-by-function guide, load references/dql-function-migration.md.
Do not translate these patterns literally:
HOSTPROCESSLoad references/special-cases.md before migrating these patterns.
When a migration centers on a specific entity family, load the matching detailed guide:
Each guide explains:
classicEntitySelector expressionsTake dynatrace/dt-migration from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.