Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Configure Langfuse to send OTel spans to the Azure Databricks OTLP endpoint. Traces are stored in Unity Catalog tables alongside your other MLflow traces, where you can query and compare them with SQL or view them in the MLflow UI.
Consolidating traces on Azure Databricks lets you:
- Query and compare Langfuse-instrumented calls together with traces from other frameworks in a single place.
- Use Azure Databricks SQL to analyze trace data at scale.
- Apply Unity Catalog governance such as access controls and lineage to all your traces.
Requirements
- A Unity Catalog-enabled workspace.
- Permissions to create catalogs and schemas in Unity Catalog.
- A Databricks SQL warehouse with
CAN USEpermission for viewing traces. - A workspace in a supported region. See Features with limited regional availability.
- An MLflow experiment with a UC trace location. For setup details, see Requirements.
- The following Unity Catalog permissions on the catalog and schema used to store traces:
USE_CATALOGandUSE_SCHEMAon the catalog and schema.MODIFYandSELECTon the<table_prefix>_otel_*tables. See Grant permissions.CREATE TABLEon the schema, so that the setup step can create the trace tables for the new experiment.
Step 1: Install packages
Install the required packages in your Azure Databricks notebook:
%pip install "langfuse>=3.14.5" "mlflow[databricks]>=3.14.0" opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http
%restart_python
Step 2: Disable Langfuse trace collection
Langfuse initializes its SDK from the LANGFUSE_HOST, LANGFUSE_PUBLIC_KEY, and LANGFUSE_SECRET_KEY environment variables. Set them to dummy values so spans go only to the Azure Databricks exporter added in step 5.
import os
os.environ["LANGFUSE_HOST"] = "localhost"
os.environ["LANGFUSE_PUBLIC_KEY"] = ""
os.environ["LANGFUSE_SECRET_KEY"] = ""
Note
Alternatively, set LANGFUSE_TRACING_ENABLED=False to disable Langfuse's built-in trace collection.
Step 3: Configure the Azure Databricks connection
Retrieve your workspace host URL and API token. In a Azure Databricks notebook, get them from the notebook context:
# If running outside a Databricks notebook, set DATABRICKS_HOST and DATABRICKS_TOKEN environment variables manually.
context = dbutils.notebook.entry_point.getDbutils().notebook().getContext()
DATABRICKS_HOST = context.apiUrl().get().rstrip("/")
DATABRICKS_TOKEN = context.apiToken().get()
Step 4: Link an experiment to Unity Catalog
Bind a Unity Catalog catalog, schema, and table prefix to an MLflow experiment. This tells Azure Databricks where to store incoming traces.
import mlflow
from mlflow.entities.trace_location import UnityCatalog
experiment = mlflow.set_experiment(
experiment_name="<MLFLOW_EXPERIMENT_NAME>",
trace_location=UnityCatalog(
catalog_name="<UC_CATALOG_NAME>",
schema_name="<UC_SCHEMA_NAME>",
table_prefix="<UC_TABLE_PREFIX>",
),
)
For full setup details, see Create an experiment with a Unity Catalog trace location.
Step 5: Add the Azure Databricks OTLP exporter
Retrieve the TracerProvider that Langfuse registers as the global OTel provider, then attach a BatchSpanProcessor that points to the Azure Databricks OTLP endpoint. The X-Databricks-UC-Table-Name header routes incoming spans to the Unity Catalog table defined by the trace location.
from langfuse import get_client
from opentelemetry import trace as otel_trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace.export import BatchSpanProcessor
# Initialize the Langfuse client. Langfuse registers its own TracerProvider as the global OTel TracerProvider.
langfuse = get_client()
# Retrieve the global TracerProvider to attach an additional span processor.
provider = otel_trace.get_tracer_provider()
databricks_exporter = OTLPSpanExporter(
endpoint=f"{DATABRICKS_HOST}/api/2.0/otel/v1/traces",
headers={
"content-type": "application/x-protobuf",
"Authorization": f"Bearer {DATABRICKS_TOKEN}",
"X-Databricks-UC-Table-Name": experiment.trace_location.full_otel_spans_table_name,
},
)
# Because the Langfuse env vars are set to dummy values, this processor is the only
# active exporter, so all spans go exclusively to Databricks.
provider.add_span_processor(BatchSpanProcessor(databricks_exporter))
Step 6: Run a traced function
Use Langfuse's @observe() decorator to instrument your agent. The decorator creates OTel spans that the exporter sends to Azure Databricks.
from langfuse import observe
@observe()
def my_llm_call(prompt: str) -> str:
# Replace with your LLM logic (OpenAI, Anthropic, etc.)
return f"Response to: {prompt}"
@observe()
def my_pipeline(user_input: str) -> str:
result = my_llm_call(user_input)
return result
my_pipeline("Hello, world!")
Step 7: View traces
Open the MLflow experiment in your Azure Databricks workspace and click the Traces tab. The trace from the my_pipeline call appears.
To search for ingested Langfuse traces by OTel span attribute values, see Search for traces by OTel span attributes.