Skip to main content
Logs, metrics, and distributed tracing are recorded signals: each holds what someone chose to emit, and asks the reader to reconstruct what happened from it. The choice was made before the incident, by someone who was guessing which values would matter. Reconstruction is the part that costs time: you hold a stream of strings and you need to know which call produced which value, and what that call was given.

For people

Recorded signals work when you knew what to log in advance and you already understand the system. They run out exactly where incident time is lost: on call, at 2am, in a service you do not own, on the other side of a team boundary. There you are reading someone else’s choice of what was worth printing, in a format their formatter picked, with no way to ask the question you actually have. What you want there is the request itself: this call ran, it was given these arguments, it returned this, and the call under it returned that.

For AI agents

An AI agent reasons from source code and tests. Both are static. The agent has no view of runtime behaviour, so when it debugs it infers execution from log lines and spans, which means guessing at the parts nobody wrote down. When it changes code, it cannot see what actually depends on the thing it is touching. Across a service boundary the static call graph simply ends, and the agent has no evidence that the function it is about to change is called from anywhere else at all. The gap is the same one in both cases. Nobody records what the code did, only what it said.

Recorded signals could get there, on three conditions

Recorded signals can answer a question like “why did this request come back empty”, if three things hold: the right log line existed, the reader guessed the right query, service, and time window, and the reader correctly discounted a dependency that reported success. The first was decided in advance, by whoever chose which value was worth printing. The other two are guesses made while the system is already broken.

The unit of foresight

Vexlo needs foresight too. Someone has to decide that a function is worth recording and mark it. The difference is the size of that decision. A log line requires predicting which value matters for which failure. It commits you to one value, in one format, at one point in the code, for failure modes you can imagine today. Mark a function instead and the decision is coarser: this code is worth recording. After that, the inputs and outputs it sees are recorded as it runs, subject to the service’s capture policy, including for failures nobody imagined. The call tree comes back assembled rather than reconstructed from timestamps, because each record carries its own path in it. Code you never marked does not appear at all, so this is a claim about where foresight is spent and not a claim to record everything. Logs, spans, and execution graphs puts the three kinds of record side by side: what each one holds, and which question each one answers.