Query Path Tracer
Query Path Tracer
The Query Path Tracer runs a dry-run simulation of the DNS resolution algorithm for any service and client IP you choose. It replays the exact filter chain that a real query would execute — using live health state and geo-IP data — and returns a step-by-step trace of which members were in contention at each stage and which member was ultimately selected.
No live DNS state is mutated. The round-robin counter is not advanced.
What the tracer shows
For a service with filter chain
["geo-ip", "weighted-round-robin"] and three members:
| Step | Filter | Action | Candidates before | Candidates after |
|---|---|---|---|---|
| 1 | geo-ip | narrowed | 3 | 1 |
| 2 | weighted-rr | selected | 1 | 1 |
Selected: 10.0.0.1
Each step records:
filter— the filter nameaction—narrowed,reordered,selected, orskippedcandidatesBefore/candidatesAfter— member IPs, weights, regions, scores at that pointnote— optional explanation (e.g. "no region match — kept all candidates")
WebUI — Trace panel
Click Trace in the top-right toolbar on the Topology page to open the trace panel.
- Select a service from the dropdown.
- Optionally enter a client IP (leave blank to use an unknown/default region).
- Click Trace — the panel shows the step list and the selected member.
- Click a step to highlight the corresponding members on the canvas:
- Blue glow — still in the candidate set after this step
- Dimmed — eliminated at or before this step
- Green outline — the final selected member
- Use ▶ Play to animate through steps automatically, or click ← / → to step manually.
API
POST /api/v1/simulate
Requires: pools:read permission.
Request body:
{
"serviceId": "svc-abc123",
"clientIp": "94.100.14.1"
}clientIp is optional. Omit or pass "" to
simulate from an unknown region.
Response:
{
"serviceId": "svc-abc123",
"domain": "api.example.com.",
"clientIp": "94.100.14.1",
"clientRegion": "GB",
"algorithm": "geo-ip → weighted-round-robin",
"steps": [
{
"filter": "geo-ip",
"action": "narrowed",
"candidatesBefore": [
{ "ip": "10.0.0.1", "weight": 10, "region": "GB", "score": 1.0, "priority": 0 },
{ "ip": "10.0.0.2", "weight": 10, "region": "US", "score": 1.0, "priority": 0 }
],
"candidatesAfter": [
{ "ip": "10.0.0.1", "weight": 10, "region": "GB", "score": 1.0, "priority": 0 }
]
},
{
"filter": "weighted-round-robin",
"action": "selected",
"candidatesBefore": [
{ "ip": "10.0.0.1", "weight": 10, "region": "GB", "score": 1.0, "priority": 0 }
],
"candidatesAfter": [
{ "ip": "10.0.0.1", "weight": 10, "region": "GB", "score": 1.0, "priority": 0 }
],
"note": "simulated — actual rotation uses live counter"
}
],
"selectedIp": "10.0.0.1"
}When no healthy candidates exist, the response has
"noCandidate": true and "selectedIp": "".
gslbctl
# Trace with a specific client IP
gslbctl trace <service-id> --client-ip 94.100.14.1 --server https://nexus-api.example.com
# Trace with unknown/default region
gslbctl trace <service-id> --server https://nexus-api.example.comExample output:
Service: api.example.com. (svc-abc1)
Client: 94.100.14.1 [region: GB]
Chain: geo-ip → weighted-round-robin
STEP FILTER ACTION N→N NOTE
────────────────────────────────────────────────────────────────────────────
1 geo-ip narrowed 2→1
· 10.0.0.1 w=10 (GB)
2 weighted-rr selected 1→1 simulated — actual rotation uses live counter
✓ 10.0.0.1 w=10 (GB)
Selected: 10.0.0.1
Behaviour notes
| Scenario | What happens |
|---|---|
| Filter would eliminate all candidates | Step is marked skipped and all candidates pass
through |
latency filter with no RTT data |
Step is marked skipped |
round-robin |
Always picks index 0 in simulate mode — live counter not advanced |
weighted-round-robin |
Random pick (reproducible within the simulation, but random across calls) |
| No pool assigned to service | noCandidate: true |
| All members unhealthy or disabled | noCandidate: true |
Permissions
Requires pools:read. Available to
tenant_admin, operator, and
viewer roles.