CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-asgi-correlation-id

Middleware correlating project logs to individual requests

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

sentry-extension.mddocs/

Sentry Extension

Integration with Sentry SDK for tagging events with correlation IDs, enabling correlation between application logs and error monitoring. This extension automatically adds correlation IDs as transaction tags in Sentry events.

Capabilities

Sentry Extension Factory

Returns a function for setting Sentry transaction IDs, with automatic detection of Sentry SDK availability.

def get_sentry_extension() -> Callable[[str], None]:
    """
    Return set_transaction_id function if Sentry SDK is installed.
    
    This factory function detects whether the Sentry SDK is available
    and returns the appropriate function for setting correlation IDs
    as Sentry transaction tags.
    
    Returns:
    - Callable[[str], None]: Function to set Sentry transaction ID
    - If Sentry SDK is not installed, returns no-op lambda function
    """

The returned function can be called with correlation IDs to tag Sentry events, enabling correlation between application logs and error monitoring. If Sentry is not installed, the function gracefully returns a no-op lambda that accepts correlation IDs but performs no action.

Transaction ID Tagging

Sets Sentry's event transaction ID as the current correlation ID, enabling correlation between logs and error events.

def set_transaction_id(correlation_id: str) -> None:
    """
    Set Sentry's event transaction ID as the current correlation ID.
    
    The transaction ID is displayed in a Sentry event's detail view,
    which makes it easier to correlate logs to specific events.
    
    This function handles different Sentry SDK versions:
    - v2.12.0+: Uses get_isolation_scope() API
    - Earlier versions: Uses configure_scope() context manager
    
    Parameters:
    - correlation_id: The correlation ID to set as transaction tag
    
    Raises:
    - ImportError: If Sentry SDK is not installed (handled internally)
    """

The function automatically detects the Sentry SDK version and uses the appropriate API:

  • Sentry SDK 2.12.0+: Uses the newer get_isolation_scope() API
  • Earlier versions: Uses the legacy configure_scope() context manager

Usage Examples

Automatic Integration

from fastapi import FastAPI
from asgi_correlation_id import CorrelationIdMiddleware
import sentry_sdk

# Initialize Sentry
sentry_sdk.init(
    dsn="your-sentry-dsn",
    traces_sample_rate=1.0,
)

# Add correlation middleware - Sentry integration is automatic
app = FastAPI()
app.add_middleware(CorrelationIdMiddleware)

@app.get("/error")
async def trigger_error():
    # This error will be tagged with the correlation ID in Sentry
    raise ValueError("Test error")

Manual Sentry Tagging

from asgi_correlation_id import correlation_id
from asgi_correlation_id.extensions.sentry import set_transaction_id
import logging

logger = logging.getLogger(__name__)

async def process_request():
    # Get current correlation ID
    current_id = correlation_id.get()
    
    if current_id:
        # Manually tag Sentry transaction
        set_transaction_id(current_id)
        logger.info(f"Processing request {current_id}")
    
    try:
        # Some processing that might fail
        result = risky_operation()
        return result
    except Exception as e:
        # Error will be correlated with logs via shared correlation ID
        logger.error(f"Processing failed: {e}")
        raise

Custom Sentry Configuration

import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration
from asgi_correlation_id import CorrelationIdFilter

# Configure Sentry with logging integration
sentry_logging = LoggingIntegration(
    level=logging.INFO,        # Capture info and above as breadcrumbs
    event_level=logging.ERROR  # Send errors as events
)

sentry_sdk.init(
    dsn="your-sentry-dsn",
    integrations=[sentry_logging],
    traces_sample_rate=1.0,
)

# Add correlation ID to logs
correlation_filter = CorrelationIdFilter()
logging.getLogger().addFilter(correlation_filter)

# Now both logs and Sentry events will have correlation IDs

Celery Integration with Sentry

from celery import Celery
from asgi_correlation_id.extensions.celery import load_correlation_ids
from asgi_correlation_id.extensions.sentry import get_sentry_extension
import sentry_sdk

# Initialize Sentry for Celery workers
sentry_sdk.init(dsn="your-sentry-dsn")

app = Celery('tasks')

# Enable correlation ID transfer to Celery tasks
load_correlation_ids()

@app.task
def process_data(data):
    # Correlation ID is automatically transferred from request
    # and tagged in Sentry via the middleware integration
    try:
        return process(data)
    except Exception as e:
        # Error in Sentry will show correlation ID from originating request
        raise

Integration Points

Middleware Integration

The Sentry extension is automatically loaded by CorrelationIdMiddleware:

# In CorrelationIdMiddleware.__post_init__()
self.sentry_extension = get_sentry_extension()

# In CorrelationIdMiddleware.__call__()
correlation_id.set(id_value)
self.sentry_extension(id_value)  # Automatically tag Sentry events

Celery Integration

The Celery extension also integrates with Sentry:

# In Celery signal handlers
from asgi_correlation_id.extensions.sentry import get_sentry_extension

sentry_extension = get_sentry_extension()

@task_prerun.connect(weak=False)
def load_correlation_id(task, **kwargs):
    id_value = task.request.get(header_key)
    if id_value:
        correlation_id.set(id_value)
        sentry_extension(id_value)  # Tag Celery task events

Sentry Event Correlation

With the extension enabled, Sentry events will include correlation IDs as transaction tags:

In Sentry Dashboard

Event ID: abc123def456
Transaction ID: req-a1b2c3d4-e5f6-7890  # Your correlation ID

Breadcrumbs:
- INFO: Processing request req-a1b2c3d4-e5f6-7890
- ERROR: Database connection failed

Tags:
- transaction_id: req-a1b2c3d4-e5f6-7890
- environment: production

Log Correlation

With both correlation logging and Sentry integration:

# Application logs
2023-01-01 12:00:00 INFO [req-a1b2c3d4] Processing user request
2023-01-01 12:00:01 ERROR [req-a1b2c3d4] Database connection failed

# Sentry event tagged with: transaction_id=req-a1b2c3d4
# Easy to correlate the Sentry error with application logs

Version Compatibility

The extension handles different Sentry SDK versions automatically:

Sentry SDK 2.12.0+

# Uses newer isolation scope API
scope = sentry_sdk.get_isolation_scope()
scope.set_tag('transaction_id', correlation_id)

Sentry SDK < 2.12.0

# Uses legacy configure_scope API
with sentry_sdk.configure_scope() as scope:
    scope.set_tag('transaction_id', correlation_id)

The version detection is handled automatically using the packaging library to parse the Sentry SDK version.

Types

from typing import Callable
from packaging import version

# Type definitions
SentryExtension = Callable[[str], None]
NoOpExtension = Callable[[str], None]

Install with Tessl CLI

npx tessl i tessl/pypi-asgi-correlation-id

docs

celery-extension.md

context.md

index.md

logging.md

middleware.md

sentry-extension.md

tile.json