mcp-product-manager
Version:
MCP Orchestrator for task and project management with web interface
94 lines • 3.39 kB
JavaScript
// logging.js - Request/response logging middleware with RBAC integration
// Enhanced request logger with RBAC support
export const requestLogger = (req, res, next) => {
const start = Date.now();
// Log request with basic info
console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`, {
query: req.query,
body: req.body,
params: req.params,
headers: {
'content-type': req.headers['content-type'],
'user-agent': req.headers['user-agent'],
'x-agent': req.headers['x-agent'],
'x-role': req.headers['x-role']
}
});
// Enhanced response logger that includes RBAC info
const originalSend = res.send;
res.send = function (data) {
const duration = Date.now() - start;
// Create comprehensive log entry
const logEntry = {
timestamp: new Date().toISOString(),
method: req.method,
path: req.path,
statusCode: res.statusCode,
duration: `${duration}ms`,
ip: req.ip,
userAgent: req.headers['user-agent']
};
// Add RBAC information if available
if (req.rbac) {
logEntry.rbac = {
role: req.rbac.role,
authorized: req.rbac.authorized,
permission: req.rbac.requiredPermission
};
}
// Add agent information if available
if (req.headers['x-agent'] || req.body?.agent) {
logEntry.agent = req.headers['x-agent'] || req.body?.agent;
}
// Log based on status code
if (res.statusCode >= 400) {
console.error(`[ERROR] ${req.method} ${req.path} - ${res.statusCode} (${duration}ms)`, logEntry);
}
else {
console.log(`[SUCCESS] ${req.method} ${req.path} - ${res.statusCode} (${duration}ms)`, logEntry);
}
// Store RBAC log data if available for persistent logging
if (req.rbacLog) {
// This could be enhanced to write to a dedicated audit log
storeAuditLog(req.rbacLog, res.statusCode, duration);
}
originalSend.call(res, data);
};
next();
};
// Store audit log entry (placeholder for future database logging)
const storeAuditLog = (rbacLog, statusCode, duration) => {
const auditEntry = {
...rbacLog,
statusCode,
duration,
result: statusCode < 400 ? 'success' : 'failed'
};
// For now, just log to console with audit prefix
console.log(`[AUDIT] 📋`, auditEntry);
// Future enhancement: Store in database
// await auditLogService.store(auditEntry);
};
// Async operation logger
export const asyncLogger = (operationName) => {
return async (fn) => {
const start = Date.now();
console.log(`[ASYNC] Starting: ${operationName}`);
try {
const result = await fn();
const duration = Date.now() - start;
console.log(`[ASYNC] Completed: ${operationName} (${duration}ms)`);
return result;
}
catch (error) {
const duration = Date.now() - start;
console.error(`[ASYNC] Failed: ${operationName} (${duration}ms)`, error);
throw error;
}
};
};
export default {
requestLogger,
asyncLogger
};
//# sourceMappingURL=logging.js.map