ServiceMap

Molecule

Services and the calls between them on a deterministic layered layout (no graph library): rate, error and latency badges, pan and zoom, roving-focus keyboard navigation along the call graph, and a panel for the selected service. Errors are never colour alone: a warning icon and percentage, a heavier border and a dashed edge. Same locals, DOM and classes as kui-react, and the same layout code (`ServiceMap/map-model.js`, run on the server and in the browser), so the coordinates are identical. The server draws the whole map at the `width` local (default 900, EJS only; React draws nothing until the browser has measured the box); `ServiceMap/scripts/service-map.js` (inlined once, idempotent) measures the real width and fits the drawing, pans, zooms, handles the keyboard and the selection, and mirrors the layout on a right-to-left page. `renderSelection` takes a function returning escaped text, or `selectionPartial` a partial path (React takes a node); `onSelect` is the bubbling `kui:service-map-select` event; `selectedId` (controlled in React) is the state at render time and makes the script only emit it.

Default

Preview
edge-gateway to web, 1.4k/s, 40 ms 1.4k/s · 40 ms web to api, 1.1k/s, 2%, 130 ms 1.1k/s · 2% · 130 ms web to auth, 1.1k/s, 14 ms 1.1k/s · 14 ms api to auth, 1.1k/s, 12 ms 1.1k/s · 12 ms api to orders-db, 2k/s, 4 ms 2k/s · 4 ms api to payments, 90/s, 12%, 700 ms ! 90/s · 12% · 700 ms api to events, 340/s, 0% 340/s · 0% payments to card-gateway, 90/s, 12%, 640 ms ! 90/s · 12% · 640 ms payments to api, 20/s, 30 ms 20/s · 30 ms edge-gateway gateway · healthy 1.4k req/s · 0.4% errors · p95 … web service · healthy 1.2k req/s · 0.6% errors · p95 … api service · degraded 1.1k req/s · p95 240 ms 3.1% auth service · healthy 1.1k req/s · 0.1% errors · p95 … payments service · failing 90 req/s · p95 900 ms 12% orders-db database · no data 2k req/s · p95 4 ms events queue · healthy 340 req/s · 0% errors card-gateway external · failing 90 req/s · p95 820 ms 12%

Drag to pan, Ctrl + scroll to zoom. Arrow keys move along calls, Enter selects.

Code
<%- include('modules/ui/ServiceMap', { nodes: nodes, edges: edges }) %>
<script>
  document.addEventListener('kui:service-map-select', (e) => openService(e.detail.node));
</script>

With a selection and a custom panel

Preview
edge-gateway to web, 1.4k/s, 40 ms 1.4k/s · 40 ms web to api, 1.1k/s, 2%, 130 ms 1.1k/s · 2% · 130 ms web to auth, 1.1k/s, 14 ms 1.1k/s · 14 ms api to auth, 1.1k/s, 12 ms 1.1k/s · 12 ms api to orders-db, 2k/s, 4 ms 2k/s · 4 ms api to payments, 90/s, 12%, 700 ms ! 90/s · 12% · 700 ms api to events, 340/s, 0% 340/s · 0% payments to card-gateway, 90/s, 12%, 640 ms ! 90/s · 12% · 640 ms payments to api, 20/s, 30 ms 20/s · 30 ms edge-gateway gateway · healthy 1.4k req/s · 0.4% errors · p95 … web service · healthy 1.2k req/s · 0.6% errors · p95 … api service · degraded 1.1k req/s · p95 240 ms 3.1% auth service · healthy 1.1k req/s · 0.1% errors · p95 … payments service · failing 90 req/s · p95 900 ms 12% orders-db database · no data 2k req/s · p95 4 ms events queue · healthy 340 req/s · 0% errors card-gateway external · failing 90 req/s · p95 820 ms 12%

Drag to pan, Ctrl + scroll to zoom. Arrow keys move along calls, Enter selects.

payments: called by 1, calls 2.
Code
<%- include('modules/ui/ServiceMap', {
  nodes: nodes, edges: edges, defaultSelectedId: 'pay',
  renderSelection: (node, { incoming, outgoing }) => node.name + ': called by ' + incoming.length,
  // or selectionPartial: '/abs/path/to/service-panel.ejs'  (locals: node, incoming, outgoing)
}) %>

Right to left

Preview
edge-gateway to web, 1.4k/s, 40 ms 1.4k/s · 40 ms web to api, 1.1k/s, 2%, 130 ms 1.1k/s · 2% · 130 ms web to auth, 1.1k/s, 14 ms 1.1k/s · 14 ms api to auth, 1.1k/s, 12 ms 1.1k/s · 12 ms edge-gateway gateway · healthy 1.4k req/s · 0.4% errors · p95 … web service · healthy 1.2k req/s · 0.6% errors · p95 … api service · degraded 1.1k req/s · p95 240 ms 3.1% auth service · healthy 1.1k req/s · 0.1% errors · p95 … payments service · failing 90 req/s · p95 900 ms 12%

Drag to pan, Ctrl + scroll to zoom. Arrow keys move along calls, Enter selects.

Code
<div dir="rtl"><%- include('modules/ui/ServiceMap', { nodes: nodes, edges: edges }) %></div>
<%# no direction local: the script mirrors the map when the page is right to left; pass direction: 'rtl' to draw it mirrored on the server %>
Source modules/ui/ServiceMap.ejs