A passive, local analyzer that infers service dependencies, asynchronous fan-out, and retry edges from OpenTelemetry JSON without a service registry. Every inferred edge retains confidence, causal evidence, observation counts, and version history.
The bundled demo reveals that shop/audit-archive, a supposedly isolated service, is connected to checkout through a
single low-volume Kafka path. It also detects a fulfillment-to-inventory retry cycle and distinguishes evidence that is
merely time-correlated from evidence joined by an exact message ID.
- Node.js 20 or newer
- npm (bundled with Node.js)
There are no third-party packages and no install step. The tool neither opens sockets nor calls external APIs. From the repository root, run all quality gates with:
npm run checkFrom the repository root:
node src/cli.js analyze samples/deploy-17.otlp.json --version deploy-17 --out build/deploy-17.graph.json
node src/cli.js analyze samples/deploy-18.otlp.json --version deploy-18 --out build/deploy-18.graph.json
node src/cli.js diff build/deploy-17.graph.json build/deploy-18.graph.jsonThe final command reports three added edges, one removed edge, and one confidence change. In particular, it prints the new hidden path and retry relation:
+ async shop/checkout -> shop/audit-archive via order-audit (99% confidence)
+ retry shop/fulfillment-worker -> inventory-api (94% confidence; 2 retries)
Add --json to either command for machine-readable output. analyze --json emits a graph snapshot; diff --json emits
the full change set. Run node src/cli.js --help for the concise command reference.
The importer reads the standard OTLP JSON resourceSpans shape, including both current scopeSpans and legacy
instrumentationLibrarySpans. It uses these OpenTelemetry semantic attributes when present:
service.namespace,service.name, andservice.versionfor identitypeer.service,server.address,net.peer.name, orhttp.hostfor synchronous peersmessaging.destination.nameandmessaging.message.idfor cross-trace asynchronous correlationapp.request.idorrequest.id, operation name, timing, and status for retry classification
The CLI fails on malformed trace/span identifiers, invalid or reversed timestamps, malformed typed attributes or
snapshots, unknown options, and missing option values instead of silently manufacturing topology. It also refuses to
replace the input trace through --out and
creates output directories as needed. Sensitive values—including message and request correlation IDs, user IDs,
emails, tokens, authorization values, cookies, passwords, secrets, and API keys—are SHA-256 hashed during import. Raw
span attributes are not written to graph snapshots. Snapshot files are replaced atomically and created with
owner-only permissions where the platform supports POSIX modes.
Exact asynchronous joins require compatible destinations and messaging systems, and one produced message can fan out to multiple consumers. The lower-confidence time heuristic is used only when both sides lack a message ID, so known but different IDs are never joined merely because their timestamps are close. Unqualified peer names are reconciled to a namespace only when exactly one observed service is a match.
- Exact producer/consumer message ID:
0.99 - Same destination within five minutes, with no message ID:
0.68 - Client span with an explicit peer hint:
0.90 - Repeated failed request attempts with a stable request ID:
0.94 - Repeated attempts inferred without a request ID:
0.76
These values are explicit heuristics, not probabilities learned from a production population. Consumers should use the attached evidence and confidence rather than treating inferred edges as ground truth.
Retry inference requires non-overlapping attempts no more than five minutes apart. Every attempt before the final one must have error status. Without a request ID, attempts must also share a non-empty parent span ID. The snapshot differ reports confidence, observation-count, retry-count, and evidence-method changes; new span IDs alone do not create change noise when the evidence method is the same.
See docs/architecture.md for component boundaries, inference rules, and known limits.
MIT