Skip to content

Querying Traces by Correlation ID in Better Stack

This guide explains how to use correlation IDs to query and debug end-to-end traces across all services in Better Stack.

Correlation IDs enable unified tracing across the entire ERP-Unlocked platform. A single correlation ID tracks a request from the webapp through Temporal workflows, Dagster pipelines, PDF processing, and all other services.

A correlation ID is a UUID v4 generated at the entry point (webapp middleware) that:

  • Propagates via HTTP headers (x-correlation-id)
  • Passes through Temporal workflow payloads (correlationId in workflow input)
  • Included in Dagster run tags (correlation_id)
  • Used as Langfuse session_id for LLM operations
  • Set as a span attribute (correlation.id) on all OpenTelemetry spans

Every HTTP response from the webapp includes the x-correlation-id header:

Terminal window
curl -i https://app.erpunlocked.com/api/erp/connections/123/sync
# Response includes:
# x-correlation-id: 550e8400-e29b-41d4-a716-446655440000

All services log the correlation ID in structured logs:

{
"level": "info",
"message": "Starting ERP sync",
"correlation_id": "550e8400-e29b-41d4-a716-446655440000",
"connection_id": "123"
}
  1. Navigate to Traces in Better Stack
  2. Click on any span
  3. Look for the correlation.id attribute in span details
  1. Go to Traces in Better Stack
  2. Click the Filter button
  3. Add filter: correlation.id = "550e8400-e29b-41d4-a716-446655440000"
  4. Click Apply

This will show all spans across all services that share this correlation ID.

Use Better Stack’s query language in the search bar:

correlation.id:"550e8400-e29b-41d4-a716-446655440000"
  1. Go to Logs in Better Stack
  2. Search for your correlation ID: correlation_id:550e8400-e29b-41d4-a716-446655440000
  3. Click on a log entry
  4. Use the View Trace link to see the full trace

When querying by correlation ID, you should see spans from:

  1. webapp - Initial request handling

    • HTTP request spans
    • Database query spans
    • Temporal workflow start spans
  2. temporal-worker (Python) - PDF extraction and order automation

    • Temporal activity spans
    • Document processing spans
    • LLM extraction spans (also visible in Langfuse)
  3. ts-temporal-worker (TypeScript) - Pricing, matching, validation

    • Temporal activity spans
    • ERP submission spans
  4. dagster - Data pipeline execution

    • Asset execution spans (bronze, silver, gold layers)
    • dbt transformation spans
    • Typesense sync spans
correlation.id:"550e8400-e29b-41d4-a716-446655440000"
correlation.id:"550e8400-e29b-41d4-a716-446655440000" AND status:error
correlation.id:"550e8400-e29b-41d4-a716-446655440000" AND duration:>5000ms
correlation.id:"550e8400-e29b-41d4-a716-446655440000" AND service.name:"dagster"

Langfuse sessions are linked via session_id = correlation_id. To find LLM operations:

  1. In Langfuse, search for session: 550e8400-e29b-41d4-a716-446655440000
  2. This shows all LLM calls (Anthropic Claude API) for that correlation ID
  3. Langfuse traces remain isolated but linked via session_id

For a complete picture:

  1. Better Stack: Query by correlation.id to see all service spans
  2. Langfuse: Query by session_id to see LLM-specific operations
  3. Both use the same correlation ID, enabling cross-platform debugging

From logs, response headers, or user report.

correlation.id:"<correlation-id>"
  • Check span durations to find bottlenecks
  • Look for error spans (red indicators)
  • Follow the trace flow: webapp → temporal-worker → ts-temporal-worker → dagster
  • Search by session_id = correlation_id
  • Review LLM token usage and costs
  • Check for LLM-specific errors
  • Filter logs by correlation_id
  • Match log timestamps with span timestamps
  • Get detailed error messages from logs
  1. Bookmark Common Queries: Save frequently used correlation ID queries in Better Stack
  2. Set Up Alerts: Create alerts for correlation IDs with errors
  3. Use Trace Comparison: Compare traces with the same correlation ID pattern to identify regressions
  4. Export Traces: Export trace data for offline analysis or sharing with the team
  • Check if the request actually went through the webapp (correlation IDs are only generated at entry point)
  • Verify the correlation ID format (should be UUID v4)
  • Check if observability is enabled for the service
  • Verify OTEL_EXPORTER_OTLP_ENDPOINT is set for the service
  • Check service logs for OTEL initialization errors
  • Ensure correlation_id is being propagated (check HTTP headers, task payloads, run tags)
  • Verify correlation_id is being passed to pdf-worker tasks
  • Check that session_id is set to correlation_id in Langfuse span creation
  • Review pdf-worker logs for correlation_id extraction

All correlation ID utilities are available from the main observability package:

import {
getOrCreateCorrelationId,
extractCorrelationId,
getCorrelationIdFromContext,
withCorrelationId,
setCorrelationIdAttribute,
CORRELATION_ID_HEADER,
} from '@repo/observability';

Extract from headers:

const correlationId = extractCorrelationId(request.headers);

Get from current context:

const correlationId = getCorrelationIdFromContext();

Execute with correlation ID:

const result = withCorrelationId(correlationId, () => {
// Your code here - correlation ID is automatically in OTEL context
return someOperation();
});

Set on current span:

setCorrelationIdAttribute(correlationId);