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 name
  • actionnarrowed, reordered, selected, or skipped
  • candidatesBefore / candidatesAfter — member IPs, weights, regions, scores at that point
  • note — 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.

  1. Select a service from the dropdown.
  2. Optionally enter a client IP (leave blank to use an unknown/default region).
  3. Click Trace — the panel shows the step list and the selected member.
  4. 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
  5. 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.com

Example 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.


Was this article helpful?
© 2026