Use knotel / Explore
Service map
How knotel draws which services, databases and APIs call each other.
The service map draws your whole system from the traces you already send: every service, the databases and external APIs it calls, and the calls between services, including calls from one project into another. Services that never talk to each other appear as separate graphs.
Reading the map
- Nodes are services, databases and external hosts. Each shows requests, error rate and p95 latency. Nodes whose error rate is 1% or more are marked.
- Edges point from caller to callee. Dashed, darker edges cross projects.
- Frames group each connected set of services, labelled with its project.
- The Connections table below lists every edge with requests, error rate and latency percentiles.
How connections are found
There are two kinds of edges, both derived from spans:
- Service → service: a span whose parent belongs to a different service or project. A browser fetch whose
traceparentreached a Worker is one; a Worker in one project calling a Worker in another is another. - Service → database or external host: spans with
db.system.name, and client spans with a peer orserver.addressthat no instrumented service picked up.
A call named only by its hostname is matched against the hosts your own services report answering on - the server.address of their incoming requests. When one matches, the call is drawn as an edge into that service rather than as a host of its own, so a hop through a gateway that drops traceparent still joins the graph. The header says how many hosts were matched this way. What stays external is what nothing of yours answers: third-party APIs, analytics beacons and CDNs.
External shows databases and those remaining hosts; with it off the map is your services and the calls between them. Database and external nodes belong to the calling project, so two unrelated projects that both use MongoDB don't get merged into one graph. Edge numbers describe the callee side: its duration and status.
Filter lists what is drawn around your services, grouped by the domain they belong to, so a tracker that arrives as twenty subdomains goes off in one click. Unchecking a node takes it and its connections off the canvas and out of the table. The choice is held in the page's address: a filtered map survives a reload and can be sent to someone else as it stands.
When a connection is missing
- Browser → API: the API's host must be in the script's
data-propagate(or be the same origin), and the API must allow thetraceparentheader in CORS. - Worker → Worker: both must be instrumented; outgoing fetches carry
traceparentby default. - A call landing on a hostname instead of the service behind it: the callee's own server spans have to carry
server.addressfor the two to be matched. The Worker SDK sets it; other instrumentation may not. A host is also ignored when it carries under a tenth of that service's requests, or when it is an IP rather than a name. - Databases: wrap calls with
trace()and setdb.system.name. See Workers. - The map covers the selected time range (24 hours by default), so a call that hasn't happened recently isn't shown.