
Dt Obs Tracing
Query Dynatrace traces and DQL to find slow or noisy database client spans and extrapolate real DB call volume per service.
Install
npx skills add https://github.com/dynatrace/dynatrace-for-ai --skill dt-obs-tracingWhat is this skill?
- DQL recipes to list DB operations via db.query.text, db.system, and db.operation.name
- Service-scoped views tying client spans to dt.smartscape.service with span counts and avg duration
- Sampling multiplicity math to extrapolate true DB call counts from aggregated spans
- Filters for span.kind client and db.namespace to isolate database client traffic
- Top-statement style summaries grouped by service, code.function, and DB metadata
Adoption & trust: 691 installs on skills.sh; 87 GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Azure Kubernetesmicrosoft/azure-skills
Github Actions Docsxixu-me/skills
Deploy To Vercelvercel-labs/agent-skills
Vercel Cli With Tokensvercel-labs/agent-skills
Turborepovercel/turborepo
Docker Expertsickn33/antigravity-awesome-skills
Journey fit
Primary fit
Production observability belongs on the Operate shelf because builders use it after ship when traces and sampling matter in live systems. Monitoring is the canonical subphase for distributed tracing analysis and database-span aggregation, not incident triage alone.
Common Questions / FAQ
Is Dt Obs Tracing safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Dt Obs Tracing
# Database Span Analysis Database operations in traces appear as client spans with database-specific attributes. Database spans can be aggregated (one span representing multiple calls). ## Basic Database Queries ### List Database Operations Query database activity: ```dql fetch spans | filter isNotNull(db.query.text) | summarize spans=count(), by: { db.system, db.operation.name, db.collection.name } ``` ### Database Spans by Service Identify which services make database calls: ```dql fetch spans | filter span.kind == "client" and isNotNull(db.namespace) | fieldsAdd getNodeName(dt.smartscape.service) | summarize { spans=count(), avg_duration=avg(duration) }, by: { dt.smartscape.service.name, db.system, db.namespace } | sort spans desc ``` ## Top Database Statements ### Extrapolated Statement Counts Count actual database calls (not just spans) per service: ```dql fetch spans | filter span.kind == "client" and isNotNull(db.namespace) | fieldsAdd getNodeName(dt.smartscape.service) // Calculate multiplicity for extrapolation | fieldsAdd sampling.probability = (power(2, 56) - coalesce(sampling.threshold, 0)) * power(2, -56) | fieldsAdd sampling.multiplicity = 1/sampling.probability | fieldsAdd multiplicity = coalesce(sampling.multiplicity, 1) * coalesce(aggregation.count, 1) * dt.system.sampling_ratio | summarize { db_calls = sum(multiplicity) }, by: { dt.smartscape.service.name, code.function, db.system, db.namespace, db.query.text } | sort db_calls desc | limit 100 ``` ## Database Performance ### Statement Duration Analysis Analyze database call durations with aggregation awareness: ```dql fetch spans | filter span.kind == "client" and isNotNull(db.query.text) // Calculate average duration for aggregated spans | fieldsAdd aggregation.duration_avg = coalesce( aggregation.duration_sum / aggregation.count, duration ) // Calculate multiplicity | fieldsAdd sampling.probability = (power(2, 56) - coalesce(sampling.threshold, 0)) * power(2, -56) | fieldsAdd sampling.multiplicity = 1/sampling.probability | fieldsAdd multiplicity = coalesce(sampling.multiplicity, 1) * coalesce(aggregation.count, 1) * dt.system.sampling_ratio | summarize { operation_count = sum(multiplicity), avg_duration = sum(aggregation.duration_avg * multiplicity) / sum(multiplicity), p95_duration = percentile(aggregation.duration_avg, 95) }, by: { db.system, db.operation.name, db.collection.name } | sort operation_count desc | limit 50 ``` ### Slow Database Queries Find slowest database statements: ```dql fetch spans | filter span.kind == "client" and isNotNull(db.query.text) | fieldsAdd aggregation.duration_avg = coalesce( aggregation.duration_sum / aggregation.count, duration ) | filter aggregation.duration_avg > 100ms | fields trace.id, db.system, db.query.text, duration=aggregation.duration_avg, aggregated_calls=aggregation.count | sort duration desc | limit 50 ``` ## Database Attributes Common database span attributes: - `db.system` - Database type (e.g., postgresql, mysql, mongodb) - `db.namespace` - Database name - `db.query.text` - SQL/query statement - `db.operation.name` - Operation type (SELECT, INSERT, UPDATE, etc.) - `db.collection.name` - Table/collection name - `db.affected_item_count` - Number of rows/documents affected ## Best Practices - **Always extrapolate** - Use multiplicity factor when counting database operations - **Use `aggregation.duration_avg`** - Calculate `aggregation.duration_sum / aggregation.count` for accurate durations - **Filter by `span.kind == "client"`** and `isNotNull(db.namespace)` to identify database spans - **Check `aggregation.count`** - Indicates one span represents multiple operations - **Consider read sampling** - Use `samplingRatio` for better performance on large datasets - **Include service context** - Add