
dt-obs-tracing
Distributed traces, spans, service dependencies, and request flow analysis. Use when investigating span-level details, failures, performance bottlenecks, or trace correlation. Trigger: "trace analysis", "slow requests", "failed spans", "service dependencies", "distributed trace", "span details", "HTTP status codes in traces", "database query spans", "messaging spans", "gRPC calls", "Lambda cold starts", "trace ID lookup", "exception analysis", "correlate logs and traces", "request attributes". Do NOT use for explaining existing queries, product documentation or configuration questions, service-level RED metrics (use dt-obs-services), log searching (use dt-obs-logs), or problem analysis (use dt-obs-problems).
- Installs
- 2.6K
- Last 24h
- +14
- Trending rank
- #7143
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/dynatrace/dynatrace-for-ai --skill dt-obs-tracing- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads dt-obs-tracing automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Application Tracing Skill
Overview
Distributed traces in Dynatrace consist of spans - building blocks representing units of work. With Traces in Grail, every span is accessible via DQL with full-text searchability on all attributes. This skill covers trace fundamentals, common analysis patterns, and span-type specific queries.
Use Cases
1. Investigate Slow Requests
- Goal: Find and diagnose requests exceeding a latency threshold
- Trigger: "slow requests", "high latency", "p99 response time", "find traces over 5 seconds"
- Done: List of slow traces with duration, endpoint, service, and trace IDs for drilldown
2. Analyze Request Failures
- Goal: Identify failed requests, failure reasons, and exception patterns
- Trigger: "failed spans", "HTTP 500 errors", "exception analysis", "failure rate by service"
- Done: Failure breakdown by reason (HTTP code, exception, gRPC status) with exemplar traces
3. Map Service Dependencies
- Goal: Understand service-to-service communication patterns and external API calls
- Trigger: "service dependencies", "what services does X call", "outgoing HTTP calls"
- Done: Dependency map showing call counts, latency, and error rates between services
Core Concepts
Understanding Traces and Spans
Spans represent logical units of work in distributed traces:
- HTTP requests, RPC calls, database operations
- Messaging system interactions
- Internal function invocations
- Custom instrumentation points
Span kinds:
span.kind: server- Incoming call to a servicespan.kind: client- Outgoing call from a servicespan.kind: consumer- Incoming message consumption call to a servicespan.kind: producer- Outgoing message production call from a servicespan.kind: internal- Internal operation within a service
Root spans: A request root span (request.is_root_span == true) represents an incoming call to a service. Use this to analyze end-to-end request performance.
Key Trace Attributes
Essential attributes for trace analysis:
| Attribute | Description |
|---|---|
trace.id | Unique trace identifier |
span.id | Unique span identifier |
span.parent_id | Parent span ID (null for root spans) |
request.is_root_span | Boolean, true for request entry points |
request.is_failed | Boolean, true if request failed |
duration | Span duration in nanoseconds |
span.timing.cpu | Overall CPU time of the span (stable) |
span.timing.cpu_self | CPU time excluding child spans (stable) |
dt.smartscape.service | Service Smartscape node ID |
dt.service.name | Dynatrace service name derived from service detection rules. It is equal to the Smartscape service node name. |
endpoint.name | Endpoint/route name |
Service Context
Spans reference services via Smartscape node IDs and the detected service name dt.service.name which is also present on every span.
fetch spans
| summarize spans=count(), by: { dt.smartscape.service, dt.service.name }
Node functions:
getNodeName(dt.smartscape.service)- Addsdt.smartscape.service.namefield with the human-readable service namegetNodeField(dt.smartscape.service, "attribute_name")- Access specific node attributes
📖 Learn more: See Entity Lookups for advanced entity selectors, infrastructure correlation, and hardware analysis.
Sampling and Extrapolation
One span can represent multiple real operations due to:
- Aggregation: Multiple operations in one span (
aggregation.count) - ATM (Adaptive Traffic Management): Head-based sampling by agent
- ALR (Adaptive Load Reduction): Server-side sampling
- Read Sampling: Query-time sampling via
samplingRatioparameter
When to extrapolate: Always extrapolate when counting actual operations (not just spans). Use the multiplicity factor:
fetch spans
| 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)
📖 Learn more: See Sampling and Extrapolation for detailed formulas and examples.
Common Query Patterns
Basic Span Access
Fetch spans and explore by type:
fetch spans | limit 1
Explore spans by function and type:
fetch spans
| summarize count(), by: { span.kind, code.namespace, code.function }
Request Root Filtering
List request root spans (incoming service calls):
fetch spans
| filter request.is_root_span == true
| fields trace.id, span.id, start_time, response_time = duration, endpoint.name
| limit 100
Service Performance Summary
Analyze service performance with error rates:
fetch spans
| filter request.is_root_span == true
| summarize
total_requests = count(),
failed_requests = countIf(request.is_failed == true),
avg_duration = avg(duration),
p95_duration = percentile(duration, 95),
by: {dt.service.name}
| fieldsAdd error_rate = (failed_requests * 100.0) / total_requests
| sort error_rate desc
Trace ID Lookup
Find all spans in a specific trace:
fetch spans
| filter trace.id == toUid("abc123def456")
| fields span.name, duration, dt.service.name
Performance Analysis
Response Time Percentiles
Calculate percentiles by endpoint:
fetch spans
| filter request.is_root_span == true
| summarize {
requests=count(),
avg_duration=avg(duration),
p95=percentile(duration, 95),
p99=percentile(duration, 99)
}, by: { endpoint.name }
| sort p99 desc
💡 Best practice: Use percentiles (p95, p99) over averages for performance insights.
Slow Trace Detection
Find requests exceeding a threshold:
fetch spans, from:now() - 2h
| filter request.is_root_span == true
| filter duration > 5s
| fields trace.id, span.name, dt.service.name, duration
| sort duration desc
| limit 50
Duration Buckets with Exemplars
fetch spans, from:now() - 24h
| filter http.route == "/api/v1/storage/findByISBN"
| summarize {
spans=count(),
trace=takeAny(record(start_time, trace.id))
}, by: { bin(duration, 10ms) }
| fields `bin(duration, 10ms)`, spans, trace.id=trace[trace.id], start_time=trace[start_time]
Performance Timeseries
Extract response time as timeseries:
fetch spans, from:now() - 24h
| filter request.is_root_span == true
| makeTimeseries {
requests=count(),
avg_duration=avg(duration),
p95=percentile(duration, 95),
p99=percentile(duration, 99)
}, by: { endpoint.name }
📖 Learn more: See Performance Analysis for advanced patterns and timeseries techniques.
Failure Investigation
Failed Request Summary
Summarize failures by service:
fetch spans
| filter request.is_root_span == true
| summarize
total = count(),
failed = countIf(request.is_failed == true),
by: { dt.service.name }
| fieldsAdd failure_rate = (failed * 100.0) / total
| sort failure_rate desc
Failure Reason Analysis
Breakdown by failure detection reason:
fetch spans
| filter request.is_failed == true and isNotNull(dt.failure_detection.results)
| expand dt.failure_detection.results
| summarize count(), by: { dt.failure_detection.results[reason] }
Failure reasons:
http_code- HTTP response code triggered failuregrpc_code- gRPC status code triggered failureexception- Exception caused failurespan_status- Span status indicated failurecustom_rule- Custom failure detection rule matched
HTTP Code Failures
Find failures by HTTP status code:
fetch spans
| filter request.is_failed == true
| filter iAny(dt.failure_detection.results[][reason] == "http_code")
| summarize count(), by: { http.response.status_code, endpoint.name }
| sort `count()` desc
Recent Failed Requests
List recent failures with details:
fetch spans
| filter request.is_root_span == true and request.is_failed == true
| fields
start_time,
trace.id,
endpoint.name,
http.response.status_code,
duration
| sort start_time desc
| limit 100
📖 Learn more: See Failure Detection for exception analysis and custom rule investigation.
Service Dependencies
Service-to-Service Analysis
Analyze service communication patterns:
fetch spans, from:now() - 1h
| filter isNotNull(server.address)
| fieldsAdd
remote_side = server.address
| summarize
call_count = count(),
avg_duration = avg(duration),
by: {dt.service.name, remote_side}
| sort call_count desc
Outgoing HTTP Calls
Identify external API dependencies:
fetch spans
| filter span.kind == "client" and isNotNull(http.request.method)
| summarize
calls = count(),
avg_latency = avg(duration),
p99_latency = percentile(duration, 99),
by: { dt.service.name, server.address, server.port }
| sort calls desc
Trace Aggregation
Complete Trace Analysis
Aggregate all spans in a trace to understand full request flow:
fetch spans, from:now() - 30m
| summarize {
spans = count(),
client_spans = countIf(span.kind == "client"),
// Endpoints involved in the trace
endpoints = toString(arrayRemoveNulls(collectDistinct(endpoint.name))),
// Extract the first request root in the trace
trace_root = takeMin(record(
root_detection_helper = coalesce(
if(request.is_root_span, 1),
if(isNull(span.parent_id), 2),
3),
start_time, endpoint.name, duration
))
}, by: { trace.id }
| fieldsFlatten trace_root
| fieldsRemove trace_root.root_detection_helper, trace_root
| fields
start_time = trace_root.start_time,
endpoint = trace_root.endpoint.name,
response_time = trace_root.duration,
spans,
client_spans,
endpoints,
trace.id
| sort start_time
| limit 100
Root detection strategy: Use takeMin(record(...)) with a detection helper to reliably find the root request:
- Priority 1: Spans with
request.is_root_span == true - Priority 2: Spans without parent (root spans)
- Priority 3: All other spans
Multi-Service Traces
Find traces spanning multiple services:
fetch spans, from:now() - 1h
| summarize {
services = collectDistinct(dt.service.name),
trace_root = takeMin(record(root_detection_helper = coalesce(if(request.is_root_span, 1), 2), endpoint.name))
}, by: { trace.id }
| fieldsAdd service_count = arraySize(services)
| filter service_count > 1
| fields endpoint = trace_root[endpoint.name], service_count, services = toString(services), trace.id
| sort service_count desc
| limit 50
Request-Level Analysis
Request Attributes
Access custom request attributes captured by OneAgent on request root spans:
fetch spans
| filter request.is_root_span == true
| filter isNotNull(request_attribute.PaidAmount)
| makeTimeseries sum(request_attribute.PaidAmount)
Field patterns: request_attribute.<name>, captured_attribute.<name> (always arrays)
→ Request Attributes — full patterns for request attributes, captured attributes, and request ID aggregation
Span Types
| Span Type | Detection | Key Fields | Reference |
|---|---|---|---|
| HTTP server (incoming) | span.kind == "server" and isNotNull(http.request.method) | http.route, http.request.method, http.response.status_code | http-spans.md |
| HTTP client (outgoing) | span.kind == "client" and isNotNull(http.request.method) | server.address, server.port | http-spans.md |
| Database | span.kind == "client" and isNotNull(db.system) | db.system, db.namespace, db.statement | database-spans.md |
| Messaging | isNotNull(messaging.system) | messaging.system, messaging.destination.name, messaging.operation.type | messaging-spans.md |
| RPC / gRPC | isNotNull(rpc.system) | rpc.system, rpc.service, rpc.method, rpc.grpc.status_code | rpc-spans.md |
| Serverless / FaaS | isNotNull(faas.name) and span.kind == "server" | faas.name, faas.trigger.type, cloud.provider | serverless-spans.md |
⚠️ Database spans: Can be aggregated (one span = multiple calls). Always use aggregation.count extrapolation for accurate operation counts.
📖 Detailed patterns per span type: See the reference files above.
Advanced Topics
Exception Analysis
Exceptions are stored as span.events within spans:
fetch spans
| filter iAny(span.events[][span_event.name] == "exception")
| expand span.events
| fieldsFlatten span.events, fields: { exception.type }
| summarize {
count(),
trace=takeAny(record(start_time, trace.id))
}, by: { exception.type }
| fields exception.type, `count()`, trace.id=trace[trace.id], start_time=trace[start_time]
💡 Tip: Use iAny() to check conditions within span event arrays.
→ Logs Correlation — joining logs and traces, filtering traces by log content → Network Analysis — client IPs, DNS resolution, subnet analysis
Best Practices
| Area | Rule |
|---|---|
| Filtering | Apply request.is_root_span == true and endpoint filters first |
| Sampling | Use samplingRatio (e.g., 100 = read 1%) for performance |
| Percentiles | Use p95/p99 over averages for performance analysis |
| Root spans | Use request.is_root_span == true for end-to-end analysis |
| Trace grouping | Group by trace.id for complete trace metrics |
| Request grouping | Group by request.id for OneAgent-only request metrics |
| Extrapolation | Always apply multiplicity for accurate operation counts |
| Exemplars | Use takeAny(record(start_time, trace.id)) to enable UI drilldown |
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| Duration values seem wrong (too large) | duration is in nanoseconds, not milliseconds | Divide by 1000000 or compare with 5s (DQL duration literal) |
| Span counts don't match expected request volume | Sampling or aggregation not accounted for | Use multiplicity extrapolation — see Sampling and Extrapolation reference |
getNodeName(dt.smartscape.service) returns null | Service not yet resolved or OneAgent not monitoring | Verify OneAgent monitors the service; entity resolution may have a short delay |
request.is_root_span filter returns nothing | Querying OpenTelemetry-only traces without OneAgent | Use isNull(span.parent_id) as fallback for root span detection |
trace.id filter returns no results | Trace ID not converted to UID format | Use filter trace.id == toUid("abc123...") for string-based trace IDs |
| Database span counts are too low | Database spans are aggregated (one span = N calls) | Always use aggregation.count extrapolation for database operation counts |
Related Skills
- dt-dql-essentials — Core DQL syntax for querying trace data
- dt-app-dashboards — Embed trace queries in dashboards
- dt-migration — Smartscape entity model and relationship navigation
References
Detailed documentation for specific topics:
- Performance Analysis - Advanced timeseries, duration buckets, endpoint ranking
- Failure Detection - Failure reasons, exception investigation, custom rules
- Sampling and Extrapolation - Multiplicity calculation, database extrapolation
- Request Attributes - Request attributes, captured attributes, request ID aggregation
- Entity Lookups - Advanced node lookups, infrastructure correlation, hardware analysis
- HTTP Span Analysis - Status codes, payload analysis, client IPs
- Database Span Analysis - Extrapolated counts, slow queries, statement analysis
- Messaging Span Analysis - Kafka, RabbitMQ, SQS throughput and latency
- RPC Span Analysis - gRPC, SOAP, service dependencies
- Serverless Span Analysis - Lambda, Azure Functions, cold start analysis
- Logs Correlation - Joining logs and traces, correlation patterns
- Network Analysis - IP addresses, DNS resolution, communication mapping
FAQ
What does the dt-obs-tracing skill do?
Distributed traces, spans, service dependencies, and request flow analysis. Use when investigating span-level details, failures, performance bottlenecks, or trace correlation. Trigger: "trace analysis", "slow requests", "failed spans", "service dependencies", "distributed trace", "span details", "HTTP status codes in traces", "database query spans", "messaging spans", "gRPC calls", "Lambda cold starts", "trace ID lookup", "exception analysis", "correlate logs and traces", "request attributes". Do NOT use for explaining existing queries, product documentation or configuration questions, service-level RED metrics (use dt-obs-services), log searching (use dt-obs-logs), or problem analysis (use dt-obs-problems).
How do I install dt-obs-tracing?
Run npx skills add https://github.com/dynatrace/dynatrace-for-ai --skill dt-obs-tracing in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/dt-obs-tracing/ (personal) or .claude/skills/dt-obs-tracing/ (project).
Which AI agents can use dt-obs-tracing?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is dt-obs-tracing safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains dt-obs-tracing?
It is published by dynatrace in dynatrace/dynatrace-for-ai. It has 2,646 recorded installs.
More from dynatrace/dynatrace-for-ai
dt-dql-essentials
dynatrace/dynatrace-for-ai
Core DQL syntax, pitfalls, query patterns, and query optimization. Load to write, build, fix, or OPTIMIZE a DQL query — prevents syntax errors and makes queries faster, more efficient, and cheaper (less data scanned = lower query consumption/cost per run). Covers fetch commands, data models, field namespaces, time alignment, entity/smartscape patterns, metric discovery, and performance/cost optimization (filter early, bucket filters, short time ranges, field selection, sampling, cardinality). Trigger: "write/build/fix a DQL query", "DQL syntax", "query logs/spans/metrics", "create a timeseries", "optimize my DQL", "make my query faster/cheaper", "reduce DQL cost/consumption/scanned data", "keep DQL cost under control". Do NOT use to explain an existing query or answer product questions. For MONITORING a tenant's ACTUAL query consumption/billing (how much queries cost, who scanned most, cost trends) use dt-platform-costs — this tunes the query text, not billing data.
dt-app-dashboards
dynatrace/dynatrace-for-ai
Work with Dynatrace dashboards - create, modify, query, and analyze dashboard JSON including tiles, layouts, DQL queries, variables, and visualizations.
dt-obs-logs
dynatrace/dynatrace-for-ai
Log querying, filtering, pattern analysis, and error rate calculation. Use when searching application or infrastructure logs, analyzing error patterns, or correlating log data. Trigger: "show error logs", "search logs for keyword", "log error rate", "recent errors", "logs from last hour", "find log entries", "top error messages", "log patterns", "parse JSON logs", "logs by process group", "log trends over time", "log entry counts per minute". Do NOT use for explaining existing queries, product documentation questions, distributed tracing or span analysis (use dt-obs-tracing).
dt-obs-problems
dynatrace/dynatrace-for-ai
DAVIS problem analysis including root cause identification, impact assessment, and correlation with other telemetry. Use when querying or investigating detected problems. Trigger: "active problems", "root cause analysis", "problem impact", "affected users", "list problems", "P-12345 details", "recurring problems", "problem history", "problem trending", "blast radius", "which entity caused the problem", "problems affecting Kubernetes", "problems by service". Do NOT use for explaining existing queries, product documentation questions, generic log searching, distributed tracing, or host-level resource monitoring.
dt-app-notebooks
dynatrace/dynatrace-for-ai
Work with Dynatrace notebooks - create, modify, query, and analyze notebook JSON including sections, DQL queries, and visualizations.
dt-obs-services
dynatrace/dynatrace-for-ai
Service performance monitoring with RED metrics (Rate, Errors, Duration) and runtime-specific telemetry for Java, .NET, Node.js, Python, PHP, and Go. Use when analyzing service health, SLA compliance, or runtime issues. Trigger: "service response time", "error rate", "throughput", "SLA compliance", "service mesh overhead", "JVM GC", "Java heap", "Node.js event loop", ".NET CLR", "Python threads", "PHP OPcache", "Go goroutines", "service performance", "p95 latency", "request failures", "database response time by name". Do NOT use for explaining existing queries, product documentation questions, infrastructure metrics (use dt-obs-hosts), log analysis (use dt-obs-logs), or distributed tracing workflows (use dt-obs-tracing).
Popular backend & apis skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
entra-app-registration
microsoft/azure-skills
Guides Microsoft Entra ID app registration, OAuth 2.0 authentication, and MSAL integration. USE FOR: create app registration, register Azure AD app, configure OAuth, set up authentication, add API permissions, generate service principal, MSAL example, console app auth, Entra ID setup, Azure AD authentication. DO NOT USE FOR: Key Vault secrets (use azure-keyvault-expiration-audit), general Azure resource security guidance.
google-agents-cli-adk-code
google/agents-cli
This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent", "use state management" — in a project that needs ADK (Agent Development Kit) API patterns and code examples. It provides a quick reference for agent types, tool definitions, orchestration patterns, callbacks, state management, the graph Workflow API, and reference recipes to study. Do NOT use for scaffolding (use google-agents-cli-scaffold) or deployment (use google-agents-cli-deploy).
embedded-captions
heygen-com/hyperframes
Add captions or subtitles to an existing single-subject talking-head video without editing the footage. Use for plain verbatim captions, cinematic captions embedded behind the subject, VFX captions, “炸/特效/酷炫字幕,” or a named identity from the 35-style catalog. Route by visual identity, not by backend engine. The quiet anchor rail is the default; embed every word only when the user explicitly wants a fully cinematic treatment. The workflow runs locally end to end, including transcription and subject matting; split multi-shot footage before applying it.
entra-agent-id
microsoft/azure-skills
Provision Microsoft Entra Agent Identity Blueprints, BlueprintPrincipals, and per-instance Agent Identities via Microsoft Graph, and configure OAuth 2.0 token exchange (fmipath, OBO, cross-tenant) including the Microsoft Entra SDK for AgentID sidecar. USE FOR: Agent Identity Blueprint, BlueprintPrincipal, agent OAuth, fmipath token exchange, agent OBO, Workload Identity Federation for agents, polyglot agent auth, Microsoft.Identity.Web.AgentIdentities. DO NOT USE FOR: standard Entra app registration (use entra-app-registration), Microsoft Foundry agent authoring (use microsoft-foundry).
neon
neondatabase/agent-skills
Overview of Neon, a complete set of cloud backend primitives around Lakebase Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or MCP server, and follow the branch-first workflow. Use when building an app or backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child skill neon-postgres wins for an existing DATABASEURL, SQL, schema, inspect, or search. Child skill neon-auth wins for login, users, sessions, identity routing, and Managed Better Auth setup. Child skill neon-realtime wins for live queries in reactive apps and agents. Also use for object storage, S3, buckets, serverless functions, function triggers, cron, AI gateway, LLM calls, realtime, logs, Loki, Grafana, observability, postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.