Smartscape on Grail is a Grail-native storage that automatically records topological data, such as monitored entities and relationships. Aside from regular entities, you can use Smartscape-specific entities in your queries. To learn more, see Smartscape.
Smartscape on Grail uses the power of DQL queries to:
This gives you deeper insight into your data records and allows you to manipulate and extract necessary information for further analysis.
Smartscape on Grail is also actively used in
Smartscape, which offers you Smartscape on Grail view.
Smartscape on Grail is fully integrated into DQL and introduces new commands and functions that you can use to:
Smartscape on Grail is included in the DPS license. This means that data returned from Smartscape queries doesn't incur any additional cost.
The data stored in traditional buckets—such as logs, events, spans, or metric data points—is ingested for a particular timestamp and never changes. In comparison, Smartscape nodes and edges are mutable and can change over time.
Smartscape nodes are identified via an ID, represented by a Grail datatype Smartscape ID. Smartscape IDs are updated regularly through the upsert events.
A Smartscape ID consists of the entity type and a 16-symbol long number. It can be represented by a following string:
ENTITY_TYPE-000000000000007BThe Smartscape type is fully compatible with its string representation, meaning that you can compare a string to Smartscape ID.
Every node has a type field that describes the entity type and determines the schema of the entity. The Semantic Dictionary contains the schema for each of the types. By convention, node types are always formatted in uppercase, like HOST, K8S_NAMESPACE, and AWS_EC2_INSTANCE.
Because nodes are updated regularly, they don't have a single timestamp field. Instead, nodes have two timeframe fields that represent the node's lifetime:
lifetime.start: the first time when the node was discovered.lifetime.end: the time when the node was last observed.While the lifetime.start field will remain unchanged, the lifetime.end field will be continuously updated with every incoming upsert event as long as the node is still being observed.
Based on the query timeframe, you will see only those nodes that have a lifetime overlapping with the query timeframe. For example, a node with a lifetime.end field containing yesterday's data won't be included in a query result for the last 2 hours.
Query timeframes that start less than 15 minutes in the past are automatically extended to 15 minutes.
Edges are relationships that connect two nodes to each other. An edge always stores an edge type (such as runs_on, calls or relates_to), and two IDs of two different nodes.
How an edge is stored on a node depends on whether the edge is static or dynamic:
Edges stored statically are included in results where the query timeframe overlaps with the node's lifetime, whereas dynamic edges are included in query results based on a timeframe when the edge was recorded.
Static edges are mostly based on configuration, such as when a disk is configured to be attached to a specific host. Dynamic edges are typically based on monitoring signals that reveal a specific relationship between nodes, such as when a service based on traces calls another service.
All static edges can be accessed through the source node via the references field. While this field is hidden by default, you can display it and use it in queries with the help of the fieldsAdd command.
You can see the examples of using the references field below:
smartscapeNodes "*"| fieldsAdd references
smartscapeNodes CONTAINER| summarize by:references[runs_on.host], count()
Data retention is fixed at 35 days. This means that nodes whose lifetime.end is older than 35 days will be deleted, including all static edges. Dynamic edges will be cleaned up after 35 days as well.
A signal's fields that start with dt.smartscape.__type__ and contain Smartscape IDs indicate that the signal has originated within a given node. A single signal can have multiple dt.smartscape.__type__ fields.
Optionally, a signal can also have:
dt.smartscape_source.id field that points to the exact source that produced the signal.dt.smartscape_source.type field that describes the type of the entity that produced the signal.Each node has a special field called tags that contains different nested fields recognized as tags.
Currently, tags can only be set at the data source. That means that, for example:
Similar to other data stored in Grail, Smartscape nodes have a dt.security_context field that can contain multiple values.
The dt.security_context field is an optional node field and is empty by default, since the regular permission fields are fully supported and often sufficient.
You can configure and use fieldsets with the smartscape table to apply filters to all data returned by Smartscape commands (smartscapeNodes and smartscapeEdges). Be aware that only certain fields can be filtered out for all entity types simultaneously.
See the example of a field set configuration below:
To define a new fieldset that filters the Kubernetes configuration details that are stored in the k8s.object field, you can use the API with the following request:
POST /fieldsets{"name": "sensitive-field-k8s-object","description": "Make k8s.object sensitive","enabled": true,"scope": "TABLE","fields": ["k8s.object"],"tables": ["smartscape"]}
Now only users that have the permission ALLOW storage:fieldsets:read WHERE storage:fieldset-name="sensitive-field-k8s-object" will be able to read the details of this field.
Node types used by Smartscape on Grail might be different from classic entity types. This means that the entity or node ID might also be different (for example, CLOUD_APPLICATION_INSTANCE is called K8S_POD in Smartscape on Grail). To avoid confusion, Smartscape nodes include an id_classic field that contains the entity ID of the corresponding classic entity. Classic entity IDs are available for K8s entities, core entities, and services.
If there are no corresponding classic entities (for example, with Clouds), there are no id_classic fields on those nodes.
| Feature | Classic entity store | Smartscape on Grail |
|---|---|---|
Query all entities regardless of their type | Not supported |
|
Query HOST entities |
|
|
Query all relationships regardless of type, source or target | Not supported |
|
References in Signal data |
|
|
Enrich entity name |
|
|
Enrich any other field (for example, tags) |
|
|
Get a list of entity IDs based on entity selector |
| Not supported |
Get a list of entity IDs based on entity traversal | Not supported |
|
Use segments to filter data from Smartscape nodes. You can use the following filters:
For more information on how to use segments, see Include data in segments.
Only Smartscape nodes can be filtered using segments, meaning that Smartscape edges can't be filtered.
OpenPipeline offers dedicated stages for node and edge extraction and processing. Use OpenPipeline to extract topological data from any signal for:
Smartscape node extraction generates Smartscape events that pass through the Smartscape events pipeline (see Direct Smartscape event ingest and processing section).
Smartscape events can be ingested directly via the Smartscape events endpoint (/platform/ingest/v1/smartscape.events). Ingested events are processed through the Smartscape events pipeline in OpenPipeline and transformed into Smartscape upserts; the events themselves are not persisted as records.
The Smartscape events pipeline supports the following stages: Processing and Permission.
Smartscape events are sent as a JSON array. Each event must include an identity field—either a pre-assembled id or a type plus id_components. For the full schema, see Smartscape events.
Use this method when the Dynatrace entity ID is already known.
[{"id": "HOST-00AB12CD00AB12CD","name": "prod-host-01","tags:custom.context": { "team": "platform-engineering" }}]
Use this method when syncing from an external system where the Dynatrace entity ID is not available. Provide type and id_components instead of id.
[{"type": "CUSTOM_SERVICE","id_components": [{ "name": "checkout-service" },{ "service.namespace": "payments" }],"dt.security_context": ["pci-scope", "prod-infra"],"service.version": "3.1.2","static_edges": {"calls": [{"type": "CUSTOM_DATABASE","id_components": [{ "name": "orders-db-primary" }]}]}}]
Processing is restricted to the following fields:
ext.*custom.*tags:custom.*tags:ext.*nameprocess.metadata[COMMAND_LINE_ARGS]primary_tags.*Fields outside this allowlist are silently dropped at upsert. No error is returned.
Smartscape events do not need to contain all node fields. Only the fields present in the event are included in the upsert; all other fields on the node remain unchanged.
This has the following implications:
null.Name: Remove the tmp field from all nodes
Matching condition: true
fieldsAdd tmp = null
When you assign a field value derived from another field, restrict the matching condition to records where the source field exists. If you use true as the matching condition, the processor runs on every record, including those that do not carry the source field. In those cases, the source resolves to null, and the upsert writes null to the target field, deleting it from the node.
The following processor copies the Azure appid tag into primary_tags. The matching condition ensures that it runs only on records where the source tag is present.
Name: Assign the primary tag appid
Matching condition: isNotNull(`tags:azure`[appid])
fieldsAdd primary_tags.appid = `tags:azure`[appid]
The tags field is not available during pipeline processing or at upsert time; it exists only at query time in DQL. Use the tags:<context> form (for example, tags:azure[appid]) to access tag values within the pipeline.
You can also set primary_tags fields in the shared Primary Grail tags stage, which applies to all data passing through the pipeline.