# Langflow Tracing and Observability Integrations: Complete Guide to LangSmith, LangFuse, and More

> Explore Langflow integrations for tracing and observability with LangSmith, LangFuse, and more. Discover how to monitor your LLM applications effectively and enhance performance.

- Repository: [Langflow/langflow](https://github.com/langflow-ai/langflow)
- Tags: tutorial
- Published: 2026-02-24

---

**Langflow natively supports seven observability platforms—including LangSmith, LangFuse, LangWatch, Opik, Arize Phoenix, and Traceloop—through a modular tracing service that automatically activates when specific environment variables are present.**

The `langflow-ai/langflow` repository implements a comprehensive tracing and observability system in `src/backend/base/langflow/services/tracing/` that forwards execution data from flow runs to third-party monitoring backends. This architecture requires no application code changes; integrations activate automatically based on environment configuration, using an abstract `BaseTracer` contract to standardize telemetry collection across diverse platforms.

## Supported Observability Integrations

Langflow's `TracingService` detects and initializes tracer implementations based on the presence of vendor-specific environment variables. Each integration implements the `BaseTracer` interface defined in [`src/backend/base/langflow/services/tracing/base.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/services/tracing/base.py).

### LangSmith

**Activation:** Set `LANGCHAIN_API_KEY`. Langflow automatically injects `LANGCHAIN_TRACING_V2="true"`.

**Implementation:** The `LangSmithTracer` class in [`src/backend/base/langflow/services/tracing/langsmith.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/services/tracing/langsmith.py) constructs run trees and component spans using the LangSmith client. It converts internal Langflow `Message` and `Data` objects to LangChain-compatible types via `_convert_to_langchain_types`.

### LangFuse

**Activation:** Define `LANGFUSE_SECRET_KEY`, `LANGFUSE_PUBLIC_KEY`, and `LANGFUSE_HOST`.

**Implementation:** `LangFuseTracer` (located in [`src/backend/base/langflow/services/tracing/langfuse.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/services/tracing/langfuse.py)) creates hierarchical spans with inputs, outputs, metadata, and error information using `self.trace.span()` calls.

### LangWatch

**Activation:** Set `LANGWATCH_API_KEY` and optionally `LANGWATCH_ENDPOINT`.

**Implementation:** The `LangWatchTracer` in [`src/backend/base/langflow/services/tracing/langwatch.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/services/tracing/langwatch.py) exports OpenTelemetry spans to LangWatch’s OTLP endpoint, converting data via `_convert_to_langwatch_types`.

### Opik

**Activation:** Configure `OPIK_PROJECT_NAME` and ensure valid Opik client configuration is present.

**Implementation:** `OpikTracer` ([`src/backend/base/langflow/services/tracing/opik.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/services/tracing/opik.py)) manages trace and span objects with distributed-header propagation support.

### Arize Phoenix

**Activation:** Provide `ARIZE_PHOENIX_API_KEY` and `ARIZE_PHOENIX_ENDPOINT`.

**Implementation:** The `ArizePhoenixTracer` in [`src/backend/base/langflow/services/tracing/arize_phoenix.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/services/tracing/arize_phoenix.py) implements a span processor that forwards telemetry to Arize Phoenix endpoints.

### Traceloop

**Activation:** Set `TRACEELOOP_API_KEY`.

**Implementation:** `TraceloopTracer` ([`src/backend/base/langflow/services/tracing/traceloop.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/services/tracing/traceloop.py)) provides automatic LangChain-compatible instrumentation via the Traceloop SDK.

### Minimal LFX Tracing

**Fallback behavior:** When `deactivate_tracing` is disabled and no external variables are set, the system uses a minimal in-process tracer defined in [`src/lfx/src/lfx/services/tracing/service.py`](https://github.com/langflow-ai/langflow/blob/main/src/lfx/src/lfx/services/tracing/service.py) for local log entries.

## Internal Architecture and Data Flow

### The BaseTracer Contract

All integrations inherit from `BaseTracer` in [`src/backend/base/langflow/services/tracing/base.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/services/tracing/base.py), which defines the interface for `add_trace`, `set_outputs`, `end_trace`, and `get_langchain_callbacks`. This abstraction allows `TracingService` to remain agnostic to specific vendor implementations.

### TraceContext and Async Processing

When a graph run starts, `TracingService.create_trace_context()` instantiates a **TraceContext** object containing:
- `run_id`, `run_name`, `user_id`, `session_id`
- A per-run **async queue** (`traces_queue`)
- A dictionary of active tracers

The service spawns a background `_trace_worker` that drains the queue sequentially, ensuring network I/O does not block graph execution. All tracer method calls are enqueued via `TraceContext.traces_queue.put_nowait()`.

### Lazy Initialization Pattern

The `TracingService._start()` method in [`src/backend/base/langflow/services/tracing/service.py`](https://github.com/langflow-ai/langflow/blob/main/src/backend/base/langflow/services/tracing/service.py) lazily instantiates tracers through helper methods like `_initialize_langsmith_tracer()` and `_initialize_langfuse_tracer()`. Each helper checks for required environment variables and SDK availability:

```python
def _initialize_langsmith_tracer(self, ctx):
    if not os.getenv("LANGCHAIN_API_KEY"):
        return
    ctx.tracers["langsmith"] = _get_langsmith_tracer()(
        trace_name=ctx.run_name,
        trace_type="chain",
        project_name=ctx.project_name,
        trace_id=ctx.run_id,
    )

```

If import or authentication fails, the tracer sets `_ready = False` and is silently omitted from the active tracer list.

### Metadata Conversion

Concrete tracers implement conversion helpers to transform Langflow internal types:
- `_convert_to_langchain_types()` for LangSmith compatibility
- `_convert_to_opik_types()` for Opik traces
- `_convert_to_langwatch_types()` for LangWatch spans

These methods recursively process `Message`, `Data`, and arbitrary Python objects into JSON-serializable dictionaries or vendor-specific message formats.

## Configuring Tracing Integrations

Enable observability by setting environment variables before starting Langflow. No code changes are required.

### Enabling LangSmith

```bash
export LANGCHAIN_API_KEY="sk-your-key"

# LANGCHAIN_TRACING_V2 is automatically set by Langflow

```

### Enabling LangFuse

```bash
export LANGFUSE_PUBLIC_KEY="public-key"
export LANGFUSE_SECRET_KEY="secret-key"
export LANGFUSE_HOST="https://cloud.langfuse.com"

```

### Enabling LangWatch

```bash
export LANGWATCH_API_KEY="your-api-key"
export LANGWATCH_ENDPOINT="https://api.langwatch.com"  # Optional

```

## Programmatic Tracing API

For custom instrumentation within components, use the `TracingService` directly.

### Manual Trace Context Management

```python
from langflow.services.tracing.service import TracingService
from uuid import uuid4

# Initialize service with settings that do not deactivate tracing

tracing = TracingService(settings_service=my_settings)

# Start a run session

run_id = uuid4()
await tracing.start_tracers(
    run_id=run_id,
    run_name="example-run",
    user_id="user-123",
    session_id="sess-abc",
    project_name="demo-proj",
)

# Trace component execution

async with tracing.trace_component(
    component=my_component,
    trace_name="my-component",
    inputs={"query": "user input"},
) as ctx:
    result = await my_component.run()
    tracing.set_outputs("my-component", {"result": result})

```

### Adding Custom Logs

```python
import time

tracing.add_log("my-component", {
    "event": "processing_started",
    "timestamp": time.time(),
    "metadata": {"batch_size": 10}
})

```

### Error Handling

Errors are automatically captured via `_error_to_string()` methods that serialize stack traces into the trace metadata before `end_trace()` finalizes the span.

## Summary

- Langflow provides **seven production-ready observability integrations** through a unified tracing architecture in `src/backend/base/langflow/services/tracing/`.
- The **modular design** uses `BaseTracer` abstractions and lazy initialization based on environment variable detection.
- **Zero-code configuration** activates tracers like LangSmith (`LANGCHAIN_API_KEY`) and LangFuse (`LANGFUSE_SECRET_KEY`) automatically.
- **Async queue processing** ensures telemetry export does not block flow execution, managed by `TraceContext` and `_trace_worker`.
- Metadata conversion helpers normalize Langflow's internal `Message` and `Data` types to vendor-specific formats.
- Programmatic access via `trace_component()` context managers allows custom instrumentation within component logic.

## Frequently Asked Questions

### How do I enable LangSmith tracing in Langflow?

Set the `LANGCHAIN_API_KEY` environment variable. Langflow automatically detects this in `TracingService._initialize_langsmith_tracer()` and instantiates the `LangSmithTracer` class. The system also injects `LANGCHAIN_TRACING_V2="true"` automatically. No code changes are required within your flows.

### What is the difference between LangSmith and LangFuse integrations?

**LangSmith** focuses on LangChain-compatible run trees and uses `_convert_to_langchain_types()` for data serialization, requiring only `LANGCHAIN_API_KEY`. **LangFuse** provides hierarchical span management with explicit input/output tracking via `self.trace.span()` calls, requiring three variables: `LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`, and `LANGFUSE_HOST`. LangFuse also captures more granular metadata by default.

### Can I use multiple tracing providers simultaneously?

Yes. `TracingService` maintains a dictionary of active tracers in `TraceContext.tracers`. If you set environment variables for multiple providers (e.g., both LangSmith and LangFuse), both tracers initialize and receive identical trace data through the async queue. Each tracer processes the data independently according to its vendor-specific conversion logic.

### Where are the tracer implementations located in the codebase?

Concrete implementations reside in `src/backend/base/langflow/services/tracing/`:
- LangSmith: [`langsmith.py`](https://github.com/langflow-ai/langflow/blob/main/langsmith.py)
- LangFuse: [`langfuse.py`](https://github.com/langflow-ai/langflow/blob/main/langfuse.py)
- LangWatch: [`langwatch.py`](https://github.com/langflow-ai/langflow/blob/main/langwatch.py)
- Opik: [`opik.py`](https://github.com/langflow-ai/langflow/blob/main/opik.py)
- Arize Phoenix: [`arize_phoenix.py`](https://github.com/langflow-ai/langflow/blob/main/arize_phoenix.py)
- Traceloop: [`traceloop.py`](https://github.com/langflow-ai/langflow/blob/main/traceloop.py)

The abstract contract is defined in [`base.py`](https://github.com/langflow-ai/langflow/blob/main/base.py), while the central orchestration logic lives in [`service.py`](https://github.com/langflow-ai/langflow/blob/main/service.py).