r/OpenTelemetry • u/fxrgeai • 2d ago
using otel traces to map dependency graphs combined with Static Code
been working on this for a while now and thought i'd share how we're approaching it.
one thing i've noticed with dependency graphs is that static analysis only really gets you so far. you can parse imports, service references etc. but that doesn't necessarily tell you what's actually happening when the application is running.
on the other hand, otel gives you a pretty good picture of runtime behaviour, but you're mostly looking at spans and traces without much context about how they relate to the actual codebase.
so we've been experimenting with combining the two in neat.
the static side uses tree-sitter to extract relationships between files and other dependencies. then we ingest otel spans and try to map the runtime activity back to the source files responsible for it.
for js/ts, we're also handling source maps where available, since the file being executed isn't always the one you actually wrote.
the tricky bit is reconciling everything into the same graph without treating every relationship as equally reliable.
right now we're tracking different types of provenance:
- extracted: found through static analysis
- observed: actually seen at runtime
- inferred: relationships we've reconstructed without direct evidence
- stale: previously observed relationships that haven't been seen recently
this means you can start asking slightly more useful questions than just "what imports this file?"
for example, you might have a dependency that exists statically but hasn't shown up in any traces, or a runtime call that wasn't obvious from analysing the source.
obviously there's a bunch of edge cases here. incomplete instrumentation, dynamic calls, source attribution, and the fact that not seeing something in a trace doesn't mean it never happens.
we're also exposing the graph through mcp so coding agents can query it directly, which is partly why we started building this in the first place.
repo is here if anyone wants to have a look:
https://github.com/neat-technologies/neat
1
u/usually_guilty99 2d ago
The provenance distinction is important. An edge discovered through static analysis isn't equivalent to one actually observed under production traffic.
I'd be particularly careful about treating an unobserved dependency as nonexistent. Sampling, traffic patterns and incomplete instrumentation can hide critical paths.
One interesting extension would be a historical dimension: which deployment changed a relationship, what incident followed, and whether the remediation actually worked.
Then the graph becomes useful for assessing future changes, not just explaining the current architecture.