Homeโ€บ๐Ÿ” DQL & Data Accessโ€บModule 42 min read ยท 5/21

DQL Fundamentals

Hands-on4 exercises

DQL: The Universal Query Language

DQL (Dynatrace Query Language) is the single most important thing to learn in Gen3. It replaces metric expressions, USQL, entity selectors, and the Data Explorer โ€” all with one pipeline-based language.

// The basic pattern: fetch โ†’ filter โ†’ transform โ†’ aggregate โ†’ sort
fetch logs, from:now() - 1h
| filter loglevel == "ERROR"
| summarize error_count = count(), by:{dt.process_group.detected_name}
| sort error_count desc
| limit 10

Key Syntax Rules

RULE                                    EXAMPLE
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Pipe-based pipeline                     fetch logs | filter ... | sort ...
Curly braces for grouping               by: {field1, field2}
Named parameters with colon             from: now()-1h, interval: 5m
No array literal syntax                 filter in(field, "a", "b") NOT [...]
Backticks for special field names       sort `count()` desc
Log severity field is "loglevel"        NOT log.level
lower() not toLowerCase()               contains(lower(field), "err")
substring uses named params             substring(field, from: 0, to: 200)

Data Objects

Each data type has its own fetch command:

fetch logs                    โ€” application and infrastructure logs
fetch spans                   โ€” distributed traces
fetch events                  โ€” Davis and custom events
fetch bizevents               โ€” business events
fetch dt.davis.problems       โ€” Davis-detected problems
fetch dt.davis.events         โ€” Davis events
fetch user.events             โ€” RUM individual events
fetch user.sessions           โ€” RUM session aggregates
fetch security.events         โ€” security findings
fetch metric.series           โ€” metric discovery
timeseries avg(metric.key)    โ€” metric queries (NOT fetch!)
smartscapeNodes "TYPE"        โ€” topology queries (NOT fetch!)
๐Ÿ›  Try it

Write a DQL query that fetches error logs from the last hour, showing timestamp, content, and process group name. Sort by newest first, limit to 20.

extension.yamlYAML
Loading...

Common Pitfalls

โŒ WRONG                                 โœ… RIGHT
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
filter field in ["a", "b"]              filter in(field, "a", "b")
by: severity, status                    by: {severity, status}
sort count() desc                       sort `count()` desc
filter log.level == "ERROR"             filter loglevel == "ERROR"
fetch dt.metric                         timeseries avg(metric.key)
fetch HOST                              smartscapeNodes "HOST"
matchesValue(stringField, "x")          contains(stringField, "x")

Your First DQL Queries

Open Notebooks in your Dynatrace environment and try these:

// 1. List all hosts
fetch dt.entity.host | fields entity.name, id | limit 10

// 2. Check CPU usage
timeseries cpu = avg(dt.host.cpu.usage), by:{dt.entity.host}

// 3. Find error logs
fetch logs, from:now() - 1h
| filter loglevel == "ERROR"
| fields timestamp, content, dt.process_group.detected_name
| sort timestamp desc
| limit 20

// 4. Check active problems
fetch dt.davis.problems, from:now() - 24h
| filter not(dt.davis.is_duplicate) and event.status == "ACTIVE"
| fields event.start, display_id, event.name, event.category
| sort event.start desc