Langfuse + Better Stack Integration Guide
Overview
Section titled βOverviewβThis integration provides dual-layer observability for LLM operations:
- Better Stack + OpenTelemetry: General observability (logs, traces, metrics)
- Langfuse: Specialized LLM observability (prompts, responses, quality scoring)
Architecture
Section titled βArchitectureββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ Your App β β OpenTelemetry β β Better Stack ββ βββββΆβ Spans βββββΆβ Dashboard ββ β β β β ββ β ββββββββββββββββββββ ββββββββββββββββββββ ββ β ββββββββββββββββββββ ββββββββββββββββββββ βββββΆβ Langfuse βββββΆβ Langfuse ββ β β Traces β β Dashboard ββββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββEnvironment Variables
Section titled βEnvironment VariablesβAdd these to your .env files:
# Better Stack Configuration (existing)OTEL_EXPORTER_OTLP_ENDPOINT=https://in-otel.betterstack.comOTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <your-better-stack-token>OTEL_SERVICE_NAME=pdf-processor-apiENABLE_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 FeaturesENABLE_DUAL_LLM_OBSERVABILITY=trueWhy LANGFUSE_TRACING_ENVIRONMENT matters
Section titled βWhy LANGFUSE_TRACING_ENVIRONMENT mattersβ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.
Features
Section titled βFeaturesβWhat Goes to Better Stack
Section titled βWhat Goes to Better Stackβ- General application traces and spans
- Performance metrics
- Error tracking
- Infrastructure metrics
- Service dependency mapping
- LLM operation timing and success rates
What Goes to Langfuse
Section titled βWhat Goes to Langfuseβ- 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
Cross-Platform Linking
Section titled βCross-Platform Linkingβ- Correlation IDs: All traces linked via
correlation_idβ Langfusesession_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)Modern Implementation: Mirascope + @with_langfuse()
Section titled βModern Implementation: Mirascope + @with_langfuse()β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.
Feature Flags (both required for Mirascope path)
Section titled βFeature Flags (both required for Mirascope path)βThe pdf-worker uses two Flagsmith flags; both must be enabled for the Mirascope + Langfuse path:
- use_mirascope β Use Mirascope for PDF/LLM extraction (gates the Mirascope code path).
- 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.
Modern Usage (Recommended)
Section titled βModern Usage (Recommended)βfrom mirascope.integrations.langfuse import with_langfusefrom mirascope import llmfrom pdf_shared.llm.extractors import extract_orders_from_document
# Automatic tracing via @with_langfuse() decorator# Model, tokens, cost, latency all captured automaticallyresult = 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
Legacy Implementation (Manual Tracing)
Section titled βLegacy Implementation (Manual Tracing)β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.
Dashboard Setup
Section titled βDashboard SetupβBetter Stack
Section titled βBetter Stackβ- 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
Langfuse
Section titled βLangfuseβ- 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
Testing the Integration
Section titled βTesting the IntegrationβRun the test script to verify everything is working:
cd apps/pdf-workertest_langfuse.shThis will:
- Check environment variables
- Test Langfuse client initialization
- Create a test trace with all observability data
- Verify both systems are receiving data
Benefits
Section titled βBenefitsβ- Comprehensive Coverage: Both general app performance and LLM-specific insights
- Specialized Tools: Langfuse provides LLM debugging tools that Better Stack doesnβt
- Cost Optimization: Track LLM costs and optimize expensive operations
- Quality Monitoring: Monitor LLM response quality and prompt effectiveness
- Unified Debugging: Correlate issues across both platforms using trace IDs
Troubleshooting
Section titled βTroubleshootingβNo Langfuse Traces Appearing
Section titled βNo Langfuse Traces Appearingβ-
Check Environment Variables:
Terminal window echo $LANGFUSE_PUBLIC_KEYecho $LANGFUSE_SECRET_KEY -
Check Logs: Look for these messages:
β Langfuse initialized for LLM observabilityStarted Langfuse trace -
Run Test Script:
Terminal window test_langfuse.sh
No OpenTelemetry Spans in Better Stack
Section titled βNo OpenTelemetry Spans in Better Stackβ-
Check Better Stack Configuration:
Terminal window echo $OTEL_EXPORTER_OTLP_ENDPOINTecho $OTEL_EXPORTER_OTLP_HEADERS -
Check Service Name:
Terminal window echo $OTEL_SERVICE_NAME
Trace IDs Not Linking
Section titled βTrace IDs Not Linkingβ- Both systems should show the same OpenTelemetry trace ID
- Langfuse traces include
otel_trace_idin metadata - Check logs for both trace IDs being recorded
Migration from Previous Setup
Section titled βMigration from Previous SetupβIf you were using the previous LLM observability setup:
- No Breaking Changes: The existing API is preserved
- Enhanced Features: New methods for Langfuse integration
- Backward Compatible: Works with or without Langfuse configured
- Gradual Migration: Can be enabled per service
Performance Impact
Section titled βPerformance Impactβ- 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)
Security Considerations
Section titled βSecurity Considerationsβ- 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
Next Steps
Section titled βNext Stepsβ- Set Environment Variables: Configure Langfuse credentials
- Test Integration: Run the test script
- Monitor Dashboards: Check both Better Stack and Langfuse
- Optimize Prompts: Use Langfuse insights to improve LLM performance
- Set Up Alerts: Configure monitoring for LLM quality and costs