Langfuse
Export OpenTelemetry traces from Langfuse to Last9 for unified LLM observability and monitoring
Monitor your LLM applications with Langfuse traces exported to Last9. Combine Langfuse’s prompt management and evaluation capabilities with Last9’s observability platform for comprehensive AI monitoring.
What is Langfuse?
Langfuse is an open-source LLM engineering platform that provides observability, prompt management, and evaluation tools for AI applications. It helps teams debug, analyze, and iterate on their LLM-powered features.
Key capabilities include:
- Tracing - Track LLM calls, chains, and agents with detailed span data
- Prompt management - Version and deploy prompts with built-in experimentation
- Evaluation - Score and analyze LLM outputs for quality monitoring
- OpenTelemetry export - Send trace data to external observability platforms
Prerequisites
Before setting up the integration:
- Last9 Account - Sign up at app.last9.io
- Langfuse Account - Create an account at langfuse.com or self-host Langfuse
- LLM Application - An existing application instrumented with Langfuse SDK
Instrument Your Application
If you haven’t already instrumented your application with Langfuse, here’s how to get started:
-
Install the Langfuse SDK
pip install langfuse -
Configure Langfuse Credentials
Set your Langfuse credentials as environment variables:
export LANGFUSE_PUBLIC_KEY="pk-..."export LANGFUSE_SECRET_KEY="sk-..."export LANGFUSE_HOST="https://cloud.langfuse.com" # or your self-hosted URL -
Instrument Your LLM Calls
Use the
@observedecorator to trace your LLM operations:from langfuse import observefrom openai import OpenAIclient = OpenAI()@observe()def answer_question(question: str) -> str:response = client.chat.completions.create(model="gpt-4",messages=[{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": question}])return response.choices[0].message.content# Usageanswer = answer_question("What is observability?")For framework integrations:
# LangChain integrationfrom langfuse.langchain import CallbackHandlerlangfuse_handler = CallbackHandler()# Pass to your LangChain callschain.invoke({"input": "Hello"}, config={"callbacks": [langfuse_handler]})
-
Install the Langfuse SDK
The Langfuse JS/TS SDK is OpenTelemetry-native. Install the tracing package:
npm install @langfuse/tracing -
Configure Langfuse Credentials
Set your Langfuse credentials as environment variables:
export LANGFUSE_PUBLIC_KEY="pk-..."export LANGFUSE_SECRET_KEY="sk-..."export LANGFUSE_HOST="https://cloud.langfuse.com" # or your self-hosted URL -
Instrument Your LLM Calls
Use
startActiveObservationto trace your LLM operations:import { startActiveObservation } from "@langfuse/tracing";import OpenAI from "openai";const openai = new OpenAI();async function answerQuestion(question: string): Promise<string> {return startActiveObservation("answer-question", async (span) => {span.update({ input: question });const response = await openai.chat.completions.create({model: "gpt-4",messages: [{ role: "system", content: "You are a helpful assistant." },{ role: "user", content: question },],});const answer = response.choices[0].message.content;span.update({ output: answer });return answer;});}
Integration Setup
The Langfuse SDK (v3+) is OpenTelemetry-native, so add Last9 as a second span processor in your application’s own OpenTelemetry setup. Langfuse has no deployment-level or dashboard toggle that forwards traces to a third-party OTLP backend. This works the same way for Langfuse Cloud and self-hosted Langfuse.
-
Get Your Last9 OTel Credentials
Navigate to Integrations → OpenTelemetry in your Last9 dashboard. Copy the OTel Endpoint and Auth Header values.
-
Install the OpenTelemetry Exporter
pip install opentelemetry-exporter-otlp-proto-http -
Add Last9 as a Second Span Processor
The Langfuse Python SDK doesn’t expose a standalone
LangfuseSpanProcessor— instead, pass your ownTracerProviderto theLangfuseclient, and attach Last9’s exporter to that same provider. This requires the Langfuse credentials (LANGFUSE_PUBLIC_KEY,LANGFUSE_SECRET_KEY,LANGFUSE_HOST) from Instrument Your Application:from langfuse import Langfusefrom opentelemetry import tracefrom opentelemetry.sdk.resources import Resourcefrom opentelemetry.sdk.trace import TracerProviderfrom opentelemetry.sdk.trace.export import BatchSpanProcessorfrom opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporterprovider = TracerProvider(resource=Resource.create({"service.name": "my-llm-app"}))provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint="https://otlp.last9.io/v1/traces",headers={"Authorization": "<your-auth-header>"},)))trace.set_tracer_provider(provider)langfuse = Langfuse(tracer_provider=provider)Replace
<your-auth-header>with the full Auth Header value from Step 1, including theBasicprefix. Replacemy-llm-appwith your service name. Set this up once, before any@observe-decorated code runs — constructingLangfuse(...)registers it as the client@observeandget_client()use. -
Verify the Integration
Make some LLM calls through your Langfuse-instrumented application, then check the Last9 Traces Explorer to see your traces.
-
Get Your Last9 OTel Credentials
Navigate to Integrations → OpenTelemetry in your Last9 dashboard. Copy the OTel Endpoint and Auth Header values.
-
Install the OpenTelemetry Packages
npm install @langfuse/otel @langfuse/tracing @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-http @opentelemetry/sdk-trace-base -
Add Last9 as a Second Span Processor
In your OpenTelemetry setup (e.g.
instrumentation.ts), add Last9’s exporter alongside Langfuse’s:import { NodeSDK } from "@opentelemetry/sdk-node";import { LangfuseSpanProcessor } from "@langfuse/otel";import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";import { SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";const sdk = new NodeSDK({serviceName: "my-llm-app",spanProcessors: [new LangfuseSpanProcessor(),new SimpleSpanProcessor(new OTLPTraceExporter({url: "https://otlp.last9.io/v1/traces",headers: { Authorization: "<your-auth-header>" },}),),],});sdk.start();Replace
<your-auth-header>with the full Auth Header value from Step 1, including theBasicprefix. Replacemy-llm-appwith your service name. Import this file before any other application code runs. -
Verify the Integration
Make some LLM calls through your Langfuse-instrumented application, then check the Last9 Traces Explorer to see your traces.
View Traces in Last9
After the integration is active, your Langfuse traces appear in Last9:
- Navigate to Traces Explorer
- Filter by the service name you set in Integration Setup, for example
my-llm-app - Explore trace data including:
- LLM generations - Model calls with prompts, completions, and token counts
- Trace hierarchy - Parent-child relationships between operations
- Latency breakdown - Time spent in each span
- Metadata - Custom attributes and tags from Langfuse
Correlate with Application Traces
Langfuse and Last9 share the same OpenTelemetry TracerProvider, which you set up in Integration Setup. As a result, Langfuse spans and your application’s other spans already share the same trace ID, so you do not need to propagate metadata manually. A request that flows through your app and into an @observe-decorated LLM call shows up as a single trace in Last9’s Traces Explorer.
Advanced Configuration
Filter Exported Traces
The BatchSpanProcessor / SimpleSpanProcessor you added for Last9 receives every span from the shared TracerProvider, independent of Langfuse’s own export filtering. To reduce volume sent to Last9, add a span processor filter or an OpenTelemetry Collector-based sampler in front of the exporter, rather than relying on Langfuse-side settings.
Custom Attributes
Add custom attributes to your Langfuse traces that will appear in Last9. Wrap the operation in propagate_attributes rather than calling a trace-update method on the client:
from langfuse import observe, propagate_attributes
@observe()def process_document(doc_id: str, user_id: str): # Your logic here pass
# Usagewith propagate_attributes( user_id="user-123", metadata={ "document_id": "doc-456", "environment": "production", "feature": "document-qa", }, tags=["production", "document-processing"],): process_document("doc-456", "user-123")These attributes enable filtering and grouping in Last9’s Traces Explorer.
Use Cases
- Unified Observability - View LLM traces alongside your application’s HTTP requests, database queries, and other operations in a single platform.
- Production Monitoring - Set up alerts on LLM latency, error rates, and token consumption using Last9’s alerting capabilities.
- Cost Analysis - Correlate Langfuse’s token tracking with Last9’s analytics to understand LLM costs per feature or user segment.
- Debugging - Trace issues from Last9 alerts back to specific Langfuse generations, prompts, and model responses.
- Compliance - Maintain a complete audit trail of all LLM interactions in your observability infrastructure.
Troubleshooting
-
Traces do not appear in Last9
- Verify the
OTLPSpanExporter/OTLPTraceExporterendpoint is set tohttps://otlp.last9.io/v1/traces - Confirm the exporter’s
Authorizationheader is correctly configured (including theBasicprefix) - Ensure the Last9 span processor is registered on the same
TracerProviderasLangfuseSpanProcessor, and that this setup runs before any@observe-decorated code orstartActiveObservationcalls - Ensure your Langfuse application is generating traces (check the Langfuse dashboard first)
- In Node.js, confirm the process calls
sdk.shutdown()(or otherwise flushes) before exit so batched spans aren’t dropped
- Verify the
Please get in touch with us on Discord or Email if you have any questions.