Skip to content

Langfuse + Better Stack Integration Guide

This integration provides dual-layer observability for LLM operations:

  1. Better Stack + OpenTelemetry: General observability (logs, traces, metrics)
  2. Langfuse: Specialized LLM observability (prompts, responses, quality scoring)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Your App β”‚ β”‚ OpenTelemetry β”‚ β”‚ Better Stack β”‚
β”‚ │───▢│ Spans │───▢│ Dashboard β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ │───▢│ Langfuse │───▢│ Langfuse β”‚
β”‚ β”‚ β”‚ Traces β”‚ β”‚ Dashboard β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Add these to your .env files:

Terminal window
# Better Stack Configuration (existing)
OTEL_EXPORTER_OTLP_ENDPOINT=https://in-otel.betterstack.com
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <your-better-stack-token>
OTEL_SERVICE_NAME=pdf-processor-api
ENABLE_OBSERVABILITY=true
# Langfuse Configuration (new)
LANGFUSE_PUBLIC_KEY=pk_...
LANGFUSE_SECRET_KEY=sk_...
LANGFUSE_HOST=https://cloud.langfuse.com
# Environment for all Langfuse events (trace, spans, generations). Must match deployment.
# Set to staging/production so Langfuse UI filters and prompt env stay consistent.
LANGFUSE_TRACING_ENVIRONMENT=production
# Combined Features
ENABLE_DUAL_LLM_OBSERVABILITY=true

The Langfuse client uses a single environment value for all events (trace, spans, generations). If you don’t set it:

  • Trace/root span environment can come from OpenTelemetry resource attributes (OTEL_RESOURCE_ATTRIBUTES / deployment.environment), e.g. β€œstaging”.
  • Generation environment can come from the linked prompt’s environment in Langfuse (e.g. β€œproduction” for pdf_extraction_prompt_production).

That produces mixed environments in one trace (e.g. trace β€œstaging”, generations β€œproduction”). Set LANGFUSE_TRACING_ENVIRONMENT (or DEPLOYMENT_ENVIRONMENT) so all events use the same value. Coolify prod/staging scripts already set this.

  • General application traces and spans
  • Performance metrics
  • Error tracking
  • Infrastructure metrics
  • Service dependency mapping
  • LLM operation timing and success rates
  • Full prompt and response content
  • Token usage analytics
  • Cost tracking per request
  • Quality scoring
  • LLM-specific debugging
  • Prompt template management
  • User session tracking
  • JSON parsing success rates
  • Correlation IDs: All traces linked via correlation_id β†’ Langfuse session_id
  • OpenTelemetry trace IDs: Included in Langfuse trace metadata
  • End-to-end tracking: Query by correlation_id across webapp β†’ pdf-api β†’ pdf-worker
  • Unified logging: Both trace IDs included in structured logs

Correlation ID Flow:

Webapp (middleware) β†’ pdf-api (headers) β†’ Celery task (task_metadata) β†’ Langfuse (session_id)

As of January 2026, we use Mirascope’s native @with_langfuse() decorator for automatic LLM tracing. This replaces manual span management and provides automatic model, token, and cost tracking.

The pdf-worker uses two Flagsmith flags; both must be enabled for the Mirascope + Langfuse path:

  1. use_mirascope – Use Mirascope for PDF/LLM extraction (gates the Mirascope code path).
  2. use_mirascope_langfuse – Use Mirascope’s @with_langfuse() for automatic LLM tracing.

If either is disabled (default), the worker uses the legacy path (manual Langfuse spans). To verify which path ran, check logs for "PDF extraction path" with extraction_path, use_mirascope, and use_mirascope_langfuse.

To enable in production: In Flagsmith (production environment), enable both use_mirascope and use_mirascope_langfuse. If use_mirascope is missing in Flagsmith, seed flags using 1Password credentials: from infrastructure/flagsmith/scripts run ./import-flags-with-op.sh --update (reads API URL and admin credentials from 1Password via op). Alternatively run ./bootstrap-flagsmith.sh production from infrastructure/flagsmith, or the GitHub Action β€œSeed Flagsmith Flags” with environment production.

from mirascope.integrations.langfuse import with_langfuse
from mirascope import llm
from pdf_shared.llm.extractors import extract_orders_from_document
# Automatic tracing via @with_langfuse() decorator
# Model, tokens, cost, latency all captured automatically
result = extract_orders_from_document(
document_content=chunk_path,
prompt_text=prompt_text,
document_type="pdf",
context=ctx, # Contains correlation_id for session linking
)

Benefits:

  • βœ… Automatic model tracking (from feature flags)
  • βœ… Automatic token usage tracking
  • βœ… Automatic cost calculation
  • βœ… Automatic latency measurement
  • βœ… Session linking via correlation_id
  • βœ… ~250 lines of boilerplate removed

When use_mirascope_langfuse is disabled, the system falls back to manual Langfuse span management:

# Manual span creation (legacy path)
span = langfuse_client.start_span(name="process_document_task", ...)
generation = span.start_generation(model="gemini-2.5-flash", ...)
# ... LLM call ...
generation.update(usage_details={...})
generation.end()
span.end()

Note: The legacy path is maintained for backward compatibility but will be removed in a future release.

  • Go to Better Stack dashboard
  • View traces, logs, and metrics
  • Set up alerts for performance issues
  • Monitor service health
  • Look for spans named llm.pdf_extraction
  • Go to Langfuse dashboard
  • View LLM traces and sessions
  • Analyze prompt performance
  • Track costs and usage
  • Debug LLM quality issues
  • Look for traces named pdf_extraction

Run the test script to verify everything is working:

Terminal window
cd apps/pdf-worker
test_langfuse.sh

This will:

  1. Check environment variables
  2. Test Langfuse client initialization
  3. Create a test trace with all observability data
  4. Verify both systems are receiving data
  1. Comprehensive Coverage: Both general app performance and LLM-specific insights
  2. Specialized Tools: Langfuse provides LLM debugging tools that Better Stack doesn’t
  3. Cost Optimization: Track LLM costs and optimize expensive operations
  4. Quality Monitoring: Monitor LLM response quality and prompt effectiveness
  5. Unified Debugging: Correlate issues across both platforms using trace IDs
  1. Check Environment Variables:

    Terminal window
    echo $LANGFUSE_PUBLIC_KEY
    echo $LANGFUSE_SECRET_KEY
  2. Check Logs: Look for these messages:

    βœ… Langfuse initialized for LLM observability
    Started Langfuse trace
  3. Run Test Script:

    Terminal window
    test_langfuse.sh
  1. Check Better Stack Configuration:

    Terminal window
    echo $OTEL_EXPORTER_OTLP_ENDPOINT
    echo $OTEL_EXPORTER_OTLP_HEADERS
  2. Check Service Name:

    Terminal window
    echo $OTEL_SERVICE_NAME
  • Both systems should show the same OpenTelemetry trace ID
  • Langfuse traces include otel_trace_id in metadata
  • Check logs for both trace IDs being recorded

If you were using the previous LLM observability setup:

  1. No Breaking Changes: The existing API is preserved
  2. Enhanced Features: New methods for Langfuse integration
  3. Backward Compatible: Works with or without Langfuse configured
  4. Gradual Migration: Can be enabled per service
  • Minimal Overhead: Langfuse operations are asynchronous
  • Graceful Degradation: Works even if Langfuse is unavailable
  • Error Handling: Failed Langfuse operations don’t affect main flow
  • Resource Usage: Additional memory for trace objects (~1KB per trace)
  • API Keys: Store Langfuse keys securely
  • Data Privacy: Prompts and responses are sent to Langfuse
  • Network: Ensure HTTPS connections to Langfuse
  • Access Control: Use appropriate Langfuse project permissions
  1. Set Environment Variables: Configure Langfuse credentials
  2. Test Integration: Run the test script
  3. Monitor Dashboards: Check both Better Stack and Langfuse
  4. Optimize Prompts: Use Langfuse insights to improve LLM performance
  5. Set Up Alerts: Configure monitoring for LLM quality and costs