Overview
Logs from concurrent requests are interleaved with no way to correlate them. Adding a request ID to every log line allows tracing a single request's journey through the system, essential for debugging production issues.
Current Problem
[INFO] Fetching price for XLM
[INFO] Fetching price for USDC
[ERROR] CoinGecko fetch failed
[INFO] Cache hit for XLM
Which request caused the CoinGecko failure? Impossible to tell.
Solution
- Generate a request ID on every incoming request (
nanoid or crypto.randomUUID())
- Attach to
req.id via middleware early in the chain
- Pass to logger via async-local storage (ALS) so child log calls inherit it:
// src/middleware/requestId.js
const { AsyncLocalStorage } = require('node:async_hooks');
const requestContext = new AsyncLocalStorage();
function requestIdMiddleware(req, res, next) {
req.id = crypto.randomUUID();
res.setHeader('X-Request-ID', req.id);
requestContext.run({ requestId: req.id }, next);
}
- Update
src/logger.js to include requestId from ALS in every log line:
const child = logger.child({
requestId: requestContext.getStore()?.requestId ?? 'system'
});
After this change:
{ "level": "error", "requestId": "f8a2-...", "msg": "CoinGecko fetch failed" }
{ "level": "info", "requestId": "a1b3-...", "msg": "Cache hit for XLM" }
Acceptance Criteria
Overview
Logs from concurrent requests are interleaved with no way to correlate them. Adding a request ID to every log line allows tracing a single request's journey through the system, essential for debugging production issues.
Current Problem
Which request caused the CoinGecko failure? Impossible to tell.
Solution
nanoidorcrypto.randomUUID())req.idvia middleware early in the chainsrc/logger.jsto includerequestIdfrom ALS in every log line:After this change:
{ "level": "error", "requestId": "f8a2-...", "msg": "CoinGecko fetch failed" } { "level": "info", "requestId": "a1b3-...", "msg": "Cache hit for XLM" }Acceptance Criteria
X-Request-IDheader on every responserequestId: 'system'requestIdfor a given requestreqpassed manually through every function)