
Dt Migration
- 1.3k installs
- 119 repo stars
- Updated July 29, 2026
- dynatrace/dynatrace-for-ai
dt-migration is a Dynatrace skill that maps auto-tagging ManagementZoneDataSourceMeAttribute keys into semantic dictionary fields so AI coding agents interpret monitoring metadata correctly.
About
dt-migration is a Dynatrace-for-AI skill that automatically maps every ManagementZoneDataSourceMeAttribute key from auto_tagging_attributes.md to the most appropriate field in a semantic dictionary used by AI coding agents. The mapping handles recursive tag rules where *_TAGS conditions reference other tags, and accounts for tags imported from cloud vendor labels or Kubernetes attributes in monitored environments. Fields without direct semantic equivalents are marked explicitly so agents do not invent mappings. Developers reach for dt-migration when Dynatrace auto-tagging metadata must be normalized before AI agents can reason about environments, ownership, or deployment zones during incident response or infrastructure change workflows.
- Maps every ManagementZoneDataSourceMeAttribute key from auto_tagging_attributes.md to the matching semantic dictionary f
- Handles HOST, Smartscape nodes, primary tags, cloud vendor tags, and Kubernetes labels
- Explains recursive tag resolution when rules depend on other *_TAGS conditions
- Produces a clean field-mapping table that agents can consume for observability context
- Prevents hallucinated attribute names when agents generate Dynatrace queries or rules
Dt Migration by the numbers
- 1,348 all-time installs (skills.sh)
- +73 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #873 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dynatrace/dynatrace-for-ai --skill dt-migrationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.3k |
|---|---|
| repo stars | ★ 119 |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 29, 2026 |
| Repository | dynatrace/dynatrace-for-ai ↗ |
How do you map Dynatrace auto-tagging keys for AI agents?
Automatically map Dynatrace auto-tagging keys and ManagementZoneDataSourceMeAttribute values into the correct semantic dictionary fields used by AI coding agents.
Who is it for?
Platform engineers running Dynatrace who need AI agents to consume normalized tagging metadata from ManagementZoneDataSourceMeAttribute sources.
Skip if: Teams without Dynatrace auto-tagging or semantic dictionary requirements who only need generic observability dashboards.
When should I use this skill?
Dynatrace auto_tagging_attributes.md keys must be translated into semantic dictionary fields for AI agent workflows or migration scripts.
What you get
Semantic dictionary field mappings for every auto-tagging key, including explicit gaps where no equivalent exists.
- field mapping table
- unmapped key report
- recursive tag resolution notes
Files
Smartscape Migration Skill
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.
Query Purpose Classification
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:
- Situations 1 or 2 — load references/mass-data-filtering-strategy.md and complete all steps including field discovery (Step 2) and equivalence verification (Step 4). Do not skip the
fieldsSnapshotgates — 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. - Situation 3 — continue with the Migration Workflow and entity mapping table below.
Note: Situation 3 has a sub-case whereclassicEntitySelectoris used to filter the entities returned byfetch dt.entity.*. This is rare and follows the samesmartscapeNodespath — resolve the selector conditions using references/mass-data-filtering-strategy.md Step 1B, then apply them as node filters insmartscapeNodes.
Migration Workflow
Follow this order for Situation 3 (pure entity list queries) and for constructing Smartscape subqueries in Situations 1 and 2:
1. Identify the classic input pattern:
fetch dt.entity.*classicEntitySelector(...)- relationship field access such as
belongs_to[...],runs[...],instance_of[...] - signal or event queries using
dt.entity.*
2. Identify the involved classic entity types. 3. Look up the Smartscape replacement in the core entity mapping table below. 4. Check which classic DQL constructs need explicit migration. 5. Rewrite the query using Smartscape primitives:
smartscapeNodessmartscapeEdgestraversereferencesgetNodeName()getNodeField()
6. Check for special cases, unsupported entities, or ID assumptions. 7. Load the matching detailed references for the specific entity family or migration pattern.
For the full migration process and output expectations, load references/migration-workflow.md.
Core Entity Mapping Table
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 |
DQL Constructs to Inspect During Migration
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.
Special Cases
Do not translate these patterns literally:
- Host group — no standalone Smartscape entity; use fields on
HOST - Process group — no standalone Smartscape entity; use fields on
PROCESS - Container group — no standalone Smartscape entity; preserve output shape with placeholders if needed
- Classic IDs — classic entity IDs do not carry over to Smartscape automatically
- Planned, missing, or not-planned mappings — check the full mapping table before assuming direct support
Load references/special-cases.md before migrating these patterns.
Entity-Focused Guides
When a migration centers on a specific entity family, load the matching detailed guide:
- references/entity-host.md
- references/entity-service.md
- references/entity-process.md
- references/entity-container.md
- references/entity-kubernetes.md
- references/entity-cloud-application.md
Each guide explains:
- what the classic entity represented
- what the Smartscape replacement is
- which fields usually change
- how relationships are migrated
- common examples and pitfalls
References
- references/README.md — Reference index and reading guide
- references/mass-data-filtering-strategy.md — Start here for Situations 1 and 2. Mandatory steps: resolve conditions, run fieldsSnapshot discovery, select approach, write query, verify equivalence
- references/auto-tagging-field-mapping.md — Maps auto-tagging rule condition keys to semantic dictionary fields (mass data and Smartscape node attributes)
- references/entity-selector-predicates.md — Full predicate vocabulary for
classicEntitySelectorexpressions - references/migration-workflow.md — End-to-end migration process and output expectations
- references/type-mappings.md — Full classic-to-Smartscape type and field mappings
- references/dql-function-migration.md — How to migrate classic DQL functions and patterns
- references/relationship-mappings.md — Valid Smartscape edges and traversal guidance
- references/special-cases.md — Non-literal and unsupported entity migrations
- references/quick-reference.md — Compact rules and gotchas
- references/examples.md — Before/after migration examples
Auto-Tagging Keys → Semantic Dictionary Field Mapping
Maps every ManagementZoneDataSourceMeAttribute key from auto_tagging_attributes.md to the most appropriate field defined in this semantic dictionary.
Legend:
—— no direct equivalent exists in the semantic dictionary
---
Notes
Any auto tagging key referring to `*_TAGS uses a rule condition that is itself based on tags. Note that the referenced tags may either be the result of another rule for which a recursive search is then necessary to find the original underlying attribute. Alternatively, the referenced tags may also be imported from the monitored environment like cloud vendor tags/labels, Kubernetes labels/attributes or OneAgent environment variables. Cloud vendor tags have the pattern aws/azure/gcp.tags.*` where
Dynatrace supports "primary tags" which is a way to letting customers select custom tags from the source environment and placing them as enriched fields on mass data and top level attributes on smartscape nodes. For example, a selected Kubernetes label `team:backend on a POD becomes primary_tags.team:backend. Smartscape nodes usually contain all collected environment labels and mass data only a selected subset. Smartscape nodes group labels or tags in the structure of the tags` attribute.
HOST
Matching Smartscape Node: HOST
| Auto-Tagging Key | Mass Data Field or Smartscape Node Attribute |
|---|---|
HOST_NAME | host.name |
HOST_DETECTED_NAME | host.name |
HOST_AWS_NAME_TAG | aws.tags.name or `tags:aws[name]` |
HOST_ONEAGENT_CUSTOM_HOST_NAME | host.name |
HOST_TAGS | See above general notes |
HOST_IP_ADDRESS | host.ip |
HOST_OS_TYPE | os.type |
HOST_OS_VERSION | os.version |
HOST_ARCHITECTURE | os.architecture |
HOST_BITNESS | process.bitness |
HOST_CLOUD_TYPE | cloud.provider |
HOST_HYPERVISOR_TYPE | — |
HOST_PAAS_TYPE | cloud.platform |
HOST_PAAS_MEMORY_LIMIT | host.physical.memory |
HOST_TECHNOLOGY | — |
HOST_CPU_CORES | host.logical.cpu.cores |
HOST_LOGICAL_CPU_CORES | host.logical.cpu.cores |
HOST_CUSTOM_METADATA | — |
HOST_KUBERNETES_LABELS | tags:k8s.labels[<label_key>] to be found on K8S_NODE not on the HOST |
HOST_AZURE_WEB_APPLICATION_HOST_NAMES | azure.container_app.hostname |
HOST_AZURE_WEB_APPLICATION_SITE_NAMES | azure.site_name |
HOST_AZURE_COMPUTE_MODE | azure.resource.type |
HOST_AZURE_SKU | — |
HOST_AIX_VIRTUAL_CPU_COUNT | host.virtual.cpus |
HOST_AIX_LOGICAL_CPU_COUNT | host.logical.cpus |
HOST_AIX_SIMULTANEOUS_THREADS | host.simultaneous.multithreading |
HOST_BOSH_NAME | — |
HOST_BOSH_INSTANCE_ID | — |
HOST_BOSH_INSTANCE_NAME | — |
HOST_BOSH_AVAILABILITY_ZONE | aws.availability_zone |
HOST_BOSH_DEPLOYMENT_ID | — |
HOST_BOSH_STEMCELL_VERSION | — |
HOST_GROUP_NAME | dt.host_group.id |
HOST_GROUP_ID | Formerly dt.entity.host_group but must now be resolved under dt.host_group.id representing the plaintext identifier on which the classic entity was based on. |
GOOGLE_COMPUTE_INSTANCE_ID | gcp.instance.id |
GOOGLE_COMPUTE_INSTANCE_NAME | gcp.resource.name |
GOOGLE_COMPUTE_INSTANCE_MACHINE_TYPE | gcp.resource.type |
GOOGLE_COMPUTE_INSTANCE_PUBLIC_IP_ADDRESSES | host.ip |
GOOGLE_COMPUTE_INSTANCE_PROJECT | gcp.organization.name |
GOOGLE_COMPUTE_INSTANCE_PROJECT_ID | gcp.project.id |
---
PROCESS_GROUP
Matching Smartscape Node: Does not exist, attributes need to be found on PROCESS nodes
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
PROCESS_GROUP_NAME | dt.process_group.detected_name |
PROCESS_GROUP_DETECTED_NAME | dt.process_group.detected_name |
PROCESS_GROUP_TAGS | See above general notes |
PROCESS_GROUP_LISTEN_PORT | process.listen_ports |
PROCESS_GROUP_TECHNOLOGY | — |
PROCESS_GROUP_TECHNOLOGY_EDITION | — |
PROCESS_GROUP_TECHNOLOGY_VERSION | — |
PROCESS_GROUP_ID | The value of this property corresponds to dt.entity.process_group. No Smartscape node of this kind exists, but that former entity's properties may now be found under dt.process_group.id on a dt.smartscape.process node. |
PROCESS_GROUP_AZURE_HOST_NAME | azure.container_app.hostname |
PROCESS_GROUP_AZURE_SITE_NAME | azure.site_name |
PROCESS_GROUP_CUSTOM_METADATA | process.metadata |
PROCESS_GROUP_PREDEFINED_METADATA | process.metadata |
---
SERVICE
Matching Smartscape Node: SERVICE
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
SERVICE_NAME | dt.service.name |
SERVICE_DETECTED_NAME | dt.service.name |
SERVICE_TAGS | See above general notes |
SERVICE_PORT | server.port |
SERVICE_TYPE | — |
SERVICE_TOPOLOGY | — |
SERVICE_TECHNOLOGY | — |
SERVICE_TECHNOLOGY_EDITION | — |
SERVICE_TECHNOLOGY_VERSION | — |
SERVICE_DATABASE_NAME | db.namespace |
SERVICE_DATABASE_VENDOR | db.system |
SERVICE_DATABASE_TOPOLOGY | — |
SERVICE_DATABASE_HOST_NAME | server.address |
SERVICE_WEB_SERVER_ENDPOINT | url.full |
SERVICE_PUBLIC_DOMAIN_NAME | url.domain |
SERVICE_REMOTE_ENDPOINT | server.address |
SERVICE_REMOTE_SERVICE_NAME | service.name |
SERVICE_IBM_CTG_GATEWAY_URL | url.full |
SERVICE_AKKA_ACTOR_SYSTEM | messaging.akka.actor.system |
SERVICE_MESSAGING_LISTENER_CLASS_NAME | messaging.system |
SERVICE_WEB_APPLICATION_ID | dt.rum.application.id |
SERVICE_WEB_CONTEXT_ROOT | url.path |
SERVICE_WEB_SERVER_NAME | server.address |
SERVICE_WEB_SERVICE_NAME | rpc.service |
SERVICE_WEB_SERVICE_NAMESPACE | rpc.namespace |
SERVICE_CTG_SERVICE_NAME | rpc.service |
SERVICE_ESB_APPLICATION_NAME | service.name |
---
QUEUE
Matching Smartscape Node: SERVICE
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
QUEUE_NAME | messaging.destination.name |
QUEUE_VENDOR | messaging.system |
QUEUE_TECHNOLOGY | messaging.system |
---
CUSTOM_DEVICE
Matching Smartscape Node: Depends on the custom devices "type" attribute.
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
CUSTOM_DEVICE_NAME | name |
CUSTOM_DEVICE_TAGS | See above general notes |
CUSTOM_DEVICE_IP_ADDRESS | device.address |
CUSTOM_DEVICE_PORT | device.port |
CUSTOM_DEVICE_DNS_ADDRESS | server.address |
CUSTOM_DEVICE_TECHNOLOGY | — |
CUSTOM_DEVICE_METADATA | — |
---
CUSTOM_DEVICE_GROUP
Matching Smartscape Node: No equivalent type.
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
CUSTOM_DEVICE_GROUP_NAME | — |
CUSTOM_DEVICE_GROUP_TAGS | See above general notes |
---
WEB_APPLICATION
Matching Smartscape Node: FRONTEND
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
WEB_APPLICATION_NAME | service.name |
WEB_APPLICATION_NAME_PATTERN | url.path.pattern |
WEB_APPLICATION_TAGS | See above general notes |
WEB_APPLICATION_TYPE | browser.type |
---
MOBILE_APPLICATION
Matching Smartscape Node: FRONTEND
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
MOBILE_APPLICATION_NAME | app.id |
MOBILE_APPLICATION_TAGS | See above general notes |
MOBILE_APPLICATION_PLATFORM | dt.rum.agent.type |
---
CUSTOM_APPLICATION
Matching Smartscape Node: FRONTEND
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
CUSTOM_APPLICATION_NAME | service.name |
CUSTOM_APPLICATION_TAGS | See above general notes |
CUSTOM_APPLICATION_PLATFORM | dt.rum.agent.type |
CUSTOM_APPLICATION_TYPE | — |
---
ENTERPRISE_APPLICATION (DC-RUM App)
Matching Smartscape Node: No equivalent
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
ENTERPRISE_APPLICATION_NAME | service.name |
ENTERPRISE_APPLICATION_TAGS | See above general notes |
ENTERPRISE_APPLICATION_DECODER_TYPE | — |
ENTERPRISE_APPLICATION_IP_ADDRESS | host.ip |
ENTERPRISE_APPLICATION_PORT | server.port |
ENTERPRISE_APPLICATION_METADATA | — |
---
DATA_CENTER_SERVICE (DC-RUM Service)
Matching Smartscape Node: No equivalent
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
DATA_CENTER_SERVICE_NAME | service.name |
DATA_CENTER_SERVICE_TAGS | See above general notes |
DATA_CENTER_SERVICE_DECODER_TYPE | — |
DATA_CENTER_SERVICE_IP_ADDRESS | host.ip |
DATA_CENTER_SERVICE_PORT | server.port |
DATA_CENTER_SERVICE_METADATA | — |
---
BROWSER_MONITOR (Synthetic Test)
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
BROWSER_MONITOR_NAME | Name of dt.smartscape.browser_monitor. |
BROWSER_MONITOR_TAGS | See above general notes |
---
EXTERNAL_MONITOR (External Synthetic Test)
Matching Smartscape Node: Coming later.
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
EXTERNAL_MONITOR_NAME | - |
EXTERNAL_MONITOR_TAGS | See above general notes |
EXTERNAL_MONITOR_ENGINE_TYPE | — |
EXTERNAL_MONITOR_ENGINE_NAME | — |
EXTERNAL_MONITOR_ENGINE_DESCRIPTION | — |
---
HTTP_MONITOR
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
HTTP_MONITOR_NAME | Name of dt.smartscape.http_monitor |
HTTP_MONITOR_TAGS | See above general notes |
---
NETWORK_AVAILABILITY_MONITOR (NAM)
Matching Smartscape Node: No equivalent.
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
NETWORK_AVAILABILITY_MONITOR_NAME | - |
NETWORK_AVAILABILITY_MONITOR_TAGS | See above general notes |
---
DOCKER
Matching Smartscape Node: CONTAINER
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
DOCKER_CONTAINER_NAME | container.name |
DOCKER_FULL_IMAGE_NAME | container.image.name |
DOCKER_IMAGE_VERSION | container.image.version |
---
ESXI_HOST (Hypervisor)
Matching Smartscape Node: No equivalent.
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
ESXI_HOST_NAME | host.name |
ESXI_HOST_TAGS | — |
ESXI_HOST_HARDWARE_MODEL | — |
ESXI_HOST_HARDWARE_VENDOR | — |
ESXI_HOST_PRODUCT_NAME | os.name |
ESXI_HOST_PRODUCT_VERSION | os.version |
ESXI_HOST_CLUSTER_NAME | k8s.cluster.name |
---
EC2_INSTANCE
Matching Smartscape Node: AWS_EC2_INSTANCE
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
EC2_INSTANCE_NAME | aws.resource.name |
EC2_INSTANCE_TAGS | `See above general notes |
EC2_INSTANCE_ID | aws.resource.id |
EC2_INSTANCE_PRIVATE_HOST_NAME | host.name |
EC2_INSTANCE_PUBLIC_HOST_NAME | host.fqdn |
EC2_INSTANCE_AWS_INSTANCE_TYPE | aws.resource.type |
EC2_INSTANCE_AWS_SECURITY_GROUP | aws.arn |
EC2_INSTANCE_AMI_ID | container.image.digest |
EC2_INSTANCE_BEANSTALK_ENV_NAME | deployment.release_stage |
---
OPENSTACK_VM
Matching Smartscape Node: Unknown
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
OPENSTACK_VM_NAME | host.name |
OPENSTACK_VM_INSTANCE_TYPE | — |
OPENSTACK_VM_SECURITY_GROUP | — |
---
VMWARE_VM
Matching Smartscape Node: Unknown.
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
VMWARE_VM_NAME | host.name |
---
KUBERNETES
Matching Smartscape Nodes, K8S_CLUSTER, K8S_NODE, K8S_SERVICE
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
KUBERNETES_CLUSTER_NAME | k8s.cluster.name |
KUBERNETES_NODE_NAME | k8s.node.name |
KUBERNETES_SERVICE_NAME | k8s.service.name |
---
CLOUD_APPLICATION
Matching Smartscape Node: K8S_DEPLOYMENT, K8S_REPLICASET, K8S_STATEFULSET, K8S_DAEMONSET, K8S_JOB, K8S_CRONJOB
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
CLOUD_APPLICATION_NAME | k8s.workload.name |
CLOUD_APPLICATION_LABELS | k8s.workload.label.__attribute_name__ |
CLOUD_APPLICATION_NAMESPACE_NAME | k8s.namespace.name |
CLOUD_APPLICATION_NAMESPACE_LABELS | k8s.namespace.label.__attribute_name__ |
---
AWS_AUTO_SCALING_GROUP
Matching Smartscape Node: AWS_AUTOSCALING_AUTOSCALINGROUP
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
AWS_AUTO_SCALING_GROUP_NAME | aws.resource.name |
AWS_AUTO_SCALING_GROUP_TAGS | aws.tags.__tag_key__ |
---
AWS_CLASSIC_LOAD_BALANCER
Matching Smartscape Node: AWS_ELASTICLOADBALANCING_LOADBALANCER
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
AWS_CLASSIC_LOAD_BALANCER_NAME | aws.resource.name |
AWS_CLASSIC_LOAD_BALANCER_TAGS | aws.tags.__tag_key__ |
AWS_CLASSIC_LOAD_BALANCER_FRONTEND_PORTS | server.port |
---
AWS_APPLICATION_LOAD_BALANCER
Matching Smartscape Node: TBD
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
AWS_APPLICATION_LOAD_BALANCER_NAME | aws.alb.name |
AWS_APPLICATION_LOAD_BALANCER_TAGS | aws.tags.__tag_key__ |
---
AWS_NETWORK_LOAD_BALANCER
Matching Smartscape Node: TBD
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
AWS_NETWORK_LOAD_BALANCER_NAME | aws.resource.name |
AWS_NETWORK_LOAD_BALANCER_TAGS | aws.tags.__tag_key__ |
---
AWS_RELATIONAL_DATABASE_SERVICE
Matching Smartscape Node: AWS_RDS_DBCLUSTER
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
AWS_RELATIONAL_DATABASE_SERVICE_NAME | aws.resource.name |
AWS_RELATIONAL_DATABASE_SERVICE_TAGS | aws.tags.__tag_key__ |
AWS_RELATIONAL_DATABASE_SERVICE_INSTANCE_CLASS | aws.resource.type |
AWS_RELATIONAL_DATABASE_SERVICE_ENDPOINT | server.address |
AWS_RELATIONAL_DATABASE_SERVICE_ENGINE | db.system |
AWS_RELATIONAL_DATABASE_SERVICE_PORT | server.port |
AWS_RELATIONAL_DATABASE_SERVICE_DB_NAME | db.namespace |
---
AWS_ACCOUNT
Matching Smartscape Node: AWS_ACCOUNT
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
AWS_ACCOUNT_NAME | aws.account.name |
AWS_ACCOUNT_ID | aws.account.id |
---
AZURE
Matching Smartscape Node: TBD
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
AZURE_VM_NAME | azure.vm.name |
AZURE_SCALE_SET_NAME | azure.vm_scale_set.name |
AZURE_ENTITY_NAME | azure.resource.name |
AZURE_ENTITY_TAGS | azure.tags.__tag_key__ |
AZURE_TENANT_NAME | azure.tenant.name |
AZURE_TENANT_UUID | azure.tenant.id |
AZURE_MGMT_GROUP_NAME | azure.management_group |
AZURE_MGMT_GROUP_UUID | azure.management_group |
AZURE_SUBSCRIPTION_NAME | — |
AZURE_SUBSCRIPTION_UUID | azure.subscription |
---
DATACENTER
Matching Smartscape Node: TBD
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
AWS_AVAILABILITY_ZONE_NAME | aws.availability_zone |
AZURE_REGION_NAME | azure.location |
GEOLOCATION_SITE_NAME | geo.name |
GOOGLE_CLOUD_PLATFORM_ZONE_NAME | gcp.zone |
OPENSTACK_AVAILABILITY_ZONE_NAME | — |
OPENSTACK_REGION_NAME | — |
VMWARE_DATACENTER_NAME | — |
---
OPENSTACK_ACCOUNT
Matching Smartscape Node: No equivalent
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
OPENSTACK_ACCOUNT_NAME | — |
OPENSTACK_ACCOUNT_PROJECT_NAME | — |
---
OPENSTACK
Matching Smartscape Node: No equivalent
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
OPENSTACK_PROJECT_NAME | — |
NAME_OF_COMPUTE_NODE | host.name |
---
CLOUD_FOUNDRY
Matching Smartscape Node: No equivalent
| Auto-Tagging Key | Semantic Dictionary Field |
|---|---|
CLOUD_FOUNDRY_ORG_NAME | — |
CLOUD_FOUNDRY_FOUNDATION_NAME | — |
DQL Function and Pattern Migration
Use this reference when the migration is driven by a classic DQL construct rather than by a single entity type.
Contents
- `entityName()`
- `entityAttr()`
- `classicEntitySelector()`
- Classic relationship fields
- Signal dimensions
- Event fields
- Classic IDs
entityName()
Typical replacements
- When querying Smartscape nodes directly, prefer
name - When you only have an ID in a signal or edge query, use
getNodeName(id)
Examples
fetch dt.entity.host
| fields entity.name, idbecomes:
smartscapeNodes HOST
| fields entity.name = name, idIf the migrated query works on edge records or signal dimensions:
| fields target_name = getNodeName(target_id)Important rule
getNodeName() accepts only an ID. Do not pass a type: argument.
entityAttr()
Typical replacements
- Prefer a direct node field when Smartscape exposes one
- Otherwise use
getNodeField(id_or_dimension, "field")
Example
Classic signal-style tag access often appears as:
| filter in(entityAttr(dt.entity.aws_lambda_function, "tags"), "[AWS]dt_owner_team:team-mirage")Smartscape form:
| filter getNodeField(dt.smartscape.aws_lambda_function, "tags:aws")[dt_owner_team] == "team-mirage"classicEntitySelector()
Migration strategy
1. Parse the selector for the constrained entity and relationships 2. Start from the constrained side if possible 3. Convert selector filters to Smartscape node filters 4. Replace fromRelationship.* and toRelationship.* with traverse
Example without relationships
fetch dt.entity.host
| filter in(id, classicEntitySelector("type(host),tag([Environment]syn_grail_log:bastion)"))
| fields entity.name, idbecomes:
smartscapeNodes HOST
| filter `tags:environment`[syn_grail_log] == "bastion"
| fields entity.name = name, idExample with relationships
fetch dt.entity.service
| filter in(id, classicEntitySelector("type(service), fromRelationship.runsOnHost(type(host), tag([Azure]dt_owner_email:team-ops@example.com))"))
| fields id, entity.namebecomes:
smartscapeNodes HOST
| filter `tags:azure`[dt_owner_email] == "team-ops@example.com"
| traverse runs_on, SERVICE, direction:backward
| fields id, entity.name = nameClassic relationship fields
Classic entity queries often expose relationships as projected fields such as:
belongs_to[...]runs[...]instance_of[...]clustered_by[...]
Typical replacements
- Use
traversefor relationship navigation - Use
smartscapeEdgeswhen the result should be an edge-centric record set - Use
references[...]for static edges when simple field access is enough
references[...]
Use references only for static edges.
Example:
fetch dt.entity.network_interface
| fieldsAdd host = belongs_to[dt.entity.host]becomes:
smartscapeNodes NETWORK_INTERFACE
| fieldsAdd host = references[belongs_to.host]Signal dimensions
Every classic entity dimension in signal queries must be migrated.
Rule
dt.entity.host→dt.smartscape.hostdt.entity.service→dt.smartscape.service- `
dt.entity.os:service→dt.smartscape.os_service`
Apply this rule everywhere in the signal query, not only in the main by clause.
Example
timeseries avg(dt.service.request.response_time),
by:{ dt.entity.service }becomes:
timeseries avg(dt.service.request.response_time),
by:{ dt.smartscape.service }Event fields
Use these field migrations in Davis event queries:
| Classic field | Smartscape field |
|---|---|
affected_entity_ids | smartscape.affected_entity.ids |
affected_entity_types | smartscape.affected_entity.types |
dt.source_entity.type | dt.smartscape_source.type |
Important value rule
When the field contains entity types, use uppercase Smartscape type values such as HOST, SERVICE, or CONTAINER, not classic values like dt.entity.host.
Classic IDs
Classic entity IDs do not automatically carry over to Smartscape.
Rule
- never use
id_classic - when comparing to a Smartscape ID literal, wrap it with
toSmartscapeId()
Example:
| filter in(dt.smartscape.host, { toSmartscapeId("HOST-ABC123") })Open assumption pattern
If the classic query filters by a specific classic entity ID and the matching Smartscape ID is unknown, call that out as an assumption and tell the user how to look it up.
Example note:
// ASSUMPTION: Replace the old classic host ID with the matching Smartscape host ID.
// Look it up with:
smartscapeNodes HOST | fields id, nameCloud Application Migration Guide
Use this guide when the classic query uses:
dt.entity.cloud_applicationdt.entity.cloud_application_instancedt.entity.cloud_application_namespace
Core mappings
| Classic | Smartscape |
|---|---|
dt.entity.cloud_application | multiple workload types: K8S_DEPLOYMENT, K8S_DAEMONSET, K8S_STATEFULSET, K8S_REPLICASET, K8S_REPLICATIONCONTROLLER, K8S_JOB, K8S_DEPLOYMENTCONFIG |
dt.entity.cloud_application_instance | K8S_POD |
dt.entity.cloud_application_namespace | K8S_NAMESPACE |
Why this matters
The classic cloud-application model grouped several Kubernetes workload concepts under one type. Smartscape models those workload types explicitly.
That means a direct one-to-one replacement often does not exist for dt.entity.cloud_application.
Migration guidance
dt.entity.cloud_application
- query the relevant workload types explicitly
- use workload or Kubernetes fields such as
k8s.cluster.name - if the classic query assumed one unified type, make the new multi-type scope explicit
dt.entity.cloud_application_instance
- translate to
smartscapeNodes K8S_POD - use first-class pod fields:
k8s.workload.namek8s.namespace.namek8s.node.namek8s.cluster.name
dt.entity.cloud_application_namespace
- translate to
smartscapeNodes K8S_NAMESPACE
Example: workload mapping
smartscapeNodes K8S_DEPLOYMENT, K8S_DAEMONSET, K8S_STATEFULSET, K8S_REPLICASET,
K8S_REPLICATIONCONTROLLER, K8S_JOB, K8S_DEPLOYMENTCONFIG
| fields
entity.name = name,
kubernetesClusterName = k8s.cluster.name,
cloudApplicationLabels = `tags:k8s.labels`Example: pod mapping
smartscapeNodes K8S_POD
| fields entity.name = name,
workloadName = k8s.workload.name,
namespaceName = k8s.namespace.name,
nodeName = k8s.node.name,
kubernetesClusterName = k8s.cluster.nameRelated references
- entity-kubernetes.md
- type-mappings.md
- examples.md
Container Migration Guide
Use this guide when the migration centers on dt.entity.container_group_instance or dt.entity.container_group.
Core mapping
| Classic | Smartscape |
|---|---|
dt.entity.container_group_instance | dt.smartscape.container |
CONTAINER node query | smartscapeNodes CONTAINER |
Container-group special case
dt.entity.container_group is not a standalone Smartscape node.
When the old query projects container-group identifiers or names, preserve the output shape with null if there is no real equivalent.
Common field migrations
entity.name→namecontainerizationType→container.containerization_type- classic affected-entity event joins →
smartscape.affected_entity.idsandsmartscape.affected_entity.types
Relationship patterns
CONTAINER runs_on HOSTCONTAINER runs_on K8S_NODECONTAINER is_part_of K8S_PODCONTAINER belongs_to K8S_NAMESPACECONTAINER belongs_to K8S_CLUSTER
Example
smartscapeNodes CONTAINER
| fields
id,
containerName = name,
containerizationType = container.containerization_type,
containerGroupId = null,
containerGroupName = nullRelated references
- special-cases.md
- examples.md
- relationship-mappings.md
Host Migration Guide
Use this guide when the migration centers on dt.entity.host or host-related signal dimensions.
Core mapping
| Classic | Smartscape |
|---|---|
dt.entity.host | dt.smartscape.host |
HOST node query | smartscapeNodes HOST |
Common field migrations
entity.name→name- host tags in signal queries →
getNodeField(dt.smartscape.host, "tags") - host group data → host fields such as
dt.host_group.id
Relationship patterns
- host to service via
runs_on - host to VM via
runs_on - host to disk via
belongs_to
Important special case
dt.entity.host_group is not a Smartscape node type. Do not traverse to HOST_GROUP.
Example
smartscapeNodes HOST
| filter `tags:environment`[syn_grail_log] == "bastion"
| fields entity.name = name, idRelated references
- special-cases.md
- relationship-mappings.md
- examples.md
Kubernetes Migration Guide
Use this guide when the migration centers on Kubernetes cluster, node, namespace, service, pod, or workload entities.
Common mappings
| Classic | Smartscape |
|---|---|
dt.entity.kubernetes_cluster | dt.smartscape.k8s_cluster / K8S_CLUSTER |
dt.entity.kubernetes_node | dt.smartscape.k8s_node / K8S_NODE |
dt.entity.kubernetes_service | dt.smartscape.k8s_service / K8S_SERVICE |
dt.entity.cloud_application_namespace | dt.smartscape.k8s_namespace / K8S_NAMESPACE |
dt.entity.cloud_application_instance | dt.smartscape.k8s_pod / K8S_POD |
Workload relationships
Smartscape models workload relationships explicitly:
K8S_POD belongs_to K8S_CLUSTERK8S_POD belongs_to K8S_NAMESPACEK8S_POD runs_on K8S_NODEK8S_POD is_part_of K8S_DEPLOYMENT,K8S_STATEFULSET,K8S_DAEMONSET, and related workload typesK8S_SERVICE routes_to K8S_POD
Migration guidance
- Prefer first-class
k8s.*fields when querying pods or workloads directly - Use
traversewhen the relationship itself matters - For classic cloud application concepts, also load entity-cloud-application.md
Example
smartscapeNodes K8S_POD
| fields entity.name = name,
workloadName = k8s.workload.name,
namespaceName = k8s.namespace.name,
nodeName = k8s.node.name,
kubernetesClusterName = k8s.cluster.nameRelated references
- entity-cloud-application.md
- relationship-mappings.md
- examples.md
Process Migration Guide
Use this guide when the migration centers on dt.entity.process_group_instance or dt.entity.process_group.
Core mapping
| Classic | Smartscape |
|---|---|
dt.entity.process_group_instance | dt.smartscape.process |
PROCESS node query | smartscapeNodes PROCESS |
Process-group special case
dt.entity.process_group is not a standalone Smartscape node.
Use fields on PROCESS instead:
dt.process_group.iddt.process_group.namedt.process_group.detected_name
Relationship patterns
PROCESS runs_on HOSTPROCESS runs_on CONTAINERPROCESS calls PROCESS
Example
smartscapeNodes PROCESS
| summarize by:{ id = dt.process_group.id, entity.name = dt.process_group.detected_name }, process.metadata = takeAny(process.metadata)Related references
- special-cases.md
- relationship-mappings.md
- type-mappings.md
Entity Selector Predicates
Reference for all valid predicates in the entity selector query language, used via the /api/v2/entities API.
Multiple predicates are combined with , (implicit AND):
type("SERVICE"),tag("env:prod"),mzName("Production"),healthState("UNHEALTHY")Each section includes a Semantic Dictionary Field column that maps classic entity selector predicates to their corresponding fields in the Dynatrace Semantic Dictionary. These mappings help when migrating from classic entity-based queries to Grail/DQL-based workflows. Calls to `fieldsSnapshot ...` allow discovery of available enriched mass data fields or Smartscape Node attributes.
---
Core / Identity
| Predicate | Example | Semantic Dictionary Field for Migration |
|---|---|---|
type | type("HOST") | Not needed for migration, usually implicit through context. |
entityId | entityId("SERVICE-123ABC") | Can not be migrated. |
entityName | entityName("my-service") | Often enriched on mass data with context specific naming. Examples host.name, dt.host_group.id, k8s.*.name. |
entityName.equals and others | entityName.equals("my-service") | See entityName, suffix implies type of comparison. |
---
Management Zone
| Predicate | Aliases | Semantic Dictionary Field |
|---|---|---|
mzId | managementZoneId | |
mzName | managementZoneName, mz | |
mzName.startsWith |
Note: In Grail, management zones are replaced by ownership and permission models. Can not appear in DQL queries, only directly in query constructs against classic APIs.
---
Tags
| Predicate | Example | Semantic Dictionary Field |
|---|---|---|
tag | tag("env:prod"), tag("owner:team-a") |
Note: See mass-data-filtering-strategy.md for how to resolve tag filter conditions.
---
Health State
| Predicate | Allowed Values | Semantic Dictionary Field |
|---|---|---|
healthState | HEALTHY, UNHEALTHY | availability.state |
---
Timestamps
Each supports .lte, .lt, .gte, .gt operators. Predicates based on entity lifetime need to be translated to Smartscape Node queries with equivalent filters on `lifetime`.
| Predicate | Example | Semantic Dictionary Field |
|---|---|---|
firstSeenTms | firstSeenTms.gte(1609459200000) | lifetime (start component) |
lastExecutionTms | lastExecutionTms.lte(1609459200000) | lastExecutionTimestamp |
modificationTms | modificationTms.gt(1609459200000) | modificationTimestamp |
creationTimestamp | creationTimestamp.gte(1609459200000) | creationTimestamp |
resourceCreationTimestamp | resourceCreationTimestamp.lt(1609459200000) | resourceCreationTimestamp |
resourceDeletionTimestamp | resourceDeletionTimestamp.exists | resourceDeletionTimestamp |
Note: lifetime is a complex record containing start/end timestamps representing when the entity was first and last seen.---
Modifiers / Wrappers
| Predicate | Example | Description | Semantic Dictionary Field |
|---|---|---|---|
not(...) | not(type("HOST")) | Negates the wrapped predicate | — (query-level operator) |
caseSensitive(...) | caseSensitive(entityName.equals("MyService")) | Makes string matching case-sensitive | — (query-level operator) |
deletedEntities.include | deletedEntities.include | Include soft-deleted entities | resourceDeletionTimestamp |
deletedEntities.exclude | deletedEntities.exclude | Exclude soft-deleted entities | resourceDeletionTimestamp |
---
Filter Predicates
These accept an optional .exists variant (e.g., ipAddress.exists).
| Predicate | Aliases | Semantic Dictionary Field |
|---|---|---|
ipAddress | dt.ip_addresses | dt.ip_addresses / host.ip |
osType | — | os.type / osType |
osDetail | — | osDetail |
monitoringMode | — | dt.agent.monitoring_mode / monitoringMode |
hostVirtualizationType | — | hypervisor.type / hypervisorType |
networkZone | — | dt.network_zone.id / networkZone |
processType | — | processType |
serviceType | — | serviceType |
cloudType | — | cloud.provider / cloudType |
paasVendorType | — | paasVendorType |
databaseVendor | — | db.system / databaseVendor |
databaseName | — | db.namespace / databaseName |
softwareTechnologies | softwareTechnologies.type, dt.software_techs, dt.software_techs.type | softwareTechnologies |
softwareTechnologies.version | dt.software_techs.version | softwareTechnologies |
kubernetesClusterId | — | k8s.cluster.uid / kubernetesClusterId |
kubernetesClusterName | — | k8s.cluster.name |
kubernetesLabels | — | k8s.workload.label.__attribute_name__ / kubernetesLabels |
kubernetesApiMonitoringState | — | — (no direct mapping) |
kubernetesDistribution | — | kubernetesDistribution |
namespaceName | — | k8s.namespace.name / namespaceName |
containerNames | containerName | container.name / containerNames |
azureSubscriptionUuid | — | azure.subscription / azureSubscriptionUuid |
azureTenantUuid | — | azure.tenant.id / azureTenantUuid |
azureManagementGroupUuid | — | azure.management_group / azureManagementGroupUuid |
azureResourceId | — | azure.resource.id / azureResourceId |
azureSiteName | — | azure.site_name / azureSiteName |
state | — | state / availability.state |
autoInjection | globalHookingStatus | autoInjection |
applicationInjectionType | — | applicationType |
standalone | — | standalone |
isContainerDeployment | — | isDockerized / containerizationType |
requestAttribute | — | request_attribute.__attribute_name__ |
affectedBySecurityProblem | — | vulnerability.* |
exposingSecurityProblem | — | vulnerability.* |
reachableThroughSecurityProblem | — | vulnerability.* |
queueName | — | messaging.destination.name / queueName |
queueVendorName | — | messaging.system / queueVendorName |
queueDestinationType | — | messaging.destination.kind / queueDestinationType |
cloudNetworkServiceType | — | cloudNetworkServiceType |
customDeviceSource | — | — (no direct mapping) |
pluginsRunning | — | pluginsRunning |
installerVersion | — | dt.agent.installer_version / installerVersion |
filesystemType | — | storage.disk.fstype |
remoteDiskId | — | disk.remote_disk_id / remoteDiskId |
Note: Where two fields are listed (e.g.,os.type/osType), the first is the normalized Semantic Dictionary resource field and the second is the classic shared entity property. Use the normalized field for new Grail/DQL queries and the shared field when querying the classic entity model.
---
AppSec
| Predicate | Allowed Values | Semantic Dictionary Field |
|---|---|---|
coveredByAppSec | SUPPORTED, MONITORED, EXCLUDED | — (no direct mapping) |
coveredByAppSecThirdParty | SUPPORTED, MONITORED, EXCLUDED | — (no direct mapping) |
coveredByAppSecCodeLevel | SUPPORTED, MONITORED, EXCLUDED | — (no direct mapping) |
Note: AppSec coverage predicates do not have direct Semantic Dictionary equivalents. Related security data is available throughvulnerability.*anddt.security.*signal fields.
---
Releases
| Predicate | Aliases | Semantic Dictionary Field |
|---|---|---|
releasesVersion | — | deployment.release_version / releasesVersion |
releasesVersion.exists | — | deployment.release_version / releasesVersion |
releasesStage | releasesEnvironment | deployment.release_stage / releasesStage |
releasesProduct | releasesApplication | deployment.release_product / releasesProduct |
releasesBuildVersion | — | deployment.release_build_version / releasesBuildVersion |
---
Installer
| Predicate | Semantic Dictionary Field |
|---|---|
installerPotentialProblem | installerPotentialProblem |
installerTrackedDownload | installerTrackedDownload |
installerSupportAlert | installerSupportAlert |
---
Relationship Predicates
Syntax: fromRelationships.<name>(<entitySelector>) or toRelationships.<name>(<entitySelector>)
Example:
type("SERVICE"),fromRelationships.runsOn(type("HOST"),entityName.contains("prod"))The Semantic Dictionary defines normalized relationship types in the relationships group of source/model/dt.entities/model_group_dt_entities.yaml. Classic entity selector relationship names map to these normalized types as follows:
Mapping to Semantic Dictionary Relationship Types
| Classic Relationship Name | Semantic Dictionary Relationship |
|---|---|
runsOn / runsOnHost / runsOnResource | runs_on / runs |
isProcessOf | runs / runs_on |
calls | calls / called_by |
manages | manages / managed_by |
monitors | monitors / monitored_by |
isChildOf | child_of / parent_of |
isPartOf | part_of / consists_of |
isSameAs | same_as |
isGroupOf / isMemberOf | groups / group_of |
isInstanceOf | instance_of / instantiates |
isDatastoreOf | serves / served_by |
isBalancedBy | balanced_by / balances |
isAccessibleBy | accessible_by / can_access |
belongsTo | belongs_to / contains |
isStepOf | part_of / consists_of |
sendsToQueue | sends_to / receives_from |
receivesFromQueue / listensOnQueue | receives_from / sends_to |
indirectlySendsToQueue | indirectly_sends_to |
indirectlyReceivesFromQueue | indirectly_receives_from |
propagatesTo | propagates_to / propagated_from |
isHostGroupOf | groups / group_of |
isServiceOf / isServiceOfProcessGroup | serves / served_by |
All Classic Relationship Names (Reference)
| Relationship Name | Relationship Name |
|---|---|
isProcessOf | runsOn |
runsOnHost | runsOnResource |
calls | manages |
monitors | isChildOf |
isPartOf | isSameAs |
isGroupOf | isMemberOf |
isInstanceOf | isDatastoreOf |
isSiteOf | isBalancedBy |
isServiceOf | isServiceOfProcessGroup |
isApplicationMethodOf | isApplicationMethodOfGroup |
isServiceMethodOf | isServiceMethodOfService |
isNetworkClientOf | isNetworkClientOfProcessGroup |
isNetworkClientOfHost | isDiskOf |
isEbsVolumeOf | isNetworkInterfaceOf |
isDockerContainerOf | isDockerContainerOfPg |
isHostOfContainer | isAccessibleBy |
belongsTo | isStepOf |
sendsToQueue | receivesFromQueue |
listensOnQueue | indirectlySendsToQueue |
indirectlyReceivesFromQueue | isHostGroupOf |
isClusterOfNode | isClusterOfHost |
isClusterOfNamespace | isClusterOfPg |
isClusterOfCa | isClusterOfCai |
isClusterOfService | isClusterOfKubernetesSvc |
isNodeOfHost | isNamespaceOfCa |
isNamespaceOfCai | isNamespaceOfPg |
isNamespaceOfService | isNamespaceOfKubernetesSvc |
isKubernetesSvcOfCai | isKubernetesSvcOfCa |
isPgOfCa | isPgOfCai |
isPgOfCg | isPgAppOf |
isCgiOfHost | isCgiOfCa |
isCgiOfCai | isCgiOfCluster |
isMainPgiOfCgi | isPgiOfCgi |
isApplicationOfSyntheticTest | isLocatedIn |
isServedByDcrumService | hostsComputeNode |
propagatesTo | isUserActionOf |
isOpenstackAvZoneOf | isMemberOfScalingGroup |
isProcessRunningOpenstackVm | isCfFoundationOfHost |
isBoshDeploymentOfHost | isSystemProfileOf |
isSoftwareComponentOfPgi | isRuntimeComponentOf |
isRuntimeOfPgi | runsOnProcessGroupInstance |
isAzrServiceBusNamespaceOfQueue | isAzrServiceBusNamespaceOfTopic |
isAzrEventHubNamespaceOfEventHub | isAzrStorageAccountOfAzrEventHub |
isAzrAppServicePlanOf | isAzrSubscriptionOfCredentials |
isAzrSubscriptionOfAzrTenant | isAzrSubscriptionOfAzrMgmtGroup |
isAzrMgmtGroupOfAzrTenant | isAzrSqlServerOfElasticPool |
isAzrSqlServerOfDatabase | isAzrSQLDatabaseOfElasticPool |
candidateTalksWith | talksWithCandidate |
Note: The Semantic Dictionary normalizes the many specific classic relationship names (e.g.,isClusterOfNode,isNamespaceOfPg) into a smaller set of generic relationship types (e.g.,cluster_of,contains). The classic names remain valid for entity selector queries against the v2 API.
---
Postfix Operators
All string predicates support these operators. Numeric and timestamp predicates support comparison operators.
| Operator | Type | Description |
|---|---|---|
| (bare) | string | Default equals match |
.equals | string | Exact match |
.contains | string | Substring match |
.startsWith | string | Prefix match |
.in | string | Multi-value list, e.g. entityName.in("a","b","c") |
.exists | any | Field existence check |
.gte | numeric / timestamp | Greater than or equal |
.gt | numeric / timestamp | Greater than |
.lte | numeric / timestamp | Less than or equal |
.lt | numeric / timestamp | Less than |
.include | modifier | Inclusion modifier |
.exclude | modifier | Exclusion modifier |
Service Migration Guide
Use this guide when the migration centers on dt.entity.service or service-related signal dimensions.
Core mapping
| Classic | Smartscape |
|---|---|
dt.entity.service | dt.smartscape.service |
SERVICE node query | smartscapeNodes SERVICE |
Common migration patterns
entity.name→name- service signal dimension
dt.entity.service→dt.smartscape.service - classic selectors constrained by host or process often become
traverse runs_on, SERVICE, direction:backward
Common relationships
SERVICE runs_on HOSTSERVICE runs_on PROCESSSERVICE runs_on CONTAINERSERVICE calls SERVICE
Example
smartscapeNodes HOST
| filter `tags:azure`[dt_owner_email] == "team-ops@example.com"
| traverse runs_on, SERVICE, direction:backward
| fields id, entity.name = nameRelated references
- relationship-mappings.md
- dql-function-migration.md
- examples.md
Example Migrations
Use these examples as before/after templates.
Keep the same pattern when adding more examples:
1. input query 2. Smartscape translation sketch 3. notes about the mapping
Contents
- Example 001: `classicEntitySelector` filter without relationships
- Example 002: expanding relationships
- Example 003: `classicEntitySelector` with relationships
- Example 004: signal query with Smartscape dimension
- Example 005: `CLOUD_APPLICATION` to workload node types
- Example 006: `CLOUD_APPLICATION_INSTANCE` to `K8S_POD`
- Example 007: signal query with Smartscape tag access
- Example 008: AWS DynamoDB table field projection
- Example 009: filter by tags and host group
- Example 010: multi-cloud datacenter traversal with missing relationship handling
- Example 011: container plus affected-entity mapping
- Example 012: mass data migration end-to-end with fieldsSnapshot
- Example 013: `timeseries filter` with tag-based entity sub-query
Example 001: classicEntitySelector filter without relationships
Input
fetch dt.entity.host
| filter in(id, classicEntitySelector("type(host),tag([Environment]syn_grail_log:bastion)"))
| fields entity.name, idSmartscape sketch
smartscapeNodes HOST
| filter `tags:environment`[syn_grail_log] == "bastion"
| fields entity.name = name, idNotes
entity.namebecomesname- tag context
[Environment]becomes `tags:environment`
Example 002: expanding relationships
Input
fetch dt.entity.host
| fieldsAdd runs[dt.entity.service_instance]
| expand service_instance = runs[dt.entity.service_instance]
| fields
id,
entity.name,
service_instanceSmartscape sketch
smartscapeEdges runs_on
| filter target_type == "HOST" and source_type == "SERVICE"
| fields
id = target_id,
entity.name = getNodeName(target_id),
service_instance = source_idNotes
- use edge records when the output shape is relationship-centric
Example 003: classicEntitySelector with relationships
Input
fetch dt.entity.service
| filter in(id, classicEntitySelector("type(service), fromRelationship.runsOnHost(type(host), tag([Azure]dt_owner_email:team-ops@example.com))"))
| fields id, entity.nameSmartscape sketch
smartscapeNodes HOST
| filter `tags:azure`[dt_owner_email] == "team-ops@example.com"
| traverse runs_on, SERVICE, direction:backward
| fields id, entity.name = nameNotes
- start from the constrained side and traverse backward
Example 004: signal query with Smartscape dimension
Input
timeseries avg(dt.service.request.response_time),
by:{ dt.entity.service }Smartscape sketch
timeseries avg(dt.service.request.response_time),
by:{ dt.smartscape.service }Notes
- every
dt.entity.*signal dimension must be migrated
Example 005: CLOUD_APPLICATION to workload node types
Input
fetch dt.entity.cloud_application
| fields entity.name, kubernetesClusterName, cloudApplicationLabelsSmartscape sketch
smartscapeNodes K8S_DEPLOYMENT, K8S_DAEMONSET, K8S_STATEFULSET, K8S_REPLICASET,
K8S_REPLICATIONCONTROLLER, K8S_JOB, K8S_DEPLOYMENTCONFIG
| fields
entity.name = name,
kubernetesClusterName = k8s.cluster.name,
cloudApplicationLabels = `tags:k8s.labels`Notes
- one classic type becomes multiple workload node types
Example 006: CLOUD_APPLICATION_INSTANCE to K8S_POD
Input
fetch dt.entity.cloud_application_instance
| fields
entity.name,
workloadName,
namespaceName,
nodeName,
kubernetesClusterName = entityName(clustered_by[dt.entity.kubernetes_cluster], type:"dt.entity.kubernetes_cluster")Smartscape sketch
smartscapeNodes K8S_POD
| fields entity.name = name,
workloadName = k8s.workload.name,
namespaceName = k8s.namespace.name,
nodeName = k8s.node.name,
kubernetesClusterName = k8s.cluster.nameNotes
- use first-class
k8s.*fields onK8S_POD
Example 007: signal query with Smartscape tag access
Input
timeseries avg(dt.host.cpu.usage),
by:{ dt.entity.host }
| filter in(entityAttr(dt.entity.host, "tags"), "Dtp_Capability:grail")Smartscape sketch
timeseries avg(dt.host.cpu.usage),
by:{ dt.smartscape.host }
| filter getNodeField(dt.smartscape.host, "tags")[Dtp_Capability] == "grail"Notes
- migrate the signal dimension and replace classic tag access with
getNodeField() - use unquoted key syntax for tag-map access:
...[Dtp_Capability]; quoted keys in this pattern cause a DQL syntax error
Example 008: AWS DynamoDB table field projection
Input
fetch `dt.entity.cloud:aws:dynamodb:table`
| fields entity.name, aws_account, aws_arn, aws_region, aws_resource_type, aws_service, cloud_providerSmartscape sketch
smartscapeNodes AWS_DYNAMODB_TABLE
| fields
entity.name = name,
aws_account = aws.account.id,
aws_arn = aws.arn,
aws_region = aws.region,
parse(aws.resource.type, """ (WORD "::" WORD) "::" WORD:aws_resource_type"""),
parse(aws.resource.type, """ (WORD "::" WORD):aws_service "::" WORD"""),
cloud_provider = cloud.providerNotes
- prefer native Smartscape cloud fields; parse composite fields only when necessary
Example 009: filter by tags and host group
Input
timeseries series = avg(dt.host.cpu.usage),
filter:{
in(dt.host_group.id, array("dtp-dev101-grail"))
and in(dt.entity.host, classicEntitySelector("type(host),tag(\"Dtp_Capability:grail\")"))
and in(dt.entity.host, classicEntitySelector("type(host),tag(\"Dtp_Tier:segment-indexer-traces\")"))
},
by:{ dt.entity.host }Smartscape sketch
timeseries series = avg(dt.host.cpu.usage),
filter:{
in(dt.host_group.id, array("dtp-dev101-grail"))
and getNodeField(dt.smartscape.host, "tags")[Dtp_Capability] == "grail"
and getNodeField(dt.smartscape.host, "tags")[Dtp_Tier] == "segment-indexer-traces"
},
by:{ dt.smartscape.host }Notes
- host group remains a host field, not a traversed entity
- use unquoted key syntax for tag-map access:
...[Dtp_Capability]and...[Dtp_Tier]; quoted keys in this pattern cause a DQL syntax error
Example 010: multi-cloud datacenter traversal with missing relationship handling
Input
fetch dt.entity.host
| filterOut isMonitoringCandidate
| fieldsAdd
dt.entity.aws_availability_zone = belongs_to[dt.entity.aws_availability_zone],
dt.entity.azure_region = belongs_to[dt.entity.azure_region],
dt.entity.gcp_zone = belongs_to[dt.entity.gcp_zone]
| fieldsAdd
awsDataCenterName = entityName(dt.entity.aws_availability_zone),
azureRegionName = entityName(dt.entity.azure_region),
gcpZoneName = entityName(dt.entity.gcp_zone)
| fields
id,
entity.name,
dataCenter = coalesce(dt.entity.aws_availability_zone, dt.entity.azure_region, dt.entity.gcp_zone, "NO_DATACENTER"),
dataCenterName = coalesce(awsDataCenterName, azureRegionName, gcpZoneName, "No Data center")Smartscape sketch
smartscapeNodes HOST
| lookup [
smartscapeNodes HOST
| traverse runs_on, {AWS_EC2_INSTANCE, AZURE_MICROSOFT_COMPUTE_VIRTUALMACHINES, GCP_COMPUTE_GOOGLEAPIS_COM_INSTANCE}, direction:forward
| traverse runs_on, {AWS_AVAILABILITY_ZONE, AZURE_REGION, GCP_ZONE}, direction:forward
| fields dt.smartscape.host = dt.traverse.history[-2][id], dataCenter = id, dataCenterName = name
], sourceField:id, lookupField:dt.smartscape.host, fields:{ dataCenter, dataCenterName }
| fields
id,
entity.name = name,
dataCenter = coalesce(dataCenter, "NO_DATACENTER"),
dataCenterName = coalesce(dataCenterName, "No Data center")Notes
- use
lookupto preserve hosts without cloud relationships
Example 011: container plus affected-entity mapping
Input
fetch dt.entity.container_group_instance
| fields
id,
containerName = entity.name,
containerizationType = containerizationType,
containerGroupId = instance_of[dt.entity.container_group],
containerGroupName = entityName(instance_of[dt.entity.container_group], type:"dt.entity.container_group")
| lookup [
fetch dt.davis.events.snapshots
| filter isNotNull(affected_entity_ids)
| filter in(affected_entity_types, "dt.entity.container_group_instance")
| expand affected_entity_ids
| summarize by:{affected_entity_ids}, events = countDistinct(event.id)
], sourceField:id, lookupField:affected_entity_ids, fields: events
| fieldsAdd events = if(isNull(events), 0, else:events)
| fields id, containerName, containerizationType, containerGroupId, containerGroupName, eventsSmartscape sketch
smartscapeNodes CONTAINER
| fields
id,
containerName = name,
containerizationType = container.containerization_type,
containerGroupId = null,
containerGroupName = null
| lookup [
fetch dt.davis.events.snapshots
| filter isNotNull(smartscape.affected_entity.ids)
| filter in(smartscape.affected_entity.types, "CONTAINER")
| expand smartscape.affected_entity.ids
| fields affected_entity_ids = smartscape.affected_entity.ids, event.id
| summarize by:{affected_entity_ids}, events = countDistinct(event.id)
], sourceField:id, lookupField:affected_entity_ids, fields: events
| fieldsAdd events = if(isNull(events), 0, else:events)
| fields id, containerName, containerizationType, containerGroupId, containerGroupName, eventsNotes
container_group_instancemaps toCONTAINERcontainer_groupremains unsupported as a standalone entity- event fields become Smartscape event fields
Example 012: mass data migration end-to-end with fieldsSnapshot
This example demonstrates the full mass-data-filtering-strategy.md workflow including field discovery and verification.
Input
timeseries avg(dt.host.cpu.idle),
filter:{ in(dt.entity.host, classicEntitySelector("type(HOST),tag(Dtp_Tier:segment-indexer-traces),hostGroupName(dtp-dev101-grail)")) },
by:{ dt.entity.host }Step 1 — Resolve conditions
Two conditions extracted from the classicEntitySelector:
tag(Dtp_Tier:segment-indexer-traces)— resolved via auto-tagging rule config. The rule targets entity type HOST with condition keyHOST_TAGSreferencing a primary tag. Mapped field: tagDtp_Tierwith valuesegment-indexer-traces.hostGroupName(dtp-dev101-grail)— maps todt.host_group.idon HOST node or as enriched dimension.
Step 2 — Discover available fields
Mass data discovery:
dtctl query 'fieldsSnapshot metrics, by:{metric.key} | filter metric.key == "dt.host.cpu.idle" | fields field' --plainOutput includes: dt.entity.host, dt.smartscape.host, dt.host_group.id, host.name, ... (but NOT Dtp_Tier or host.group.name)
Node discovery:
dtctl query 'fieldsSnapshot smartscape.nodes, by:{node.type} | filter node.type == "HOST" | fields field' --plainOutput includes: host.group.name, tags, name, cloud.provider, ...
Step 3 — Select approach
dt.host_group.idis an enriched dimension on the metric -> Check 1 applies for the host group condition.Dtp_Tiertag is NOT an enriched dimension, butdt.smartscape.hostexists andtagsis available on the HOST node -> Check 2 applies for the tag condition.
Both conditions can be expressed as inline filters using a mix of direct dimension filter and getNodeField.
Migrated query
timeseries avg(dt.host.cpu.idle),
filter:{
dt.host_group.id == "dtp-dev101-grail"
AND getNodeField(dt.smartscape.host, "tags")[Dtp_Tier] == "segment-indexer-traces"
},
by:{ dt.smartscape.host }
/* Original: timeseries avg(dt.host.cpu.idle), filter:{ in(dt.entity.host, classicEntitySelector("type(HOST),tag(Dtp_Tier:segment-indexer-traces),hostGroupName(dtp-dev101-grail)")) }, by:{ dt.entity.host } */Step 4 — Verification
- Output shape: original had
timeframe,interval,avg(dt.host.cpu.idle),dt.entity.host. Migrated has same structure withdt.smartscape.hostreplacingdt.entity.host. - Probe: ran migrated query over last 5 minutes, returned 3 time series matching expected hosts.
- Host group condition confirmed via
dt.host_group.idenriched dimension; tag condition confirmed viagetNodeFieldondt.smartscape.host.
Mapping Resolution
dt.entity.hostdimension ->dt.smartscape.hosthostGroupName(X)->dt.host_group.id(enriched dimension, Check 1)tag(Dtp_Tier:X)->getNodeField(dt.smartscape.host, "tags")[Dtp_Tier](Check 2)
Notes
- Combines Check 1 (direct dimension) and Check 2 (getNodeField) in the same query when conditions map to different field types
fieldsSnapshotdiscovery was mandatory to confirmdt.host_group.idis enriched butDtp_Tieris not
Example 013: timeseries filter with tag-based entity sub-query
Input
timeseries usage=avg(dt.host.cpu.usage),
filter: { in(dt.entity.host, classicEntitySelector("type(host),tags(\"BF\")")) }Smartscape sketch
timeseries usage=avg(dt.host.cpu.usage),
filter: { dt.smartscape.host in [smartscapeNodes "HOST" | filter tags ~ "BF" | fields id] }Notes
dt.entity.host→dt.smartscape.host(standard dimension migration)in(dt.entity.host, classicEntitySelector(...))→dt.smartscape.host in [...]: thein()function does not accept execution blocks — use theinoperator (field in [execution block]) when the right-hand side is a sub-querytags("BF")in the classic selector matches hosts tagged withBF; in Smartscape,tags ~ "BF"uses substring matching on the serialized tag string, which also matches tags whose key or value containsBF— use an exact match if needed: `tags[BF] == <value>orisNotNull(tags[BF]`
Mass Data Filtering Strategy
Covers Situations 1 and 2 from the Query Purpose Classification in SKILL.md: migrating DQL queries where entities serve only as a filter on mass data (timeseries, logs, metrics). For pure entity list queries (Situation 3), return to SKILL.md.
Step 1 — Resolve the filter conditions
A. Tag-based filter — tag(X) or matchesValue(tags, "X")
Tag origins: Tags in Dynatrace have three possible sources:
>
1. Rule-based — created via auto-tagging rules (builtin:tags.auto-tagging).2. Imported — automatically applied from cloud providers (e.g., AWS tags, Azure tags, GCP labels) or other integrations. Imported tags are recognizable by a bracketed prefix in their key, e.g.[AWS]Name,[Environment]Stage.
3. Manually applied — added by users through the UI or the Dynatrace API.
>
Only rule-based tags can be migrated by inspecting the tagging rule configuration as described below. For imported or manually applied tags there is no declarative rule to resolve; you must identify the underlying entity attribute or condition that the tag represents and use that directly as the filter (treat as Step 1B). However, the values behind imported or manually applied tags may still be available as enriched dimensions on the mass data — the field discovery in Step 2 still applies and should be executed to check for a direct match.
Fetch the tagging rule config:
dtctl get settings --schema builtin:tags.auto-tagging -o json --plainFind the entry where value.name matches the tag key. Rules within a tag have OR semantics; conditions within a rule have AND semantics. If a condition key ends with _TAG, recursively resolve that tag's rule.
Propagation flags: pgToHostPropagation, pgToServicePropagation, serviceToHostPropagation mean the tag applies to a different entity type than the rule's entityType. Note which entity type the conditions actually describe — this drives approach selection in Step 3.
key:value tags: Inspect valueFormat for placeholders like {Host:Kubernetes:label//key}. If the value comes from a K8s label, k8s.workload.name is often a simpler discriminator.
Map condition keys to semantic fields via auto-tagging-field-mapping.md. Resolve *_TAG conditions recursively.
B. Explicit attribute filter — non-tag classicEntitySelector predicates
The conditions are already explicit in the selector string. Parse each predicate using entity-selector-predicates.md and map to its semantic field using the table below.
classicEntitySelector predicate | Entity type | Semantic field (mass data / smartscape node) |
|---|---|---|
entityName(X) | any | name on smartscape node; entity.name on fetch dt.entity.* |
entityId(X) | any | id_classic on smartscape node; id on fetch dt.entity.* |
hostGroupName(X) | HOST | host.group.name on HOST node (getNodeField or smartscapeNodes) |
hostGroupId(X) | HOST | dt.host_group.id (enriched) or dt.entity.host_group (entity id) |
serviceTechnologyTypes(X) | SERVICE | no enriched field; use service.technology on SERVICE smartscape node |
serviceType(X) | SERVICE | no enriched field; use service.type on SERVICE smartscape node |
databaseName(X) | SERVICE | db.namespace (enriched on spans/metrics) |
toEntityId(X) | any | id_classic on smartscape node |
k8sNamespaceName(X) | CLOUD_APPLICATION / K8S_NAMESPACE | k8s.namespace.name (enriched) |
k8sWorkloadName(X) | CLOUD_APPLICATION | k8s.workload.name (enriched) |
k8sClusterName(X) | K8S_CLUSTER | k8s.cluster.name (enriched) |
awsRegion(X) | AWS_* | aws.region (enriched) |
managementZone(X) | any | Not migratable — management zones are access-control constructs in Grail. Rewrite using the underlying entity conditions directly. |
---
Step 2 — Discover available fields (MANDATORY — execute before proceeding)
STOP. Execute the commands below now. The outputs determine which approach is viable. Do not proceed to Step 3 without these results.
2a. Inspect the mass data source
Run fieldsSnapshot on the data source from the original query to discover enriched dimensions:
dtctl query 'fieldsSnapshot metrics, by:{metric.key} | filter metric.key == "<the_metric>" | fields field' --plaindtctl query 'fieldsSnapshot logs, by:{dt.system.bucket} | filter matchesValue(dt.system.bucket, "<the_bucket>") | fields field' --plainRecord from the output:
1. Which enriched dimensions match the resolved conditions from Step 1 (e.g., k8s.namespace.name, host.name) 2. Whether a dt.smartscape.* dimension exists for the relevant entity type (e.g., dt.smartscape.host) 3. Whether a dt.entity.* dimension exists (e.g., dt.entity.host)
2b. Inspect the smartscape node type
Run fieldsSnapshot on the smartscape node type that matches the entity type from Step 1:
dtctl query 'fieldsSnapshot smartscape.nodes, by:{node.type} | filter node.type == "<TYPE>" | fields field' --plainRecord from the output: which node attributes match the resolved conditions (e.g., host.group.name, service.technology).
---
Step 3 — Select the approach
Use the discovery outputs from Step 2 to select the first matching approach. Follow this order strictly.
Check 1 → Direct dimension filter
Condition: Step 2a shows the resolved condition is available as an enriched dimension on the mass data.
timeseries avg(dt.host.cpu.idle), filter:k8s.namespace.name == "my-ns" AND k8s.workload.name == "my-app"This is the simplest and most performant path. Use it whenever possible.
Check 2 → getNodeField (same-node smartscape filter)
Condition: Step 2a shows a dt.smartscape.* dimension exists, and Step 2b shows the condition attribute is available on that node type, but the attribute is not an enriched dimension on the mass data.
timeseries avg(dt.host.cpu.idle), filter:getNodeField(dt.smartscape.host, "host.group.name") == "my-group"Multiple conditions on the same node:
timeseries avg(dt.host.cpu.idle), filter:getNodeField(dt.smartscape.host, "host.group.name") == "my-group" AND getNodeField(dt.smartscape.host, "cloud.provider") == "aws"Check 3 → in [smartscapeNodes] subquery (cross-node filter)
Condition: The condition targets a different node type than the data's smartscape dimension, or neither Check 1 nor Check 2 applies.
With dt.smartscape.* — project id:
timeseries avg(dt.host.cpu.idle), filter:dt.smartscape.host in [smartscapeNodes "PROCESS" | filter name == "Cassandra" | traverse edgeTypes: {runs_on}, targetTypes: {HOST}, direction: forward | fields id]Pattern: start at the node type that carries the condition -> filter -> traverse to target node type.
Step 4 — Verify equivalence (MANDATORY — execute before delivering)
STOP. Execute the commands below now. Do not deliver the migrated query without verification evidence.
4a. Output shape check
Compare the columns/fields between the original and migrated query. They must match. If you renamed fields (e.g., entity.name -> name), alias them back to the original names.
4b. Probe run
Validate syntax, then run the migrated query with a short timeframe:
dtctl verify query '<migrated_query>' --plaindtctl query '<migrated_query>' --plainCheck:
- Non-empty results: The query returns data. Zero rows when the original would return data means the approach selection or field mapping is wrong — go back to Step 2.
- Plausible values: Spot-check that metric values, entity names, and row counts are reasonable.
If the original query can still execute (deprecated constructs may still work temporarily), run both side-by-side and compare row counts and a sample of values.
4c. Document deviations
If exact equivalence is not achievable, add a leading comment:
/* Migration note: <what differs and why> */---
Critical constraints
| Constraint | Detail |
|---|---|
PROCESS_GROUP node type does not exist | Only PROCESS is available in smartscapeNodes. Substituting may over-select. |
| Nested array fields | e.g. process.software_technologies[].type — cannot be filtered in smartscapeNodes expressions. |
dt.smartscape.* vs dt.entity.* | Check 2 requires dt.smartscape.*. Check 3 works with both (id for smartscape, id_classic for entity). |
fetch dt.entity.* has no Grail tags | Rule-based tags are not present on smartscape nodes. Always resolve to underlying conditions (Step 1A). |
managementZone(X) is not migratable | Management zones are access-control constructs; no equivalent attribute exists. |
---
Checklist (condensed)
Use this as a sequential checklist. Each step has a required output.
1. Classify — Mass data query (Pattern A) or entity list sub-source (Pattern B)? -> output: pattern type 2. Resolve conditions — tag(X) -> Step 1A (dtctl get settings). Explicit predicate -> Step 1B (lookup table). -> output: list of (entity type, field, value) conditions 3. Discover fields — Execute dtctl query 'fieldsSnapshot ...' on the mass data source AND the smartscape node type. -> output: list of available enriched dimensions and node attributes 4. Select approach — Walk Check 1 -> Check 2 -> Check 3 using the discovery outputs. -> output: selected approach with rationale 5. Write query — Apply the selected approach. Include the original as a /* */ trailing comment. 6. Verify — Execute dtctl verify query then dtctl query on the migrated query, confirm non-empty results, check output shape matches original. -> output: verification evidence (row count, field comparison) 7. Deliver — Return the migrated query with mapping resolution and any open assumptions.
---
When to abandon
Return the original query with a /* */ comment explaining the closest approximation if:
- No viable approach exists for the resolved conditions.
- 3+ distinct approaches tried and failed.
- Verification (Step 4) shows non-equivalent results that cannot be reconciled.
/* Migration not completed: <reason>. Closest approximation: <what was tried>. */
<original query unchanged>Migration Workflow
Contents
- Purpose
- Required Input
- Query Purpose Gate
- Step-by-Step Process
- Core Rules
- Signal and Event Rules
- Tag Matching Rules
- Traverse Guidance
- Output Expectations
- When to Load More References
Purpose
Use this workflow when converting classic or Gen2 entity-based DQL to Smartscape DQL.
This reference is based on the source prompt pack and keeps the same migration order, but reformats it for skill usage.
Required Input
The minimum required input is the classic DQL query.
Infer the intent, timeframe, relationships, output shape, and likely Smartscape replacements from the query itself. If something cannot be confirmed from the mapping references, state the assumption explicitly.
Query Purpose Gate
Before mapping types, determine what role entities play in the query.
- Entities serve only as a filter on mass data (timeseries, logs, metrics) — the real output is metric values, log records, or trace spans, and the entity condition merely narrows which data to include. Load mass-data-filtering-strategy.md and complete all steps — including the mandatory
fieldsSnapshotdiscovery (Step 2) and equivalence verification (Step 4). Do not write the migrated query before runningfieldsSnapshot. Return here only if you need entity-type mapping or relationship traversal to complete a Smartscape subquery.
- Entities are the primary output — the query lists, counts, or describes entities. This is a pure entity list query. Continue with the Step-by-Step Process below.
Step-by-Step Process
1. Consult mappings first. Do not skip this.
- type-mappings.md — classic entity type to Smartscape node type and field mappings
- relationship-mappings.md — valid edges per type
2. Detect the input pattern:
fetch dt.entity.*classicEntitySelector(...)- signal query with
dt.entity.*dimensions - event query using classic entity fields
3. Extract the important parts:
- entity types
- filters
- relationships
- projected fields
- timeframe
4. Map types, fields, and edges using the reference files. 5. Build the Smartscape query with the appropriate primitives:
smartscapeNodessmartscapeEdgestraversefilterfields,fieldsAdd,fieldsRemovegetNodeField()andgetNodeName()only when needed
6. Validate the translation:
- timeframe or topology lifetime changes
- missing or unsupported fields
- special cases such as host group or process group
7. Return the migrated query along with the mapping resolution and any open assumptions.
Core Rules
- Node types are uppercase and unquoted:
smartscapeNodes HOST - Do not use
id_classic; use Smartscapeid - Prefer
nameovergetNodeName()when querying nodes directly getNodeName()accepts only an ID; do not pass atype:argument- Avoid
entityAttr()andentityName()in the migrated query; use direct fields orgetNodeField()/getNodeName()as needed | fieldsremoves all other fields; use| fieldsAddif you need to preserve existing ones- Prefer
dt.smartscape.<type>dimensions in signal queries smartscapeNodessupportsfrom:andto:for historical topology queries- Add explicit assumptions when the exact Smartscape equivalent is unclear
Signal and Event Rules
- Every
dt.entity.*dimension in signal queries must be migrated to the correctdt.smartscape.*field - This applies to:
by:{}filterfieldsAddexpand- helper functions using entity dimensions
- Event fields migrate as follows:
affected_entity_ids→smartscape.affected_entity.idsaffected_entity_types→smartscape.affected_entity.typesdt.source_entity.type→dt.smartscape_source.type
Tag Matching Rules
- Node queries:
- classic
in(tags, "[CONTEXT]key:value") - becomes `
tags:renamedContext[key] == "value"` - Signal queries:
- use
getNodeField(dt.smartscape.<type>, "tags:<context>")[key] == "value"
Traverse Guidance
- Multiple targets:
| traverse runs_on, {AWS_EC2_INSTANCE, AZURE_MICROSOFT_COMPUTE_VIRTUALMACHINES, GCP_COMPUTE_GOOGLEAPIS_COM_INSTANCE}- Multiple edge types:
| traverse {runs_on, belongs_to}, {AWS_AVAILABILITY_ZONE, AZURE_REGION}- Chained traversal:
- HOST → VM → DATACENTER
fieldsKeep
fieldsKeep preserves source node fields through traversal. After traversal, id and name refer to the target node, and the source fields are available via dt.traverse.history.
smartscapeNodes CONTAINER
| traverse runs_on, HOST, direction:forward, fieldsKeep:name
| fieldsAdd
containerName = dt.traverse.history[0][name],
containerId = dt.traverse.history[0][id],
hostId = id,
hostName = namePreserving entities without relationships
Use lookup when you must preserve entities even if the traversal has no match.
smartscapeNodes HOST
| lookup [
smartscapeNodes HOST
| traverse runs_on, {AWS_EC2_INSTANCE, AZURE_MICROSOFT_COMPUTE_VIRTUALMACHINES, GCP_COMPUTE_GOOGLEAPIS_COM_INSTANCE}, direction:forward
| traverse {runs_on, belongs_to}, {AWS_AVAILABILITY_ZONE, AZURE_REGION, GCP_ZONE}, direction:forward, fieldsKeep:name
| fieldsAdd dataCenter = id, dataCenterName = name, host_id = dt.traverse.history[0][id]
| fields host_id, dataCenter, dataCenterName
], sourceField:id, lookupField:host_id, fields:{dataCenter, dataCenterName}
| fields id,
dataCenter = coalesce(dataCenter, "NO_DATACENTER"),
dataCenterName = coalesce(dataCenterName, "No Data center")Output Expectations
Every final translation should include:
1. the Smartscape DQL in a code block 2. a Mapping Resolution section 3. open assumptions, if any 4. verification evidence — for Situation 1/2 migrations (mass data), include which fieldsSnapshot queries were run, the selected approach with rationale, and the result of the equivalence check (row count comparison, output shape match)
Suggested format:
## Mapping Resolution
Applied mappings:
- dt.entity.container_group_instance → CONTAINER
- dt.entity.host → HOST
Applied edge mappings:
- CONTAINER runs_on HOST
## Verification
- fieldsSnapshot on metrics confirmed `k8s.namespace.name` as enriched dimension
- Approach: direct dimension filter (Check 1)
- Probe: migrated query returned 42 rows over last 5m, matching originalWhen to Load More References
- Load dql-function-migration.md when the hard part is a specific function or pattern
- Load special-cases.md when the query mentions host group, process group, container group, or classic IDs
- Load examples.md when you need a before/after template
Quick Reference
Use this page as a compact cheat sheet during Smartscape migration.
Core rules
- Use
smartscapeNodes,smartscapeEdges, andtraversefor topology queries - Smartscape node
typevalues are uppercase and unquoted insmartscapeNodes - Prefer Smartscape dimensions (
dt.smartscape.<type>) in signal queries - Prefer direct node fields like
name; usegetNodeName()only when you only have an ID - Use
getNodeField(dt.smartscape.<type>, "tags:<context>")[key] == "value"for tag matching in signal queries - Classic tag filter
in(tags, "[CONTEXT]key:value")becomes `tags:renamedContext[key] == "value"` in node queries - Do not use
id_classic; use Smartscapeid | fieldsdrops other fields; use| fieldsAddwhen you need to preserve them
Traversal tips
- Multiple target types:
| traverse runs_on, {AWS_EC2_INSTANCE, AZURE_MICROSOFT_COMPUTE_VIRTUALMACHINES, GCP_COMPUTE_GOOGLEAPIS_COM_INSTANCE}- Multiple edge types:
| traverse {runs_on, belongs_to}, {AWS_AVAILABILITY_ZONE, AZURE_REGION}- Preserve source fields through traversal:
| traverse runs_on, HOST, direction:forward, fieldsKeep:name- Starting node after traversal:
dt.traverse.history[0][id]
Event field updates
affected_entity_ids→smartscape.affected_entity.idsaffected_entity_types→smartscape.affected_entity.typesdt.source_entity.type→dt.smartscape_source.type
Common gotchas
Mass data migrations require fieldsSnapshot before approach selection
Run fieldsSnapshot on both the mass data source and the smartscape node type before choosing direct dimension filter, getNodeField, or smartscapeNodes subquery. See mass-data-filtering-strategy.md Step 2.
Always verify equivalence
Run the migrated query with a short timeframe. Confirm non-empty results and matching output shape. See mass-data-filtering-strategy.md Step 4.
getNodeName() takes no type: argument
getNodeName(someId)not:
getNodeName(someId, type: "HOST")Host group is not an entity
Do not traverse to HOST_GROUP. Use host fields like dt.host_group.id on HOST.
All dt.entity.* dimensions must become dt.smartscape.*
Apply this everywhere in signal and event queries:
timeseries by:{}filterfieldsAddexpandsummarize by:{}
references is for static edges
Use references[...] when the relationship is static. Use traverse for general navigation.
smartscapeNodes supports from: and to:
Use historical topology when the classic query has an explicit timeframe.
Where to go next
- Full mappings: type-mappings.md
- Full edges: relationship-mappings.md
- Function migration: dql-function-migration.md
- Examples: examples.md
dt-migration references
Use these references with SKILL.md.
Read This First
1. Start with `../SKILL.md` for scope, use cases, and the Query Purpose Classification — this determines which path to take. 2. For mass data queries filtered by entity conditions (Situations 1 and 2), load `mass-data-filtering-strategy.md` before anything else. 3. For pure entity list queries (Situation 3), load `migration-workflow.md` for the step-by-step migration process. 4. Then choose the most relevant deep reference for the task at hand.
Reference Map
| File | When to use |
|---|---|
| `mass-data-filtering-strategy.md` | The query filters mass data (timeseries/logs/metrics) by entity conditions — primary strategy guide for Situations 1 and 2 |
| `auto-tagging-field-mapping.md` | Resolving a tag(X) filter from an auto-tagging rule — maps rule condition keys to semantic dictionary fields |
| `entity-selector-predicates.md` | Looking up an unfamiliar predicate inside a classicEntitySelector(...) string |
| `migration-workflow.md` | You need the end-to-end migration process, validation checklist, and output structure |
| `type-mappings.md` | You need the full classic-to-Smartscape entity and field mapping tables |
| `dql-function-migration.md` | You need to migrate entityName(), entityAttr(), selectors, relationship fields, signal dimensions, or ID filters |
| `relationship-mappings.md` | You need to verify valid Smartscape edges and traversal targets |
| `special-cases.md` | The query uses host group, process group, container group, or unsupported mappings |
| `quick-reference.md` | You need a compact cheat sheet or gotcha list |
| `examples.md` | You need concrete before/after migration patterns |
| `entity-host.md` | The migration centers on hosts, host tags, host groups, or host traversal |
| `entity-service.md` | The migration centers on services, service relationships, or service signal dimensions |
| `entity-process.md` | The migration centers on process-group-instance or process-group patterns |
| `entity-container.md` | The migration centers on container-group-instance, container group, or affected-entity event joins |
| `entity-kubernetes.md` | The migration centers on Kubernetes cluster, node, service, namespace, pod, or workload entities |
| `entity-cloud-application.md` | The migration centers on cloud_application, cloud_application_instance, or cloud_application_namespace |
Related Skills
- Load
dt-dql-essentialsbefore writing final DQL.
Relationship Mappings
Use this reference to verify which Smartscape edges are valid when rewriting classic relationships to traverse, smartscapeEdges, or references.
Contents
How to use this file
- Use
traverseto navigate edges in topology queries - Use
smartscapeEdgeswhen you want edge-centric records - Use
references[...]only for static edges
Edge types
| Source Type | Edge Type | Target Type | Edge Kind |
|---|---|---|---|
AWS_APIGATEWAYV2_STAGE | is_attached_to | AWS_APIGATEWAYV2_API | static |
AWS_APIGATEWAY_STAGE | is_attached_to | AWS_APIGATEWAY_RESTAPI | static |
AWS_AUTOSCALING_AUTOSCALINGGROUP | contains | AWS_EC2_INSTANCE | static |
AWS_AUTOSCALING_AUTOSCALINGGROUP | is_attached_to | AWS_ELASTICLOADBALANCINGV2_TARGETGROUP | static |
AWS_AUTOSCALING_AUTOSCALINGGROUP | is_attached_to | AWS_ELASTICLOADBALANCING_LOADBALANCER | static |
AWS_AUTOSCALING_AUTOSCALINGGROUP | runs_on | AWS_AVAILABILITY_ZONE | static |
AWS_AUTOSCALING_AUTOSCALINGGROUP | uses | AWS_EC2_LAUNCHTEMPLATE | static |
AWS_AVAILABILITY_ZONE | is_part_of | AWS_REGION | static |
AWS_CLOUDFRONT_DISTRIBUTION | is_attached_to | AWS_CERTIFICATEMANAGER_CERTIFICATE | static |
AWS_CLOUDFRONT_DISTRIBUTION | is_attached_to | AWS_WAFV2_WEBACL | static |
AWS_CLOUDFRONT_DISTRIBUTION | routes_to | AWS_S3_BUCKET | static |
AWS_CLOUDTRAIL_TRAIL | uses | AWS_KMS_KEY | static |
AWS_CLOUDTRAIL_TRAIL | uses | AWS_S3_BUCKET | static |
AWS_DMS_REPLICATIONINSTANCE | is_attached_to | AWS_EC2_SUBNET | static |
AWS_DMS_REPLICATIONINSTANCE | is_attached_to | AWS_EC2_VPC | static |
AWS_DMS_REPLICATIONINSTANCE | runs_on | AWS_AVAILABILITY_ZONE | static |
AWS_DMS_REPLICATIONINSTANCE | uses | AWS_EC2_SECURITYGROUP | static |
AWS_DYNAMODB_TABLE | uses | AWS_KMS_KEY | static |
AWS_EC2_EIP | is_attached_to | AWS_EC2_INSTANCE | static |
AWS_EC2_EIP | is_attached_to | AWS_EC2_NETWORKINTERFACE | static |
AWS_EC2_INSTANCE | is_attached_to | AWS_EC2_SUBNET | static |
AWS_EC2_INSTANCE | is_attached_to | AWS_EC2_VPC | static |
AWS_EC2_INSTANCE | runs_on | AWS_AVAILABILITY_ZONE | static |
AWS_EC2_INSTANCE | uses | AWS_EC2_SECURITYGROUP | static |
AWS_EC2_INSTANCE | uses | AWS_IAM_INSTANCEPROFILE | static |
AWS_EC2_NETWORKINTERFACE | is_attached_to | AWS_EC2_INSTANCE | static |
AWS_EC2_NETWORKINTERFACE | is_attached_to | AWS_EC2_SUBNET | static |
AWS_EC2_NETWORKINTERFACE | is_attached_to | AWS_EC2_VPC | static |
AWS_EC2_NETWORKINTERFACE | runs_on | AWS_AVAILABILITY_ZONE | static |
AWS_EC2_NETWORKINTERFACE | uses | AWS_EC2_SECURITYGROUP | static |
AWS_EC2_SUBNET | is_attached_to | AWS_EC2_VPC | static |
AWS_EC2_SUBNET | runs_on | AWS_AVAILABILITY_ZONE | static |
AWS_EC2_VOLUME | is_attached_to | AWS_EC2_INSTANCE | static |
AWS_EC2_VOLUME | runs_on | AWS_AVAILABILITY_ZONE | static |
AWS_EC2_VOLUME | uses | AWS_KMS_KEY | static |
AWS_ECS_SERVICE | balanced_by | AWS_ELASTICLOADBALANCINGV2_TARGETGROUP | static |
AWS_ECS_SERVICE | belongs_to | AWS_ECS_CLUSTER | static |
AWS_ECS_SERVICE | is_attached_to | AWS_EC2_SUBNET | static |
AWS_ECS_SERVICE | uses | AWS_EC2_SECURITYGROUP | static |
AWS_ECS_SERVICE | uses | AWS_ECS_TASKDEFINITION | static |
AWS_ECS_SERVICE | uses | AWS_IAM_ROLE | static |
AWS_ECS_TASK | belongs_to | AWS_ECS_CLUSTER | static |
AWS_ECS_TASK | is_part_of | AWS_ECS_SERVICE | static |
AWS_ECS_TASK | runs_on | AWS_AVAILABILITY_ZONE | static |
AWS_ECS_TASK | uses | AWS_EC2_NETWORKINTERFACE | static |
AWS_ECS_TASK | uses | AWS_EC2_SUBNET | static |
AWS_ECS_TASK | uses | AWS_ECS_TASKDEFINITION | static |
AWS_EKS_CLUSTER | is_attached_to | AWS_EC2_SUBNET | static |
AWS_EKS_CLUSTER | is_attached_to | AWS_EC2_VPC | static |
AWS_EKS_CLUSTER | uses | AWS_EC2_SECURITYGROUP | static |
AWS_EKS_CLUSTER | uses | AWS_IAM_ROLE | static |
AWS_EKS_CLUSTER | uses | AWS_KMS_KEY | static |
AWS_EKS_NODEGROUP | belongs_to | AWS_EKS_CLUSTER | static |
AWS_EKS_NODEGROUP | is_attached_to | AWS_EC2_SUBNET | static |
AWS_EKS_NODEGROUP | uses | AWS_EC2_LAUNCHTEMPLATE | static |
AWS_EKS_NODEGROUP | uses | AWS_IAM_ROLE | static |
AWS_ELASTICLOADBALANCINGV2_LOADBALANCER | is_attached_to | AWS_EC2_SUBNET | static |
AWS_ELASTICLOADBALANCINGV2_LOADBALANCER | is_attached_to | AWS_EC2_VPC | static |
AWS_ELASTICLOADBALANCINGV2_LOADBALANCER | runs_on | AWS_AVAILABILITY_ZONE | static |
AWS_ELASTICLOADBALANCINGV2_LOADBALANCER | uses | AWS_EC2_SECURITYGROUP | static |
AWS_ELASTICLOADBALANCINGV2_TARGETGROUP | balanced_by | AWS_ELASTICLOADBALANCINGV2_LOADBALANCER | static |
AWS_ELASTICLOADBALANCINGV2_TARGETGROUP | balances | AWS_EC2_INSTANCE | static |
AWS_ELASTICLOADBALANCING_LOADBALANCER | balances | AWS_EC2_INSTANCE | static |
AWS_ELASTICLOADBALANCING_LOADBALANCER | is_attached_to | AWS_EC2_SUBNET | static |
AWS_ELASTICLOADBALANCING_LOADBALANCER | is_attached_to | AWS_EC2_VPC | static |
AWS_ELASTICLOADBALANCING_LOADBALANCER | runs_on | AWS_AVAILABILITY_ZONE | static |
AWS_ELASTICLOADBALANCING_LOADBALANCER | uses | AWS_CERTIFICATEMANAGER_CERTIFICATE | static |
AWS_ELASTICLOADBALANCING_LOADBALANCER | uses | AWS_EC2_SECURITYGROUP | static |
AWS_LAMBDA_FUNCTION | is_attached_to | AWS_EC2_SUBNET | static |
AWS_LAMBDA_FUNCTION | is_attached_to | AWS_EC2_VPC | static |
AWS_LAMBDA_FUNCTION | uses | AWS_EC2_SECURITYGROUP | static |
AWS_LAMBDA_FUNCTION | uses | AWS_IAM_ROLE | static |
AWS_LAMBDA_FUNCTION | uses | AWS_KMS_KEY | static |
AWS_RDS_DBINSTANCE | is_attached_to | AWS_EC2_SUBNET | static |
AWS_RDS_DBINSTANCE | is_attached_to | AWS_EC2_VPC | static |
AWS_RDS_DBINSTANCE | is_part_of | AWS_RDS_DBCLUSTER | static |
AWS_RDS_DBINSTANCE | runs_on | AWS_AVAILABILITY_ZONE | static |
AWS_RDS_DBINSTANCE | uses | AWS_EC2_SECURITYGROUP | static |
AWS_RDS_DBINSTANCE | uses | AWS_KMS_KEY | static |
AWS_RDS_DBINSTANCE | uses | AWS_RDS_OPTIONGROUP | static |
CONTAINER | belongs_to | K8S_CLUSTER | static |
CONTAINER | belongs_to | K8S_NAMESPACE | static |
CONTAINER | is_part_of | K8S_CRONJOB | static |
CONTAINER | is_part_of | K8S_DAEMONSET | static |
CONTAINER | is_part_of | K8S_DEPLOYMENT | static |
CONTAINER | is_part_of | K8S_JOB | static |
CONTAINER | is_part_of | K8S_POD | static |
CONTAINER | is_part_of | K8S_REPLICASET | static |
CONTAINER | is_part_of | K8S_STATEFULSET | static |
CONTAINER | runs_on | HOST | static |
CONTAINER | runs_on | K8S_NODE | static |
DISK | belongs_to | HOST | static |
HOST | calls | HOST | dynamic |
HOST | runs_on | AWS_EC2_INSTANCE | static |
HOST | runs_on | AZURE_MICROSOFT_COMPUTE_VIRTUALMACHINES | static |
HOST | runs_on | GCP_COMPUTE_GOOGLEAPIS_COM_INSTANCE | static |
K8S_CLUSTER | uses | AWS_EC2_SECURITYGROUP | static |
K8S_CRONJOB | belongs_to | K8S_CLUSTER | static |
K8S_CRONJOB | belongs_to | K8S_NAMESPACE | static |
K8S_DAEMONSET | belongs_to | K8S_CLUSTER | static |
K8S_DAEMONSET | belongs_to | K8S_NAMESPACE | static |
K8S_DEPLOYMENT | belongs_to | K8S_CLUSTER | static |
K8S_DEPLOYMENT | belongs_to | K8S_NAMESPACE | static |
K8S_INGRESS | belongs_to | K8S_CLUSTER | static |
K8S_INGRESS | belongs_to | K8S_NAMESPACE | static |
K8S_INGRESS | routes_to | K8S_SERVICE | static |
K8S_JOB | belongs_to | K8S_CLUSTER | static |
K8S_JOB | belongs_to | K8S_NAMESPACE | static |
K8S_JOB | is_part_of | K8S_CRONJOB | static |
K8S_NAMESPACE | belongs_to | K8S_CLUSTER | static |
K8S_NODE | belongs_to | K8S_CLUSTER | static |
K8S_PERSISTENTVOLUMECLAIM | belongs_to | K8S_CLUSTER | static |
K8S_PERSISTENTVOLUMECLAIM | belongs_to | K8S_NAMESPACE | static |
K8S_PERSISTENTVOLUMECLAIM | uses | K8S_PERSISTENTVOLUME | static |
K8S_POD | belongs_to | K8S_CLUSTER | static |
K8S_POD | belongs_to | K8S_NAMESPACE | static |
K8S_POD | is_part_of | K8S_CRONJOB | static |
K8S_POD | is_part_of | K8S_DAEMONSET | static |
K8S_POD | is_part_of | K8S_DEPLOYMENT | static |
K8S_POD | is_part_of | K8S_JOB | static |
K8S_POD | is_part_of | K8S_REPLICASET | static |
K8S_POD | is_part_of | K8S_STATEFULSET | static |
K8S_POD | runs_on | K8S_NODE | static |
K8S_POD | uses | K8S_CONFIGMAP | static |
K8S_POD | uses | K8S_PERSISTENTVOLUMECLAIM | static |
K8S_POD | uses | K8S_SECRET | static |
K8S_REPLICASET | belongs_to | K8S_CLUSTER | static |
K8S_REPLICASET | belongs_to | K8S_NAMESPACE | static |
K8S_REPLICASET | is_part_of | K8S_DEPLOYMENT | static |
K8S_SECRET | belongs_to | K8S_CLUSTER | static |
K8S_SECRET | belongs_to | K8S_NAMESPACE | static |
K8S_SERVICE | belongs_to | K8S_CLUSTER | static |
K8S_SERVICE | belongs_to | K8S_NAMESPACE | static |
K8S_SERVICE | routes_to | K8S_POD | static |
K8S_STATEFULSET | belongs_to | K8S_CLUSTER | static |
K8S_STATEFULSET | belongs_to | K8S_NAMESPACE | static |
NETWORK_INTERFACE | belongs_to | HOST | static |
ONEAGENT | monitors | HOST | static |
PROCESS | calls | PROCESS | dynamic |
PROCESS | runs_on | CONTAINER | static |
PROCESS | runs_on | HOST | static |
SERVICE | belongs_to | K8S_CLUSTER | dynamic |
SERVICE | belongs_to | K8S_DEPLOYMENT | dynamic |
SERVICE | belongs_to | K8S_NAMESPACE | dynamic |
SERVICE | belongs_to | K8S_STATEFULSET | dynamic |
SERVICE | calls | SERVICE | dynamic |
SERVICE | runs_on | CONTAINER | dynamic |
SERVICE | runs_on | HOST | dynamic |
SERVICE | runs_on | K8S_POD | dynamic |
SERVICE | runs_on | PROCESS | dynamic |
Standardized edge types
| Edge Type | Description |
|---|---|
belongs_to | Membership or containment relationship |
calls | Communication or invocation |
contains | Parent contains child entities |
is_attached_to | Attachment or association |
is_part_of | Composition relationship |
routes_to | Traffic or request routing |
runs_on | Execution environment relationship |
uses | Dependency or utilization relationship |
balances | Load-balancing relationship |
balanced_by | Reverse load-balancing relationship |
monitors | Monitoring relationship |
Examples
Querying edges directly
smartscapeEdges "runs_on"
| filter source_type == "SERVICE" and target_type == "HOST"
| fields source_id, source_name = getNodeName(source_id), target_id, target_name = getNodeName(target_id)Following an edge with traverse
smartscapeNodes HOST
| filter `tags:azure`[dt_owner_email] == "team-ops@example.com"
| traverse runs_on, SERVICE, direction:backwardUsing references for static edges
smartscapeNodes NETWORK_INTERFACE
| fieldsAdd host = references[belongs_to.host]Note on completeness
This file contains the migration-relevant edge set extracted from the source repository. If a migration depends on an edge not listed here, verify it directly in the target environment before assuming availability.
Special Cases
Use this reference before translating classic entity patterns literally. Several classic entity concepts are not modeled as standalone Smartscape node types.
Contents
Host group
dt.entity.host_group is not a separate Smartscape entity.
What to do instead
- query
HOST - use host fields such as
dt.host_group.id - if the classic query expects a host-group ID that no longer exists as a standalone entity, preserve the output shape with
nullor use the host-group name if grouping still requires a value
Example
Classic:
fetch dt.entity.host
| fields id, entity.name, hostGroupNameSmartscape:
smartscapeNodes HOST
| fields id, entity.name = name, hostGroupName = `dt.host_group.id`Process group
dt.entity.process_group is not a separate Smartscape entity.
What to do instead
- query
PROCESS - use
dt.process_group.id,dt.process_group.name, ordt.process_group.detected_name - summarize if you need one row per process group rather than one row per process
Example
Classic:
fetch dt.entity.process_group
| fields id, entity.name, metadataSmartscape:
smartscapeNodes PROCESS
| summarize by:{ id = dt.process_group.id, entity.name = dt.process_group.detected_name }, process.metadata = takeAny(process.metadata)Container group
dt.entity.container_group is not a separate Smartscape entity.
What to do instead
- treat
dt.entity.container_group_instanceasCONTAINER - when the classic query asks for container-group identity or name, preserve the output shape with
nullplaceholders if there is no real Smartscape equivalent
Example
Classic:
fetch dt.entity.container_group_instance
| fields
id,
containerGroupId = instance_of[dt.entity.container_group],
containerGroupName = entityName(instance_of[dt.entity.container_group], type:"dt.entity.container_group")Smartscape:
smartscapeNodes CONTAINER
| fields
id,
containerGroupId = null,
containerGroupName = nullClassic IDs
Classic entity IDs do not carry over automatically to Smartscape IDs. The suffix changes.
Rules
- do not reuse classic entity IDs blindly
- do not use
id_classic - use Smartscape
id - if the correct Smartscape ID is unknown, add an explicit assumption and a lookup hint
Example lookup hint:
smartscapeNodes HOST
| fields id, nameMissing or planned mappings
The mapping table distinguishes between:
- available — direct mapping is already known
- planned — a Smartscape replacement is expected but may not be fully usable yet
- missing or unclear — direct replacement is not confirmed
- not planned — do not expect a direct Smartscape entity replacement
Guidance
- If the mapping is available, translate directly.
- If the mapping is planned, translate cautiously and call out the assumption.
- If the mapping is missing or unclear, avoid pretending the mapping is certain.
- If the mapping is not planned, work around it with fields, placeholders, or a different starting entity.
Related references
- type-mappings.md — full table and status values
- entity-host.md — host and host-group migration patterns
- entity-process.md — process-group-instance and process-group patterns
- entity-container.md — container migration patterns
Type and Field Mappings
Use this reference when you need the full classic-to-Smartscape mapping set.
Contents
- How to read this table
- Type mappings
- Special cases: entities that are no longer standalone types
- Field mappings
- Related references
How to read this table
- Classic entity type and field name appears in classic queries such as
fetch dt.entity.<type>or signal filters usingdt.entity.* - Smartscape id field name is the signal or helper field to use in Smartscape-aware signal queries
- Smartscape type is the node type used with
smartscapeNodes - Status indicates how certain the mapping is:
available— already availableplanned— expected to be availableunclear— direct mapping not confirmednot planned— no direct Smartscape replacement should be assumed
Type mappings
| Classic entity type and field name | Smartscape id field name | Smartscape type | Status |
|---|---|---|---|
dt.entity.application | dt.smartscape.frontend | FRONTEND | available |
dt.entity.auto_scaling_group | dt.smartscape.aws_autoscaling_autoscalinggroup | AWS_AUTOSCALING_AUTOSCALINGGROUP | available |
dt.entity.aws_availability_zone | dt.smartscape.aws_availability_zone | AWS_AVAILABILITY_ZONE | available |
dt.entity.aws_credentials | dt.smartscape.aws_account | AWS_ACCOUNT | available |
dt.entity.aws_lambda_function | dt.smartscape.aws.lambda_function | AWS_LAMBDA_FUNCTION | available |
dt.entity.azure_region | dt.smartscape.azure_microsoft_resources_locations | AZURE_MICROSOFT_RESOURCES_LOCATIONS | available |
dt.entity.azure_subscription | dt.smartscape.azure_microsoft_resources_subscriptions | AZURE_MICROSOFT_RESOURCES_SUBSCRIPTIONS | available |
dt.entity.azure_vm | dt.smartscape.azure_microsoft_compute_virtualmachines | AZURE_MICROSOFT_COMPUTE_VIRTUALMACHINES | available |
dt.entity.azure_vm_scale_set | dt.smartscape.azure_microsoft_compute_virtualmachinescalesets | AZURE_MICROSOFT_COMPUTE_VIRTUALMACHINESCALESETS | available |
dt.entity.cloud:aws:lambda | dt.smartscape.aws.lambda_function | AWS_LAMBDA_FUNCTION | available |
dt.entity.cloud:gcp:cloudsql_database | <missing> | <missing> | unclear |
dt.entity.cloud_application | dt.smartscape.k8s_deployment, dt.smartscape.k8s_daemonset, dt.smartscape.k8s_statefulset, dt.smartscape.k8s_replicaset, dt.smartscape.k8s_replicationcontroller, dt.smartscape.k8s_job, dt.smartscape.k8s_deploymentconfig | K8S_DEPLOYMENT, K8S_DAEMONSET, K8S_STATEFULSET, K8S_REPLICASET, K8S_REPLICATIONCONTROLLER, K8S_JOB, K8S_DEPLOYMENTCONFIG | available |
dt.entity.cloud_application_instance | dt.smartscape.k8s_pod | K8S_POD | available |
dt.entity.cloud_application_namespace | dt.smartscape.k8s_namespace | K8S_NAMESPACE | available |
dt.entity.container_group | <removed> | <removed> | not planned |
dt.entity.container_group_instance | dt.smartscape.container | CONTAINER | available |
dt.entity.custom_application | dt.smartscape.frontend | FRONTEND | available |
dt.entity.custom_device | <removed> | <removed> | not planned |
dt.entity.custom_device_group | <removed> | <removed> | not planned |
dt.entity.disk | dt.smartscape.disk | DISK | available |
dt.entity.ec2_instance | dt.smartscape.aws_ec2_instance | AWS_EC2_INSTANCE | available |
dt.entity.ebs_volume | dt.smartscape.aws_ec2_volume | AWS_EC2_VOLUME | available |
dt.entity.elasticsearch:cluster | <missing> | <missing> | unclear |
dt.entity.elasticsearch:index | <missing> | <missing> | unclear |
dt.entity.elasticsearch:node | <missing> | <missing> | unclear |
dt.entity.elasticsearch:thread_pool | <missing> | <missing> | unclear |
dt.entity.environment | <removed> | <removed> | not planned |
dt.entity.gcp_zone | <missing> | <missing> | unclear |
dt.entity.haproxy-prometheus:server | <missing> | <missing> | unclear |
dt.entity.host | dt.smartscape.host | HOST | available |
dt.entity.host_group | <removed> | <removed> | not planned |
dt.entity.http_check | dt.smartscape.http_check | HTTP_CHECK | planned |
dt.entity.http_check_step | dt.smartscape.http_check_step | HTTP_CHECK_STEP | planned |
dt.entity.kafka:consumer | <missing> | <missing> | unclear |
dt.entity.kafka:producer | <missing> | <missing> | unclear |
dt.entity.kafka:topic | <missing> | <missing> | unclear |
dt.entity.kubernetes_cluster | dt.smartscape.k8s_cluster | K8S_CLUSTER | available |
dt.entity.kubernetes_node | dt.smartscape.k8s_node | K8S_NODE | available |
dt.entity.kubernetes_service | dt.smartscape.k8s_service | K8S_SERVICE | available |
dt.entity.network_interface | dt.smartscape.network_interface | NETWORK_INTERFACE | available |
dt.entity.os:service | dt.smartscape.os_service | OS_SERVICE | planned |
dt.entity.process_group | <removed> | <removed> | not planned |
dt.entity.process_group_instance | dt.smartscape.process | PROCESS | available |
dt.entity.relational_database_service | dt.smartscape.aws_rds_dbinstance | AWS_RDS_DBINSTANCE | available |
dt.entity.service | dt.smartscape.service | SERVICE | available |
dt.entity.service_instance | dt.smartscape.service_deployment | SERVICE_DEPLOYMENT | planned |
dt.entity.standardised:slo | <missing> | <missing> | unclear |
dt.entity.synthetic_location | dt.smartscape.synthetic_location | SYNTHETIC_LOCATION | planned |
dt.entity.synthetic_test | dt.smartscape.synthetic_test | SYNTHETIC_TEST | planned |
dt.entity.synthetic_test_step | dt.smartscape.synthetic_test_step | SYNTHETIC_TEST_STEP | planned |
Special cases: entities that are no longer standalone types
Host group
| Classic | Smartscape |
|---|---|
dt.entity.host_group | Not a separate Smartscape entity |
entity.name, entityName(dt.entity.host_group) | available as dt.host_group.id on HOST; despite the field name, it is the usable host-group label |
id | no standalone host-group ID in Smartscape |
Example:
smartscapeNodes HOST
| fields id, entity.name = name, hostGroupName = `dt.host_group.id`Process group
| Classic | Smartscape |
|---|---|
dt.entity.process_group | Not a separate Smartscape entity |
entity.name, entityName(dt.entity.process_group) | available as dt.process_group.name or dt.process_group.detected_name on PROCESS |
id | available as dt.process_group.id on PROCESS |
Example:
smartscapeNodes PROCESS
| summarize by:{ id = dt.process_group.id, entity.name = dt.process_group.detected_name }, process.metadata = takeAny(process.metadata)Container group
| Classic | Smartscape |
|---|---|
dt.entity.container_group | Not a separate Smartscape entity |
instance_of[dt.entity.container_group] | unsupported as entity relation |
entityName(instance_of[dt.entity.container_group], type:"dt.entity.container_group") | unsupported; preserve output shape with null if needed |
dt.entity.container_group_instance still maps to CONTAINER.
Field mappings
Use these field migrations when the classic field name, not just the entity type, needs updating.
| Classic field | Smartscape field | Notes |
|---|---|---|
affected_entity_ids | smartscape.affected_entity.ids | Davis events field for affected entity IDs |
affected_entity_types | smartscape.affected_entity.types | Davis events field for affected entity types; values become uppercase Smartscape type names |
dt.source_entity.type | dt.smartscape_source.type | Davis events field for source entity type |
containerizationType | container.containerization_type | Planned Smartscape container field |
customPgMetadata | process.metadata | Classic process-group metadata now lives on process |
customHostMetadata | host.custom.metadata | Custom host metadata field |
Related references
- special-cases.md
- dql-function-migration.md
- entity-cloud-application.md
Related skills
How it compares
Use dt-migration for Dynatrace-specific tag-to-dictionary translation rather than general monitoring setup or APM dashboard skills.
FAQ
What does dt-migration map from Dynatrace?
dt-migration maps every ManagementZoneDataSourceMeAttribute key listed in auto_tagging_attributes.md to the closest semantic dictionary field, including recursive *_TAGS rules and tags imported from cloud vendors or Kubernetes labels.
How does dt-migration handle unmapped Dynatrace keys?
dt-migration marks keys with no direct semantic dictionary equivalent explicitly, preventing AI coding agents from guessing field mappings when auto-tagging attributes lack a defined target in the semantic dictionary.
Is Dt Migration safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.