mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-04 06:12:10 +03:00
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
99 lines
2.7 KiB
TypeScript
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),
|
|
};
|
|
}
|