chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Request Logger Plugin — logs API requests and responses with timing.
|
||||
*
|
||||
* @module request-logger
|
||||
*/
|
||||
|
||||
const LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
|
||||
|
||||
function shouldLog(configLevel, messageLevel) {
|
||||
return (LEVELS[messageLevel] ?? 1) >= (LEVELS[configLevel] ?? 1);
|
||||
}
|
||||
|
||||
function truncate(str, max) {
|
||||
if (typeof str !== "string") return str;
|
||||
return str.length > max ? str.slice(0, max) + "..." : str;
|
||||
}
|
||||
|
||||
function formatBody(body, maxLen) {
|
||||
if (body === undefined || body === null) return undefined;
|
||||
try {
|
||||
const json = JSON.stringify(body);
|
||||
return truncate(json, maxLen);
|
||||
} catch {
|
||||
return truncate(String(body), maxLen);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* onRequest hook — records request start time and logs request details.
|
||||
*/
|
||||
export function onRequest(ctx) {
|
||||
const config = ctx?.config || {};
|
||||
const level = config.logLevel || "info";
|
||||
|
||||
if (ctx?.metadata) {
|
||||
ctx.metadata.__requestStart = Date.now();
|
||||
}
|
||||
|
||||
if (shouldLog(level, "info")) {
|
||||
const logEntry = {
|
||||
timestamp: new Date().toISOString(),
|
||||
requestId: ctx.requestId,
|
||||
model: ctx.model,
|
||||
provider: ctx.provider,
|
||||
method: ctx.method || "POST",
|
||||
};
|
||||
|
||||
if (config.includeBody) {
|
||||
logEntry.body = formatBody(ctx.body, config.maxBodyLength || 500);
|
||||
}
|
||||
|
||||
console.log("[request-logger] REQUEST:", JSON.stringify(logEntry));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* onResponse hook — logs response with timing.
|
||||
*/
|
||||
export function onResponse(ctx, response) {
|
||||
const config = ctx?.config || {};
|
||||
const level = config.logLevel || "info";
|
||||
const startTime = ctx?.metadata?.__requestStart || Date.now();
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
if (shouldLog(level, "info")) {
|
||||
const logEntry = {
|
||||
timestamp: new Date().toISOString(),
|
||||
requestId: ctx.requestId,
|
||||
model: ctx.model,
|
||||
durationMs: duration,
|
||||
status: response?.status || 200,
|
||||
};
|
||||
|
||||
if (config.includeBody && response?.data) {
|
||||
logEntry.response = formatBody(response.data, config.maxBodyLength || 500);
|
||||
}
|
||||
|
||||
console.log("[request-logger] RESPONSE:", JSON.stringify(logEntry));
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* onError hook — logs errors with context.
|
||||
*/
|
||||
export function onError(ctx, error) {
|
||||
const config = ctx?.config || {};
|
||||
const level = config.logLevel || "info";
|
||||
const startTime = ctx?.metadata?.__requestStart || Date.now();
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
if (shouldLog(level, "error")) {
|
||||
console.error("[request-logger] ERROR:", JSON.stringify({
|
||||
timestamp: new Date().toISOString(),
|
||||
requestId: ctx.requestId,
|
||||
model: ctx.model,
|
||||
durationMs: duration,
|
||||
error: error?.message || String(error),
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "request-logger",
|
||||
"version": "1.0.0",
|
||||
"description": "Logs all API requests and responses with timing information",
|
||||
"author": "OmniRoute",
|
||||
"license": "MIT",
|
||||
"main": "index.mjs",
|
||||
"source": "local",
|
||||
"tags": ["logging", "debug", "monitoring"],
|
||||
"hooks": {
|
||||
"onRequest": true,
|
||||
"onResponse": true,
|
||||
"onError": true
|
||||
},
|
||||
"requires": {
|
||||
"permissions": []
|
||||
},
|
||||
"enabledByDefault": false,
|
||||
"configSchema": {
|
||||
"logLevel": {
|
||||
"type": "select",
|
||||
"default": "info",
|
||||
"enum": ["debug", "info", "warn", "error"],
|
||||
"description": "Minimum log level to output"
|
||||
},
|
||||
"includeBody": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Include request/response body in logs"
|
||||
},
|
||||
"maxBodyLength": {
|
||||
"type": "number",
|
||||
"default": 500,
|
||||
"min": 100,
|
||||
"max": 10000,
|
||||
"description": "Maximum body length to log"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user