Skip to content

feat(framework): implement centralized request ID management framework#9554

Merged
bernard-eugine merged 22 commits intomainfrom
capture-upstream-request-id
Nov 12, 2025
Merged

feat(framework): implement centralized request ID management framework#9554
bernard-eugine merged 22 commits intomainfrom
capture-upstream-request-id

Conversation

@maverox
Copy link
Contributor

@maverox maverox commented Sep 25, 2025

Summary

This PR implements a comprehensive solution for centralized request ID management, enabling robust distributed tracing by consuming upstream request_id and passing it to UCS as x-session-id for end-to-end correlation.

Closes #9553

Key Changes

🎯 Core Implementation

  • Centralized middleware in router_env crate for single source of truth
  • Upstream request_id consumption for robust distributed tracing across services
  • Custom tracing integration to eliminate duplicate request_id fields in logs
  • UCS x-session-id integration for end-to-end request correlation with unified connector service

🔧 Technical Improvements

  • Feature flag cleanup: Simplified UUID configuration with consistent defaults
  • Comprehensive documentation: Full API docs with examples and usage patterns
  • Clean architecture: Removed redundant middleware implementations
  • Error handling: Proper error types and context propagation

📋 Detailed Changes

crates/router_env/src/request_id.rs

  • Complete request ID middleware implementation compatible with actix-request-identifier
  • Support for incoming X-Request-Id header consumption with configurable IdReuse policy
  • RequestId extractor for handlers with proper error handling
  • Upstream request ID logging for debugging and distributed tracing correlation
  • Comprehensive API documentation with real-world examples

crates/router_env/src/request_id_span.rs

  • Custom RequestIdRootSpanBuilder implementation
  • Avoids root_span! macro to prevent duplicate request_id generation
  • Manual span creation with comprehensive HTTP tracing attributes
  • Proper request ID extraction from middleware extensions for consistent tracing

crates/router_env/Cargo.toml

  • Cleaned up feature flags for consistent UUID generation
  • Removed uuid_v7 feature from tracing-actix-web to prevent conflicts
  • Streamlined dependency management with optional features

crates/router/src/middleware.rs

  • Removed redundant RequestId middleware implementation (70+ lines)
  • Replaced with clean re-export from router_env for backward compatibility
  • Eliminates code duplication and maintenance overhead

crates/router/src/lib.rs

  • Updated to use router_env::RequestIdentifier with RequestIdRootSpanBuilder
  • Proper middleware ordering for request ID availability throughout the stack
  • Integration with UCS x-session-id for unified connector service correlation

Distributed Tracing Benefits

Robust Request Correlation

  • Upstream request_id consumption: Preserves request correlation across service boundaries
  • End-to-end tracing: Request IDs flow from external services through to UCS
  • Single request_id field: Clean logs without duplicate entries
  • UCS integration: x-session-id header enables connector service correlation

📊 Observability Improvements

  • Consistent request tracking: Same ID used across all services in the request path
  • Reduced debugging time: Clear request correlation through distributed systems
  • Clean log parsing: Single request_id field reduces log processing complexity
  • Service mesh compatibility: Standard X-Request-Id header usage

UCS Integration

x-session-id Implementation

  • Request correlation: Upstream request_id passed as x-session-id to unified connector service
  • End-to-end tracking: Full request path visibility from client to connector
  • Service isolation: Each service maintains its own request context while preserving correlation
  • Debug capability: Easy request tracking across service boundaries

Security Considerations

  • Input validation: Proper header value validation prevents injection
  • ASCII enforcement: Ensures safe header transmission
  • Configurable reuse: IdReuse::IgnoreIncoming for security-sensitive environments
  • Upstream trust: Configurable policies for external request ID acceptance

Testing

Manual Testing

  • ✅ Single request_id field in all log entries (no duplicates)
  • ✅ Upstream request_id consumption working correctly
  • ✅ UCS x-session-id correlation functioning
  • ✅ Middleware extraction in handlers
  • ✅ Response header injection maintained

Integration Points

  • ✅ UCS (Unified Connector Service) x-session-id correlation
  • ✅ Webhook processing with request ID continuity
  • ✅ API logging middleware compatibility
  • ✅ Error handling and tracing integration across services

Migration Guide

For Developers

// OLD: Local RequestId middleware
use crate::middleware::RequestId;

// NEW: Centralized router_env RequestId
use router_env::RequestId;  // Same API, improved implementation

For Deployment

  • No configuration changes required
  • Existing request correlation continues to work
  • Enhanced distributed tracing automatically enabled
  • UCS x-session-id correlation available immediately

Backward Compatibility

  • API compatibility: All existing RequestId usage continues to work
  • Header compatibility: Still uses x-request-id by default
  • Middleware compatibility: Works with existing middleware stack
  • Tracing compatibility: Enhanced without breaking existing observability

Documentation

  • 📚 Comprehensive module docs with distributed tracing explanations
  • 📝 Usage examples for request correlation patterns
  • 🔧 Configuration options for upstream request handling
  • ⚠️ Error conditions and correlation failure scenarios documented

Checklist

  • Single request_id field in all log entries (eliminated duplicates)
  • Upstream request_id consumption when X-Request-Id header present
  • UCS x-session-id correlation for end-to-end tracing
  • No code duplication between router and router_env
  • Comprehensive documentation with distributed tracing examples
  • Backward compatibility maintained
  • Security considerations for upstream ID handling
  • Distributed tracing improvements verified

Review Focus Areas

  1. Distributed Tracing: Upstream request_id consumption and correlation flow
  2. UCS Integration: x-session-id implementation for connector service correlation
  3. Architecture: Clean separation of concerns and centralized implementation
  4. Documentation: Comprehensive API docs and distributed tracing examples
  5. Security: Input validation and configurable upstream ID policies

Testing

Request

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'X-Request-Id: adsfadfads-11-11-1' \
--header 'traceparent: 00-12345678901234567890123456789012-1234567890123456-01' \
--header 'api-key: dev_iTbySOVTqap2S4d7lr80lizI9gP4Ud3cji91v7AV1xk1elLdWNNq6dDVnSoAbpI6' \
--data-raw '{
    "amount": 6540,
    "currency": "INR",
    "amount_to_capture": 6540,
    "confirm": true,
    "profile_id": "pro_RkdjC1k2ZDLH1wvhSc76",
    "email": "customer@gmail.com",
    "capture_method": "automatic",
    
    "authentication_type": "no_three_ds",
    
    "customer": {
        "id": "customer123",
        "name": "John Doe",
        "email": "customer@gmail.com",
        "phone": "9999999999",
        "phone_country_code": "+91"
    },
    "customer_id": "customer123",
    
    "description": "Its my first payment request",
    "return_url": "https://google.com",
    "payment_method": "upi",
    "payment_method_type": "upi_collect",
    "payment_method_data": {
        "upi": {
            "upi_collect": {
                "vpa_id": "success@razorpay"
            }
        },
        "billing": {
            "email": "pmbi@example.com",
            "phone": {
                "country_code": "+91",
                "number": "6502530000"
            }
        }
    },
    
   
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "IN",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "si@example.com"
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "order_details": [
        {
            "product_name": "Apple iphone 15",
            "quantity": 1,
            "amount": 6540,
            "account_name": "transaction_processing"
        }
    ],
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "browser_info": {
        "user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36",
        "accept_header": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,image\/apng,*\/*;q=0.8",
        "language": "nl-NL",
        "color_depth": 24,
        "screen_height": 723,
        "screen_width": 1536,
        "time_zone": 0,
        "java_enabled": true,
        "java_script_enabled": true,
        "ip_address": "128.0.0.1"
    },
   
    "request_incremental_authorization": false,
    "merchant_order_reference_id": "testing_the_integ03454",
    "all_keys_required": true,
    "session_expiry": 900
}'```

#### response
```json
{
    "payment_id": "pay_g2vLsgNHETOm99RrDR6A",
    "merchant_id": "merchant_1756906013",
    "status": "processing",
    "amount": 6540,
    "net_amount": 6540,
    "shipping_cost": null,
    "amount_capturable": 6540,
    "amount_received": null,
    "connector": "razorpay",
    "client_secret": "pay_g2vLsgNHETOm99RrDR6A_secret_C19qY49DA7HObS6lZb6w",
    "created": "2025-09-24T14:37:36.318Z",
    "currency": "INR",
    "customer_id": "customer123",
    "customer": {
        "id": "customer123",
        "name": "John Doe",
        "email": "customer@gmail.com",
        "phone": "9999999999",
        "phone_country_code": "+91"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "upi",
    "payment_method_data": {
        "upi": {
            "upi_collect": {
                "vpa_id": "su*****@razorpay"
            }
        },
        "billing": {
            "address": null,
            "phone": {
                "number": "6502530000",
                "country_code": "+91"
            },
            "email": "pmbi@example.com"
        }
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "IN",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe",
            "origin_zip": null
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "si@example.com"
    },
    "billing": null,
    "order_details": [
        {
            "sku": null,
            "upc": null,
            "brand": null,
            "amount": 6540,
            "category": null,
            "quantity": 1,
            "tax_rate": null,
            "product_id": null,
            "description": null,
            "product_name": "Apple iphone 15",
            "product_type": null,
            "sub_category": null,
            "total_amount": null,
            "commodity_code": null,
            "unit_of_measure": null,
            "product_img_link": null,
            "product_tax_code": null,
            "total_tax_amount": null,
            "requires_shipping": null,
            "unit_discount_amount": null
        }
    ],
    "email": "customer@gmail.com",
    "name": "John Doe",
    "phone": "9999999999",
    "return_url": "https://google.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": null,
    "error_code": "ORDER_CREATION_ERROR",
    "error_message": "Order creation failed: Failed to execute a processing step: None",
    "unified_code": "UE_9000",
    "unified_message": "Something went wrong",
    "payment_experience": null,
    "payment_method_type": "upi_collect",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "customer123",
        "created_at": 1758724656,
        "expires": 1758728256,
        "secret": "epk_2b334ac1c83742d8b599d22146f6aaab"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": null,
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "unified_connector_service"
    },
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_RkdjC1k2ZDLH1wvhSc76",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_1cYyVsBadn8UVLK5vI24",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-09-24T14:52:36.318Z",
    "fingerprint": null,
    "browser_info": {
        "language": "nl-NL",
        "time_zone": 0,
        "ip_address": "128.0.0.1",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1536,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 723,
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-09-24T14:37:36.360Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": "testing_the_integ03454",
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": null,
    "force_3ds_challenge": false,
    "force_3ds_challenge_trigger": false,
    "issuer_error_code": null,
    "issuer_error_message": null,
    "is_iframe_redirection_enabled": null,
    "whole_connector_response": null,
    "enable_partial_authorization": null,
    "enable_overcapture": null,
    "is_overcapture_enabled": null,
    "network_details": {
        "network_advice_code": null
    }
}

logs

Screenshot 2025-09-25 at 12 49 04 PM

- Change feature flag logic to make UUID v7 default (no feature flag required)
- UUID v4 is now behind `uuid-v4-generator` feature flag for backward compatibility
- Update Cargo.toml feature configuration to reflect new defaults
- Remove `uuid_v7` feature from tracing-actix-web to prevent conflicts

This change improves database performance by using time-ordered UUIDs
and provides better chronological sorting without additional metadata.
@maverox maverox requested review from a team as code owners September 25, 2025 07:00
@semanticdiff-com
Copy link

semanticdiff-com bot commented Sep 25, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/core/payment_methods/transformers.rs  93% smaller
  crates/external_services/src/grpc_client/unified_connector_service.rs  62% smaller
  crates/router/src/routes/app.rs  61% smaller
  crates/router/src/lib.rs  49% smaller
  crates/router/src/services/api/client.rs  26% smaller
  crates/common_utils/src/keymanager.rs  5% smaller
  crates/external_services/src/grpc_client.rs  4% smaller
  crates/router/src/events/api_logs.rs  2% smaller
  Cargo.lock Unsupported file format
  config/config.example.toml Unsupported file format
  config/deployments/env_specific.toml Unsupported file format
  config/development.toml Unsupported file format
  config/docker_compose.toml Unsupported file format
  crates/common_utils/src/types/keymanager.rs  0% smaller
  crates/events/src/actix.rs  0% smaller
  crates/hyperswitch_interfaces/src/api_client.rs  0% smaller
  crates/hyperswitch_interfaces/src/events/connector_api_logs.rs  0% smaller
  crates/hyperswitch_interfaces/src/events/routing_api_logs.rs  0% smaller
  crates/router/src/configs/secrets_transformers.rs  0% smaller
  crates/router/src/configs/settings.rs  0% smaller
  crates/router/src/core/payment_methods/cards.rs  0% smaller
  crates/router/src/core/payments/routing.rs  0% smaller
  crates/router/src/core/payments/routing/utils.rs  0% smaller
  crates/router/src/core/routing/helpers.rs  0% smaller
  crates/router/src/core/webhooks/incoming.rs  0% smaller
  crates/router/src/core/webhooks/incoming_v2.rs  0% smaller
  crates/router/src/middleware.rs  0% smaller
  crates/router/src/services/api.rs  0% smaller
  crates/router/src/types/domain/types.rs  0% smaller
  crates/router_env/Cargo.toml Unsupported file format
  crates/router_env/src/lib.rs  0% smaller
  crates/router_env/src/request_id.rs  0% smaller
  crates/router_env/src/root_span.rs  0% smaller
  crates/subscriptions/src/state.rs  0% smaller
  loadtest/config/development.toml Unsupported file format

@maverox maverox self-assigned this Sep 25, 2025
@maverox maverox force-pushed the capture-upstream-request-id branch from 94310e3 to 338d03a Compare September 25, 2025 11:00
@maverox maverox changed the title feat: implement centralized request ID management with UUID v7 default feat(framework): implement centralized request ID management framework Sep 25, 2025
maverox and others added 8 commits September 25, 2025 17:15
…ting

- Add TraceHeaderConfig to router settings with configurable header_name
- Update RequestIdentifier middleware to accept String instead of &'static str
- Modify get_application_builder to use configurable trace header
- Add trace_header configuration to all relevant TOML files
- Set default header_name to 'x-request-id' for backward compatibility

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
jarnura
jarnura previously approved these changes Oct 6, 2025
tsdk02
tsdk02 previously approved these changes Oct 7, 2025
@maverox maverox dismissed stale reviews from tsdk02 and jarnura via a345842 October 16, 2025 14:03
@codecov
Copy link

codecov bot commented Nov 4, 2025

Codecov Report

❌ Patch coverage is 63.50000% with 73 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@0e287d7). Learn more about missing BASE report.

Files with missing lines Patch % Lines
crates/router_env/src/request_id.rs 58.97% 48 Missing ⚠️
crates/router/src/routes/app.rs 25.00% 6 Missing ⚠️
crates/router_env/src/root_span.rs 84.21% 6 Missing ⚠️
...es/router/src/core/payment_methods/transformers.rs 0.00% 5 Missing ⚠️
...vices/src/grpc_client/unified_connector_service.rs 0.00% 2 Missing ⚠️
crates/router/src/core/payments/routing/utils.rs 0.00% 2 Missing ⚠️
...switch_interfaces/src/events/connector_api_logs.rs 0.00% 1 Missing ⚠️
...erswitch_interfaces/src/events/routing_api_logs.rs 0.00% 1 Missing ⚠️
crates/router/src/services/api/client.rs 50.00% 1 Missing ⚠️
crates/subscriptions/src/state.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #9554   +/-   ##
=======================================
  Coverage        ?    4.08%           
=======================================
  Files           ?     1229           
  Lines           ?   305123           
  Branches        ?        0           
=======================================
  Hits            ?    12463           
  Misses          ?   292660           
  Partials        ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Replace infallible From implementations with TryFrom to properly
handle empty string validation:

- From<String> → TryFrom<String> with empty check
- From<&str> → TryFrom<&str> with empty check
- Remove From<RequestId> for HeaderValue (hardcoded fallback removed)
- Rename new_from_string() → try_from_string() returning Result

These changes ensure proper error handling at type conversion boundaries
and eliminate implicit error cases.
SanchithHegde
SanchithHegde previously approved these changes Nov 10, 2025
@maverox maverox added A-framework Area: Framework C-feature Category: Feature request or enhancement labels Nov 10, 2025
@bernard-eugine bernard-eugine added this pull request to the merge queue Nov 12, 2025
Merged via the queue into main with commit 1a7a43a Nov 12, 2025
41 of 50 checks passed
@bernard-eugine bernard-eugine deleted the capture-upstream-request-id branch November 12, 2025 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-framework Area: Framework C-feature Category: Feature request or enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement centralized request ID management with UUID v7 default

7 participants