Skip to content

Commit 85ef972

Browse files
authored
docs: Add individual tracing docs pages (#11660)
1 parent 0fef576 commit 85ef972

20 files changed

Lines changed: 1354 additions & 468 deletions

File tree

docs-website/docs/concepts/pipelines/debugging-pipelines.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ Here’s what the resulting log would look like when a pipeline is run:
116116

117117
## Tracing
118118

119-
To get a bigger picture of the pipeline’s performance, try tracing it with [Langfuse](../../development/tracing.mdx#langfuse).
119+
To get a bigger picture of the pipeline’s performance, try tracing it with [Langfuse](../../development/tracing/langfuse.mdx).
120120

121121
Our [Tracing](../../development/tracing.mdx) page has more about other tracing solutions for Haystack.
122122

docs-website/docs/development/tracing.mdx

Lines changed: 15 additions & 232 deletions
Original file line numberDiff line numberDiff line change
@@ -2,150 +2,33 @@
22
title: "Tracing"
33
id: tracing
44
slug: "/tracing"
5-
description: "This page explains how to use tracing in Haystack. It describes how to set up a tracing backend with OpenTelemetry, Datadog, or your own solution. This can help you monitor your app's performance and optimize it."
5+
description: "This page explains how to use tracing in Haystack. It lists the tracing backends Haystack supports out of the box and explains how to enable, configure, and disable tracing."
66
---
77

8-
import ClickableImage from "@site/src/components/ClickableImage";
9-
108
# Tracing
119

12-
This page explains how to use tracing in Haystack. It describes how to set up a tracing backend with OpenTelemetry, Datadog, or your own solution. This can help you monitor your app's performance and optimize it.
13-
14-
Traces document the flow of requests through your application and are vital for monitoring applications in production. This helps to understand the execution order of your pipeline components and analyze where your pipeline spends the most time.
15-
16-
## Configuring a Tracing Backend
17-
18-
Instrumented applications typically send traces to a trace collector or a tracing backend. Haystack provides out-of-the-box support for [OpenTelemetry](https://opentelemetry.io/) and [Datadog](https://app.datadoghq.eu/dashboard/lists). You can also quickly implement support for additional providers of your choosing.
19-
20-
### OpenTelemetry
21-
22-
The `OpenTelemetryConnector` component lets you trace your Haystack pipelines with [OpenTelemetry](https://opentelemetry.io/).
23-
24-
Simply install the integration with `pip install opentelemetry-haystack`, then add the connector to your pipeline.
25-
26-
:::info
27-
Check out the [integration page](https://haystack.deepset.ai/integrations/opentelemetry) for more details and example usage.
28-
:::
29-
30-
### Datadog
31-
32-
The `DatadogConnector` component lets you trace your Haystack pipelines with [Datadog](https://www.datadoghq.com/).
33-
34-
Simply install the integration with `pip install datadog-haystack`, then add the connector to your pipeline.
35-
36-
:::info
37-
Check out the [integration page](https://haystack.deepset.ai/integrations/datadog) for more details and example usage.
38-
:::
39-
40-
### Langfuse
41-
42-
`LangfuseConnector` component allows you to easily trace your Haystack pipelines with the Langfuse UI.
43-
44-
Simply install the component with `pip install langfuse-haystack`, then add it to your pipeline.
45-
46-
:::info
47-
Check out the component's [documentation page](../pipeline-components/connectors/langfuseconnector.mdx) for more details and example usage, or our [blog post](https://haystack.deepset.ai/blog/langfuse-integration) for the complete walkthrough.
48-
:::
49-
<ClickableImage src="/img/11cec4f-langfuse-generation-span.png" alt="Langfuse trace detail view showing generation span with input prompt, output, metadata, latency, and cost information for a language model call" />
50-
51-
### MLflow
52-
53-
[MLflow](https://mlflow.org/) is an open-source platform for managing the end-to-end machine learning and AI lifecycle. MLflow provides native tracing support for Haystack. Simply install MLflow and enable automatic tracing with a single line of code.
54-
55-
```shell
56-
pip install mlflow
57-
```
58-
59-
```python
60-
import mlflow
61-
62-
mlflow.haystack.autolog()
63-
# Optionally set an experiment name
64-
mlflow.set_experiment("Haystack")
65-
```
66-
67-
This automatically captures traces from all Haystack pipelines and components, including latencies, token usage, cost, and any exceptions.
68-
69-
:::info
70-
Check out the [MLflow Haystack integration guide](https://haystack.deepset.ai/integrations/mlflow) for a full walkthrough with examples.
71-
:::
72-
73-
### Weights & Biases Weave
74-
75-
The `WeaveConnector` component allows you to trace and visualize your pipeline execution in [Weights & Biases](https://wandb.ai/site/) framework.
76-
77-
You will first need to create a free account on Weights & Biases website and get your API key, as well as install the integration with `pip install weights_biases-haystack`.
78-
79-
:::info
80-
Check out the component's [documentation page](../pipeline-components/connectors/weaveconnector.mdx) for more details and example usage.
81-
:::
82-
83-
### Custom Tracing Backend
84-
85-
To use your custom tracing backend with Haystack, follow these steps:
86-
87-
1. Implement the `Tracer` interface. The following code snippet provides an example using the OpenTelemetry package:
10+
Traces document the flow of requests through your application and are vital for monitoring applications in production. This helps you understand the execution order of your pipeline components and analyze where your pipeline spends the most time.
8811

89-
```python
90-
import contextlib
91-
from typing import Optional, Dict, Any, Iterator
12+
Instrumented applications typically send traces to a trace collector or a tracing backend. Haystack provides out-of-the-box support for several backends, and you can also quickly implement support for additional providers of your choosing.
9213

93-
from opentelemetry import trace
94-
from opentelemetry.trace import NonRecordingSpan
14+
## Supported Tracers
9515

96-
from haystack.tracing import Tracer, Span
97-
from haystack.tracing import utils as tracing_utils
98-
import opentelemetry.trace
99-
100-
class OpenTelemetrySpan(Span):
101-
def __init__(self, span: opentelemetry.trace.Span) -> None:
102-
self._span = span
103-
104-
def set_tag(self, key: str, value: Any) -> None:
105-
# Tracing backends usually don't support any tag value
106-
# `coerce_tag_value` forces the value to either be a Python
107-
# primitive (int, float, boolean, str) or tries to dump it as string.
108-
coerced_value = tracing_utils.coerce_tag_value(value)
109-
self._span.set_attribute(key, coerced_value)
110-
111-
class OpenTelemetryTracer(Tracer):
112-
def __init__(self, tracer: opentelemetry.trace.Tracer) -> None:
113-
self._tracer = tracer
114-
115-
@contextlib.contextmanager
116-
def trace(
117-
self, operation_name: str, tags: Optional[Dict[str, Any]] = None, parent_span: Optional[Span] = None
118-
) -> Iterator[Span]:
119-
with self._tracer.start_as_current_span(operation_name) as span:
120-
span = OpenTelemetrySpan(span)
121-
if tags:
122-
span.set_tags(tags)
123-
124-
yield span
125-
126-
def current_span(self) -> Optional[Span]:
127-
current_span = trace.get_current_span()
128-
if isinstance(current_span, NonRecordingSpan):
129-
return None
130-
131-
return OpenTelemetrySpan(current_span)
132-
```
133-
134-
2. Tell Haystack to use your custom tracer:
135-
136-
```python
137-
from haystack import tracing
138-
139-
haystack_tracer = OpenTelemetryTracer(tracer)
140-
tracing.enable_tracing(haystack_tracer)
141-
```
16+
| Tracer | Description |
17+
| --- | --- |
18+
| [OpenTelemetry](tracing/opentelemetry.mdx) | Send traces to any [OpenTelemetry](https://opentelemetry.io/)-compatible backend using the `OpenTelemetryTracer` or the `OpenTelemetryConnector` component. Includes a Jaeger setup for local development. |
19+
| [MLflow](tracing/mlflow.mdx) | Capture traces with [MLflow](https://mlflow.org/)'s native Haystack tracing support. |
20+
| [Datadog](tracing/datadog.mdx) | Trace your pipelines with [Datadog](https://www.datadoghq.com/) using the `DatadogTracer` or the `DatadogConnector` component. |
21+
| [Langfuse](tracing/langfuse.mdx) | Trace your pipelines with the [Langfuse](https://langfuse.com/) UI using the `LangfuseTracer` or the `LangfuseConnector` component. |
22+
| [Weights & Biases Weave](tracing/weave.mdx) | Trace and visualize pipeline execution in [Weights & Biases](https://wandb.ai/site/) using the `WeaveTracer` or the `WeaveConnector` component. |
23+
| [LoggingTracer](tracing/logging-tracer.mdx) | Inspect the data flowing through your pipeline in real time through logs, with no backend setup. |
24+
| [Custom Tracer](tracing/custom-tracer.mdx) | Connect any tracing backend by implementing the `Tracer` interface. |
14225

14326
## Disabling Auto Tracing
14427

14528
Haystack automatically detects and enables tracing under the following circumstances:
14629

147-
- If `opentelemetry-sdk` is installed and configured for OpenTelemetry.
148-
- If `ddtrace` is installed for Datadog.
30+
- If `opentelemetry-sdk` is installed and configured for OpenTelemetry. Note that this auto-enabling is deprecated and will be removed in Haystack 3.0 – use the [`OpenTelemetryConnector`](tracing/opentelemetry.mdx) to enable OpenTelemetry tracing instead.
31+
- If `ddtrace` is installed for Datadog. Note that this auto-enabling is deprecated and will be removed in Haystack 3.0 – use the [`DatadogConnector`](tracing/datadog.mdx) to enable Datadog tracing instead.
14932

15033
To disable this behavior, there are two options:
15134

@@ -180,103 +63,3 @@ To enable content tracing, there are two options:
18063

18164
tracing.tracer.is_content_tracing_enabled = True
18265
```
183-
184-
## Visualizing Traces During Development
185-
186-
Use [Jaeger](https://www.jaegertracing.io/docs/1.6/getting-started/) as a lightweight tracing backend for local pipeline development. This allows you to experiment with tracing without the need for a complex tracing backend.
187-
<ClickableImage src="/img/dd906d7-Screenshot_2024-02-22_at_16.51.01.png" alt="Jaeger UI trace timeline displaying haystack pipeline execution with component spans showing duration and nesting of operations" />
188-
189-
1. Run the Jaeger container. This creates a tracing backend as well as a UI to visualize the traces:
190-
191-
```shell
192-
docker run --rm -d --name jaeger \
193-
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
194-
-p 6831:6831/udp \
195-
-p 6832:6832/udp \
196-
-p 5778:5778 \
197-
-p 16686:16686 \
198-
-p 4317:4317 \
199-
-p 4318:4318 \
200-
-p 14250:14250 \
201-
-p 14268:14268 \
202-
-p 14269:14269 \
203-
-p 9411:9411 \
204-
jaegertracing/all-in-one:latest
205-
```
206-
2. Install the OpenTelemetry SDK:
207-
208-
```shell
209-
pip install opentelemetry-sdk
210-
pip install opentelemetry-exporter-otlp
211-
```
212-
3. Configure `OpenTelemetry` to use the Jaeger backend:
213-
214-
```python
215-
from opentelemetry.sdk.resources import Resource
216-
from opentelemetry.semconv.resource import ResourceAttributes
217-
218-
from opentelemetry import trace
219-
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
220-
from opentelemetry.sdk.trace import TracerProvider
221-
from opentelemetry.sdk.trace.export import BatchSpanProcessor
222-
223-
# Service name is required for most backends
224-
resource = Resource(attributes={
225-
ResourceAttributes.SERVICE_NAME: "haystack"
226-
})
227-
228-
tracer_provider = TracerProvider(resource=resource)
229-
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces"))
230-
tracer_provider.add_span_processor(processor)
231-
trace.set_tracer_provider(tracer_provider)
232-
```
233-
4. Tell Haystack to use OpenTelemetry for tracing:
234-
235-
```python
236-
import haystack.tracing
237-
238-
haystack.tracing.auto_enable_tracing()
239-
```
240-
5. Run your pipeline:
241-
242-
```python
243-
...
244-
pipeline.run(...)
245-
...
246-
```
247-
6. Inspect the traces in the UI provided by Jaeger at [http://localhost:16686](http://localhost:16686/search).
248-
249-
## Real-Time Pipeline Logging
250-
251-
Use Haystack's [`LoggingTracer`](https://github.com/deepset-ai/haystack/blob/main/haystack/tracing/logging_tracer.py) logs to inspect the data that's flowing through your pipeline in real-time.
252-
253-
This feature is particularly helpful during experimentation and prototyping, as you don’t need to set up any tracing backend beforehand.
254-
255-
Here’s how you can enable this tracer. In this example, we are adding color tags (this is optional) to highlight the components' names and inputs:
256-
257-
```python
258-
import logging
259-
from haystack import tracing
260-
from haystack.tracing.logging_tracer import LoggingTracer
261-
262-
logging.basicConfig(
263-
format="%(levelname)s - %(name)s - %(message)s",
264-
level=logging.WARNING,
265-
)
266-
logging.getLogger("haystack").setLevel(logging.DEBUG)
267-
268-
tracing.tracer.is_content_tracing_enabled = (
269-
True # to enable tracing/logging content (inputs/outputs)
270-
)
271-
tracing.enable_tracing(
272-
LoggingTracer(
273-
tags_color_strings={
274-
"haystack.component.input": "\x1b[1;31m",
275-
"haystack.component.name": "\x1b[1;34m",
276-
},
277-
),
278-
)
279-
```
280-
281-
Here’s what the resulting log would look like when a pipeline is run:
282-
<ClickableImage src="/img/55c3d5c84282d726c95fb3350ec36be49a354edca8a6164f5dffdab7121cec58-image_2.png" alt="Console output showing Haystack pipeline execution with DEBUG level tracing logs including component names, types, and input/output specifications" />
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
title: "Custom Tracer"
3+
id: custom-tracer
4+
slug: "/tracing-custom-tracer"
5+
description: "Learn how to connect Haystack to a custom tracing backend by implementing the Tracer interface."
6+
---
7+
8+
# Custom Tracer
9+
10+
Learn how to connect Haystack to a custom tracing backend by implementing the `Tracer` interface.
11+
12+
<div className="key-value-table">
13+
14+
| | |
15+
| --- | --- |
16+
| **Base classes** | `Tracer` and `Span` |
17+
| **How to enable** | Implement the `Tracer` interface, then `tracing.enable_tracing(your_tracer)` |
18+
| **Content tracing** | Optional. Set `HAYSTACK_CONTENT_TRACING_ENABLED` to `true` to trace component inputs and outputs |
19+
| **Package** | Built into Haystack |
20+
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/tracing/tracer.py |
21+
22+
</div>
23+
24+
## Overview
25+
26+
If your tracing backend isn't supported out of the box, you can connect it to Haystack by implementing the `Tracer` interface. This gives you full control over how spans are created and how tags are recorded.
27+
28+
## Usage
29+
30+
1. Implement the `Tracer` interface. The following code snippet provides an example using the OpenTelemetry package:
31+
32+
```python
33+
import contextlib
34+
from typing import Optional, Dict, Any, Iterator
35+
36+
from opentelemetry import trace
37+
from opentelemetry.trace import NonRecordingSpan
38+
39+
from haystack.tracing import Tracer, Span
40+
from haystack.tracing import utils as tracing_utils
41+
import opentelemetry.trace
42+
43+
class OpenTelemetrySpan(Span):
44+
def __init__(self, span: opentelemetry.trace.Span) -> None:
45+
self._span = span
46+
47+
def set_tag(self, key: str, value: Any) -> None:
48+
# Tracing backends usually don't support any tag value
49+
# `coerce_tag_value` forces the value to either be a Python
50+
# primitive (int, float, boolean, str) or tries to dump it as string.
51+
coerced_value = tracing_utils.coerce_tag_value(value)
52+
self._span.set_attribute(key, coerced_value)
53+
54+
class OpenTelemetryTracer(Tracer):
55+
def __init__(self, tracer: opentelemetry.trace.Tracer) -> None:
56+
self._tracer = tracer
57+
58+
@contextlib.contextmanager
59+
def trace(self, operation_name: str, tags: Optional[Dict[str, Any]] = None) -> Iterator[Span]:
60+
with self._tracer.start_as_current_span(operation_name) as span:
61+
span = OpenTelemetrySpan(span)
62+
if tags:
63+
span.set_tags(tags)
64+
65+
yield span
66+
67+
def current_span(self) -> Optional[Span]:
68+
current_span = trace.get_current_span()
69+
if isinstance(current_span, NonRecordingSpan):
70+
return None
71+
72+
return OpenTelemetrySpan(current_span)
73+
```
74+
75+
2. Tell Haystack to use your custom tracer:
76+
77+
```python
78+
from haystack import tracing
79+
80+
haystack_tracer = OpenTelemetryTracer(tracer)
81+
tracing.enable_tracing(haystack_tracer)
82+
```

0 commit comments

Comments
 (0)