|
2 | 2 | title: "Tracing" |
3 | 3 | id: tracing |
4 | 4 | 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." |
6 | 6 | --- |
7 | 7 |
|
8 | | -import ClickableImage from "@site/src/components/ClickableImage"; |
9 | | - |
10 | 8 | # Tracing |
11 | 9 |
|
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. |
88 | 11 |
|
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. |
92 | 13 |
|
93 | | - from opentelemetry import trace |
94 | | - from opentelemetry.trace import NonRecordingSpan |
| 14 | +## Supported Tracers |
95 | 15 |
|
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. | |
142 | 25 |
|
143 | 26 | ## Disabling Auto Tracing |
144 | 27 |
|
145 | 28 | Haystack automatically detects and enables tracing under the following circumstances: |
146 | 29 |
|
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. |
149 | 32 |
|
150 | 33 | To disable this behavior, there are two options: |
151 | 34 |
|
@@ -180,103 +63,3 @@ To enable content tracing, there are two options: |
180 | 63 |
|
181 | 64 | tracing.tracer.is_content_tracing_enabled = True |
182 | 65 | ``` |
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" /> |
0 commit comments