feat(haystack): Added Components instrumentation #2383
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In the existing haystack instrumentation, tracing was only applied within the Pipeline execution path. The instrumentation wrapped Pipeline methods, so component methods like run() or run_async() were dynamically wrapped only when they were executed as part of a pipeline. This design ensured that components inside a pipeline were traced properly, but if specific component is invoked directly (outside pipeline) is never traced because their execution did not go through the pipeline wrapping machanism. As a result, invoking Agent.run() directly created no spans at all, since the tracing logic was never attached to the Agent class itself.
Additionally, even when Agent.run() internally invoked Pipeline._run_component, the instrumentation still treated each sub-component call(LLM, Tools, Embeddings or other components) as an independent span. Instead of grouping them under a parent Agent.run span, every internal component run appeared as a separate trace segment. This happened because there was no root span created for Agent.run to serve as the parent for those internal operations—the pipeline instrumentation only captured the individual component spans without establishing hierarchical context.
Haystack will register all the components in component.registry, now we can wrap the all the registered components run and run_async methods at instrumentation time. This ensures that every component, including Agent gets traced consistently wheather it runs independently or within a pipeline. It also enables proper span hierarchy, allowing Agent.run to created as root span that encapsulates the nested component executions.
closes #2328
Note
Wrap all registered Haystack components (including Agent) for tracing, update span names to reflect actual method (run/run_async), and add examples plus tests (with VCR cassettes).
haystack.core.component.component.registryto tracerunandrun_asyncoutside pipelines (includesAgent).ClassName.<method>usingwrapped.__name__(e.g.,OpenAIChatGenerator.run_async,InMemoryBM25Retriever.run).test_agent_run_component_spans(sync/async) validating parentAgent.<method>span and nested LLM/tool spans.InMemoryBM25Retriever.run/run_async)..run_asyncfor async paths.examples/:agent_run.py,agent_with_pipeline.py,retriever_component_run.pydemonstrating tracing setup and component/agent runs.Written by Cursor Bugbot for commit 1cd56df. This will update automatically on new commits. Configure here.