What logs give you and what they don't
When something goes wrong with a traditional service, the first place you look is the logs. Logs are a timeline: this happened, then this, then this. For most software bugs, that timeline is enough to reconstruct what went wrong. You find the error message, trace it back through the function call that triggered it, and you have a lead.
For an LLM agent, logs tell you what happened at each step but not how the steps relate. If your agent calls a retrieval tool, passes the results to an LLM, and then the LLM output is wrong, your logs might show:
retrieval called, returned 3 documentsLLM call completed in 1.2sfinal output: [response text]
The output is wrong. The logs tell you nothing about why. Did the retrieval return the wrong documents? Did the LLM use those documents correctly? Did the prompt template fill in the documents in an order that confused the model? You have a before-state and an after-state, but no causal structure connecting them.
What traces give you instead
A trace captures the same events but in a structured parent-child relationship that reflects how they were caused. The retrieval call is a child span of the LLM step that needed it. The LLM call is a child span of the agent turn that triggered it. The relationship between events is part of the data, not something you have to reconstruct by reading timestamps.
For debugging a quality failure in a multi-step agent, this structure is the difference between "I know the output was wrong" and "I know the output was wrong because the retrieval step returned a document that predated the relevant event, and the model used that document's date in its response." The second form of knowledge tells you what to fix.
Traces also carry context through the span hierarchy. Each span has access to the data its parent passed to it. For an agent with tool use, you can inspect exactly what the agent sent to the tool, what the tool returned, and how that return was incorporated into the next step. Logs rarely capture this flow because logging at each function boundary would require invasive instrumentation.
The practical difference when debugging a quality drop
A concrete example from our own development: we were debugging a summarization agent that was producing summaries that skipped key findings. The outputs were syntactically fine, grounded in the source documents, but consistently incomplete on a specific class of inputs.
With logs, we would have seen: retrieval succeeded, LLM call completed, output generated. The incompleteness wouldn't appear as an error in any log. We'd have to read the outputs manually and reason about what caused the pattern.
With traces, we could see that for the inputs where summaries were incomplete, the retrieval step was returning documents in a specific order where the most relevant content appeared in the middle of the context window rather than at the beginning. The LLM was underweighting middle-of-context content, which is a known behavior. The fix was to reorder the retrieval results before passing them to the model. We found this in a few hours rather than days, because the trace gave us visibility into the causal chain.
When to reach for logs first
Logs still have a place. For operational questions, "how many requests failed in the last hour," "what was the median latency on Tuesday," "did this error message appear in any run this week," logs are the right tool. They're cheaper to store, faster to query for simple patterns, and sufficient for the class of debugging that's about counting and timing rather than causality.
When a request is unambiguously broken (the agent returned an HTTP 500, the tool call failed, the output parsing threw an exception), a log is often enough to identify the failure. The error is a discrete event with a clear cause.
The limitation appears when the failure is a quality issue rather than a technical one. "The agent returned a response but the response was not what the user needed" is not an error log entry. It's a quality signal that only surfaces through evaluation. And to understand why the quality dropped, you need the trace structure, not the log stream.
Both, in practice
The "vs." framing in the title is a bit of a misdirection. In a functioning observability setup, you want both. The question is which one to reach for first when you're investigating a specific problem.
Reach for logs when: you're investigating operational anomalies, you're trying to quantify a failure rate, or you're debugging an exception that has a clear error message. These are fast, well-tooled, and sufficient for these categories.
Reach for traces when: you're debugging a quality issue, you're trying to understand why a specific agent run produced a specific output, or you're comparing two runs that had the same input but different outputs. These require the causal structure that traces provide.
In Orq, traces and logs coexist in the same interface. When an eval score flags a run as a potential regression, you can click through to the trace for that run and see the full call sequence. The evaluation score is the signal; the trace is the explanation. Starting from a log entry and working backward to the causal chain that produced it is possible but slower. Starting from a flagged eval and jumping to its trace is the investigation pattern we find most effective for quality debugging.
Instrumenting for both without doubling your effort
If you're already using structured logging, adding trace-level instrumentation doesn't mean replacing your logs. OpenTelemetry, which Orq sits on top of, supports both logs and traces in the same instrumentation framework. You emit log records and span data from the same instrumented points. The tracing SDK handles the parent-child relationship automatically based on the execution context.
For LangChain agents specifically, the callback system already has hooks at the right level of granularity: per chain, per LLM call, per tool use. The Orq tracing callback wraps these into spans and logs them to the Orq trace collector. You get trace structure for quality debugging and log-compatible event data for operational monitoring from the same setup.
The implementation detail is: start with tracing, and you get logs as a subset. Start with only logs, and adding traces later requires more instrumentation work. This is why we recommend trace-first when you're setting up observability for an LLM agent for the first time.
A note on what traces don't solve
Traces give you the causal structure of an execution. They don't interpret it for you. A trace that shows the retrieval step returned three documents doesn't tell you whether those documents were the right ones, whether they were fresh, or whether the model used them correctly in the next step. The trace is the evidence; the conclusion requires either a human reading it or an eval scoring it.
This is why traces and evals are complementary rather than one being sufficient. Evals tell you a score dropped. Traces tell you why. For the investigation workflow to work, you need both: the signal to know something is wrong and the trace to understand what caused it. A trace corpus without eval scores is just data. Eval scores without traces are signal without explanation. Together, they give you the feedback loop that makes LLM agent quality maintainable over time.