Files
OmniRoute/src/shared/middleware/correlationId.ts
diegosouzapw 71d14209a4 feat: OmniRoute v1.0.0 — Intelligent AI Gateway & Universal LLM Proxy
OmniRoute is an intelligent API gateway that unifies 20+ AI providers behind a single
OpenAI-compatible endpoint. Features include intelligent routing with 6 strategies,
multi-format translation (OpenAI/Claude/Gemini/Responses API), circuit breakers,
semantic caching, combo fallback chains, real-time health monitoring, and a full
dashboard with provider management, analytics, and CLI tool integration.

Key highlights:
- 20+ providers (Claude Code, Codex, Gemini CLI, GitHub Copilot, iFlow, Qwen, Kiro, etc.)
- 6 routing strategies (Fill First, Round Robin, P2C, Random, Least Used, Cost Optimized)
- Export/Import database backup with full archive support
- Translator Playground with 4 modes (Playground, Chat Tester, Test Bench, Live Monitor)
- 100% TypeScript across src/ and open-sse/
- Docker support with multi-stage builds
- Comprehensive documentation and 9 dashboard screenshots
2026-02-18 00:02:15 -03:00

99 lines
2.7 KiB
TypeScript

/**
* Correlation ID Middleware — FASE-04 Observability
*
* Generates and propagates correlation IDs (X-Request-Id) across
* requests and responses for distributed tracing. Uses AsyncLocalStorage
* to make the correlation ID available in any downstream code.
*
* @module middleware/correlationId
*/
import { AsyncLocalStorage } from "node:async_hooks";
import crypto from "node:crypto";
const correlationStore = new AsyncLocalStorage();
/**
* Generate a unique correlation ID.
* @returns {string} UUID-like correlation ID
*/
function generateCorrelationId() {
return crypto.randomUUID();
}
/**
* Get the current correlation ID from async context.
* @returns {string|undefined}
*/
export function getCorrelationId() {
return correlationStore.getStore();
}
/**
* Run a function within a correlation context.
* If a correlationId is provided, it is used; otherwise a new one is generated.
*
* @param {string|null} correlationId - Optional existing correlation ID
* @param {Function} fn - Function to run in context
* @returns {*} Result of fn()
*/
export function runWithCorrelation(correlationId, fn) {
const id = correlationId || generateCorrelationId();
return correlationStore.run(id, fn);
}
/**
* Express/Next.js middleware that injects correlation IDs.
*
* Usage:
* // In Next.js middleware or Express app
* import { correlationMiddleware } from './correlationId.js';
* app.use(correlationMiddleware);
*
* @param {Request} request
* @param {Function} next
* @returns {Promise<Response>}
*/
export function correlationMiddleware(request, next) {
const requestId =
request.headers.get("x-request-id") ||
request.headers.get("x-correlation-id") ||
generateCorrelationId();
return runWithCorrelation(requestId, async () => {
const response = await next();
// Attach correlation ID to response
if (response && response.headers) {
response.headers.set("x-request-id", requestId);
}
return response;
});
}
/**
* Create a logger wrapper that automatically includes correlation IDs.
*
* @param {Object} baseLogger - Base logger with info/warn/error methods
* @returns {Object} Wrapped logger
*/
export function createCorrelatedLogger(baseLogger) {
const withCorrelation = (level, ...args) => {
const correlationId = getCorrelationId();
if (correlationId) {
const meta = typeof args[args.length - 1] === "object" ? args.pop() : {};
meta.correlationId = correlationId;
args.push(meta);
}
baseLogger[level](...args);
};
return {
info: (...args) => withCorrelation("info", ...args),
warn: (...args) => withCorrelation("warn", ...args),
error: (...args) => withCorrelation("error", ...args),
debug: (...args) => withCorrelation("debug", ...args),
};
}