← Back to Insights

Production investigation

Tracing a Failed Request Across Services

Written by:Better SoftwareBetter Software TeamUpdated 6 min read
Tracing a Failed Request Across Services

Quick Answer

Tracing a failed request across services starts with a request ID, then correlates centralized logs, distributed traces and service metrics to find where the failure began. Engineers examine the faulty span, confirm the component and check its dependencies before changing anything. Correlation IDs, consistent log formats, service-level objectives, retries and circuit breakers make the next trace faster, while grepping logs on individual machines does not scale.

Tracing a request failure across multiple services involves correlating telemetry data. This includes distributed traces, aggregated logs, and service-level metrics. The goal is pinpointing the exact service and code path responsible for the erroneous behavior.

Why This Happens

Distributed systems process requests across many independent services. Each service contributes to the overall request flow. A failure in one component can propagate upstream, affecting the user experience. Monolithic systems present failures differently. Failures within a single codebase are directly observable. In distributed systems, a faulty service might return an error, timeout, or respond incorrectly. This requires correlating events across service boundaries. Investigating failures in distributed systems adds complexity due to asynchronous operations and network latency. The absence of a unified call stack necessitates coordinated telemetry.

Investigation Process

  1. Identify the impacted request. Obtain a unique request ID, user ID, or timestamp range. This narrows the scope.
  2. Query centralized logs. Use the request ID to find relevant log entries. Look for error messages, exceptions, or unusual statuses.
  3. Examine distributed traces. Utilize a distributed tracing system (e.g., OpenTelemetry, Jaeger, Zipkin). Trace the request ID through all services it touched. Pinpoint spans indicating errors or high latency.
  4. Review service metrics. Check dashboards for the services identified in the trace. Look for spikes in error rates, latency, or resource utilization.
  5. Analyze specific service logs. Once a problematic service is identified, dig deeper into its individual logs. Search for detailed fault information.
  6. Replicate the issue (if possible). Attempt to reproduce the failure. This provides immediate feedback on potential fixes.
  7. Isolate and confirm the faulty component. Determine the exact code path returning the error. Verify its dependencies and configurations.

Practical Example

A customer reported an inability to complete an order. The frontend showed a generic error, "Payment Failed."

  • Step 1. The customer support ticket provided a user ID and approximate timestamp.
  • Step 2. Engineers searched centralized logs for the user ID. They found entries from the Order Processing Service. These logs showed a call to Payment Gateway Service returned HTTP 500. There was no internal error in the Order Processing Service itself.
  • Step 3. A distributed trace for the customer's order ID was pulled. The trace showed the request flowing from the Frontend Service to Order Processing Service, then to Payment Gateway Service. The span for the call to an external payment provider from Payment Gateway Service was marked as an error.
  • Step 4. Metrics for Payment Gateway Service were reviewed. Error rates for external payment provider calls spiked around that time. Latency also increased.
  • Step 5. Logs for Payment Gateway Service were filtered by the order ID. They revealed an upstream timeout when connecting to the external payment provider's API. This was not an internal service error.
  • Step 6. Engineers checked the external payment provider's status page. There was a reported outage impacting a specific region.
  • Step 7. The faulty component was identified as the external payment provider's API. The Payment Gateway Service correctly handled its timeout.

The incident was escalated to a vendor. The Order Processing Service fallback mechanism was reviewed for future similar outages.

Preventing Recurrence

  • Implement robust distributed tracing. Ensure all services emit correlation IDs and span data. This is crucial for effective incident handoffs.
  • Standardize logging patterns. Enforce consistent log formats and enrichment with trace contexts. Centralize log aggregation.
  • Develop comprehensive service metrics. Monitor error rates, latency, and throughput for all external and internal calls.
  • Service Level Objectives (SLOs) and Alerts. Define SLOs for critical service interactions. Configure alerts for deviations.
  • Idempotent Operations and Retries. Design request handlers to be idempotent. Implement exponential backoff and retry mechanisms for transient failures.
  • Circuit Breakers and Fallbacks. Implement circuit breakers to prevent cascading failures. Design graceful degradation paths or fallback mechanisms.
  • Regular Chaos Engineering experiments. Introduce failures intentionally to test system resilience and observability.

We design services for traceability as part of product engineering, so the next failure takes less time to locate.

What Teams Usually Do Instead

Some teams primarily rely on individual service logs. They often jump directly to examining the service that first reported the error. This approach is inefficient in distributed systems. A service reporting an error might just be the first point of observation. The root cause could reside deep within a dependency. Without a correlation ID, logs become disconnected. Manual log grepping across many machines is time-consuming and error-prone. This siloed investigation prolongs incident resolution. It also hinders understanding the full impact of an issue. Another common mistake is over-reliance on aggregated metrics without context. Metrics show 'what' is happening. Tracing and structured logs show 'why' and 'where' it is happening.

Key Takeaways

  • Distributed tracing is essential for request flow visibility.
  • Correlate logs, traces, and metrics for effective debugging.
  • Standardize telemetry across all services.
  • Design services for resilience and fault tolerance.
  • Manual log analysis rapidly becomes unscalable.

For related reading, see how to trace intermittent production bugs. For more on how we work, visit Better Software.

Frequently Asked Questions

What Is the First Step in Tracing a Failed Request?

We start by identifying the impacted request through a unique request ID, a user ID or a timestamp range. That narrows the scope before we query centralized logs for error messages, exceptions or unusual statuses, and then follow the request through the distributed trace.

Why Are Distributed Traces Better Than Individual Service Logs?

A service reporting an error may only be the first point of observation, while the root cause sits deep in a dependency. Without a correlation ID, logs become disconnected. We use traces to follow the request across every service it touched and to spot spans with errors or high latency.

How Do Logs, Traces and Metrics Work Together?

Metrics show what is happening, and traces and structured logs show where and why. We use the trace to find the suspect service, check its dashboards for spikes in error rates or latency, and then read its logs for detailed fault information.

How Can Teams Make Failures Easier to Trace?

We make every service emit correlation IDs and span data, standardize log formats with trace context, and centralize log aggregation. We also define service-level objectives and alerts, design idempotent handlers with retries and backoff, add circuit breakers and fallbacks, and run chaos experiments.

What Did the Payment Example Teach Us?

The generic payment error came from an external provider outage, not an internal bug. The gateway service handled the timeout correctly, so the incident went to the vendor. We then reviewed the order service fallback mechanism for similar outages in the future.

About the author

Better Software

Better Software Team

Product and engineering team

Better Software Team is the product and engineering team at Better Software. We build new software products and improve existing applications and systems, with deeper experience in healthcare, finance and energy.