Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions stellar-payment-platform/middleware/correlation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const { v4: uuidv4 } = require('uuid');

const CORRELATION_HEADER = 'X-Correlation-ID';

// #31 — Correlation ID middleware for end-to-end request tracing.
// Reuses an incoming X-Correlation-ID header when present, otherwise generates
// a fresh uuidv4. The ID is exposed on req.correlationId and echoed back on the
// response so callers and downstream services can stitch logs together.
const correlationId = (req, res, next) => {
const incoming = req.get(CORRELATION_HEADER);
const id = typeof incoming === 'string' && incoming.trim() ? incoming.trim() : uuidv4();

req.correlationId = id;
res.set(CORRELATION_HEADER, id);

// Prefix request logs with the correlation ID so a single API call can be
// traced end-to-end across the backend's log output.
res.on('finish', () => {
console.log(`[Correlation ID: ${id}] ${req.method} ${req.originalUrl} ${res.statusCode}`);
});

next();
};

module.exports = { correlationId, CORRELATION_HEADER };
21 changes: 15 additions & 6 deletions stellar-payment-platform/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions stellar-payment-platform/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"rate-limit-redis": "^4.2.0",
"redis": "^4.7.0",
"sqlite3": "^5.1.7",
"uuid": "^9.0.1",
"xss": "^1.0.15"
},
"devDependencies": {
Expand Down
9 changes: 8 additions & 1 deletion stellar-payment-platform/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const RedisStore = require('rate-limit-redis');
const { createClient } = require('redis');
const { prisma } = require('./prismaClient');
const { scheduleCleanupJob } = require('./src/cleanup-cron');
const { correlationId } = require('./middleware/correlation');
const Filter = require('bad-words');
const dotenv = require('dotenv');
const timeout = require('connect-timeout');
Expand Down Expand Up @@ -50,6 +51,9 @@ const corsOptions = {
optionsSuccessStatus: 204,
};

// #31 — Attach a correlation ID to every request before anything else runs so
// all downstream middleware, handlers and logs can reference the same trace.
app.use(correlationId);
const redisClient = process.env.REDIS_URL ? createClient({
url: process.env.REDIS_URL
}) : null;
Expand Down Expand Up @@ -522,11 +526,14 @@ app.use((err, _req, res, _next) => {

if (statusCode === 500) {
const errorId = crypto.randomUUID();
console.error(`[Error ID: ${errorId}]`, err);
// #31 — Prefix error logs with the correlation ID so a single API call can
// be traced across every log line it produced.
console.error(`[Correlation ID: ${req.correlationId}] [Error ID: ${errorId}]`, err);
return res.status(500).json({
success: false,
error: 'Internal Server Error',
reference_id: errorId,
correlation_id: req.correlationId
});
}

Expand Down
Loading