| name | langfuse-observability |
| description | Set up comprehensive observability for Langfuse with metrics, dashboards, and alerts.
Use when implementing monitoring for LLM operations, setting up dashboards,
or configuring alerting for Langfuse integration health.
Trigger with phrases like "langfuse monitoring", "langfuse metrics",
"langfuse observability", "monitor langfuse", "langfuse alerts", "langfuse dashboard".
|
| allowed-tools | Read, Write, Edit |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Langfuse Observability
Overview
Set up comprehensive observability for Langfuse integrations including metrics, dashboards, and alerts.
Prerequisites
- Prometheus or compatible metrics backend
- Grafana or similar dashboarding tool
- AlertManager or PagerDuty configured
- Langfuse SDK integrated
Key Metrics
| Metric | Type | Description |
|---|
langfuse_traces_total | Counter | Total traces created |
langfuse_generations_total | Counter | Total LLM generations |
langfuse_generation_duration_seconds | Histogram | LLM call latency |
langfuse_tokens_total | Counter | Total tokens used |
langfuse_cost_usd_total | Counter | Total LLM cost |
langfuse_errors_total | Counter | Error count by type |
langfuse_flush_duration_seconds | Histogram | SDK flush latency |
Instructions
Step 1: Implement Prometheus Metrics
import { Registry, Counter, Histogram, Gauge } from "prom-client";
const registry = new Registry();
export const traceCounter = new Counter({
name: "langfuse_traces_total",
help: "Total Langfuse traces created",
labelNames: ["name", "status", "environment"],
registers: [registry],
});
export const generationCounter = new Counter({
name: "langfuse_generations_total",
help: "Total LLM generations",
labelNames: ["model", "status"],
registers: [registry],
});
export const generationDuration = new Histogram({
name: "langfuse_generation_duration_seconds",
help: "LLM generation duration",
labelNames: ["model"],
buckets: [0.1, 0.5, , , , , , ],
: [registry],
});
tokenCounter = ({
: ,
: ,
: [, ],
: [registry],
});
costCounter = ({
: ,
: ,
: [],
: [registry],
});
errorCounter = ({
: ,
: ,
: [, ],
: [registry],
});
flushDuration = ({
: ,
: ,
: [, , , , , , ],
: [registry],
});
pendingEventsGauge = ({
: ,
: ,
: [registry],
});
{ registry };
Step 2: Create Instrumented Langfuse Wrapper
import { Langfuse } from "langfuse";
import {
traceCounter,
generationCounter,
generationDuration,
tokenCounter,
costCounter,
errorCounter,
flushDuration,
} from "./metrics";
const MODEL_PRICING: Record<string, { input: number; output: number }> = {
"gpt-4-turbo": { input: 10.0, output: 30.0 },
"gpt-4o": { input: 5.0, output: 15.0 },
"gpt-4o-mini": { input: 0.15, output: 0.6 },
"claude-3-sonnet": { input: 3.0, output: 15.0 },
};
class InstrumentedLangfuse {
private langfuse: Langfuse;
private environment: string;
constructor(config: ConstructorParameters<typeof Langfuse>[0]) {
this.langfuse = (config);
. = process.. || ;
}
() {
trace = ..(params);
traceCounter.({
: params. || ,
: ,
: .,
});
originalUpdate = trace..(trace);
trace. = {
(updateParams. === ) {
traceCounter.({
: params. || ,
: ,
: .,
});
} (updateParams.) {
traceCounter.({
: params. || ,
: ,
: .,
});
}
(updateParams);
};
originalGeneration = trace..(trace);
trace. = {
startTime = .();
generation = (genParams);
model = genParams. || ;
generationCounter.({ model, : });
originalEnd = generation..(generation);
generation. = {
duration = (.() - startTime) / ;
generationDuration.({ model }, duration);
generationCounter.({ model, : });
(endParams?.) {
{ promptTokens = , completionTokens = } = endParams.;
tokenCounter.({ model, : }, promptTokens);
tokenCounter.({ model, : }, completionTokens);
pricing = [model];
(pricing) {
cost =
(promptTokens / ) * pricing. +
(completionTokens / ) * pricing.;
costCounter.({ model }, cost);
}
}
(endParams);
};
generation;
};
trace;
}
() {
timer = flushDuration.();
{
..();
} (error) {
errorCounter.({ : , : });
error;
} {
();
}
}
() {
..();
}
}
langfuse = ({
: process..!,
: process..!,
});
Step 3: Expose Metrics Endpoint
import { registry } from "@/lib/langfuse/metrics";
export async function GET() {
const metrics = await registry.metrics();
return new Response(metrics, {
headers: {
"Content-Type": registry.contentType,
},
});
}
Step 4: Configure Prometheus Scraping
scrape_configs:
- job_name: "llm-app"
static_configs:
- targets: ["app:3000"]
metrics_path: "/api/metrics"
scrape_interval: 15s
- job_name: "langfuse-cloud"
static_configs:
- targets: ["cloud.langfuse.com"]
scheme: https
metrics_path: "/api/public/metrics"
bearer_token: "${LANGFUSE_PUBLIC_KEY}"
Step 5: Create Grafana Dashboard
{
"dashboard": {
"title": "Langfuse LLM Observability",
"panels": [
{
"title": "LLM Requests per Second",
"type": "timeseries",
"targets": [{
"expr": "rate(langfuse_generations_total[5m])",
"legendFormat": "{{model}}"
}]
},
{
"title": "LLM Latency (P50/P95/P99)",
"type": "timeseries",
"targets": [
{
"expr": "histogram_quantile(0.5, rate(langfuse_generation_duration_seconds_bucket[5m]))",
"legendFormat":
Step 6: Configure Alerts
groups:
- name: langfuse_alerts
rules:
- alert: LangfuseHighErrorRate
expr: |
rate(langfuse_errors_total[5m]) /
rate(langfuse_generations_total[5m]) > 0.05
for: 5m
labels:
severity: warning
annotations:
summary: "Langfuse error rate > 5%"
description: "LLM error rate is {{ $value | humanizePercentage }}"
- alert: LangfuseHighLatency
expr: |
histogram_quantile(0.95,
rate(langfuse_generation_duration_seconds_bucket[5m])
) > 10
for: 5m
labels:
severity: warning
annotations:
summary: "LLM P95 latency > 10s"
- alert: LangfuseHighCost
expr: |
sum(rate(langfuse_cost_usd_total[1h])) * 24 > 100
for: 15m
labels:
severity: warning
annotations:
summary: "Projected daily LLM cost > $100"
Output
- Prometheus metrics for all Langfuse operations
- Instrumented Langfuse wrapper
- Metrics endpoint for scraping
- Grafana dashboard configuration
- AlertManager rules
Metrics Reference
| Dashboard Panel | Prometheus Query | Purpose |
|---|
| Request Rate | rate(langfuse_generations_total[5m]) | LLM throughput |
| Latency | histogram_quantile(0.95, ...) | Performance |
| Token Usage | rate(langfuse_tokens_total[1h]) | Usage tracking |
| Cost | sum(rate(langfuse_cost_usd_total[1h])) | Budget |
| Error Rate | rate(langfuse_errors_total[5m]) | Reliability |
Error Handling
| Issue | Cause | Solution |
|---|
| Missing metrics | No instrumentation | Use wrapped client |
| High cardinality | Too many labels | Limit label values |
| Alert storms | Wrong thresholds | Tune alert rules |
| Metric gaps | Scrape failures | Check Prometheus targets |
Resources
Next Steps
For incident response, see langfuse-incident-runbook.