backend logging
This commit is contained in:
53
backend/middleware/apiLogger.js
Normal file
53
backend/middleware/apiLogger.js
Normal file
@@ -0,0 +1,53 @@
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
const apiLogger = (req, res, next) => {
|
||||
const startTime = Date.now();
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
|
||||
const requestData = {
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
userAgent: req.get('User-Agent'),
|
||||
ip: req.ip,
|
||||
userId: req.user?.id || 'anonymous',
|
||||
body: logger.sanitize(req.body),
|
||||
params: req.params,
|
||||
query: req.query,
|
||||
headers: {
|
||||
'content-type': req.get('Content-Type'),
|
||||
'content-length': req.get('Content-Length'),
|
||||
'referer': req.get('Referer'),
|
||||
}
|
||||
};
|
||||
|
||||
reqLogger.info('API Request', requestData);
|
||||
|
||||
const originalSend = res.send;
|
||||
res.send = function(body) {
|
||||
const endTime = Date.now();
|
||||
const responseTime = endTime - startTime;
|
||||
|
||||
const responseData = {
|
||||
statusCode: res.statusCode,
|
||||
responseTime: `${responseTime}ms`,
|
||||
contentLength: res.get('Content-Length') || (body ? body.length : 0),
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
userId: req.user?.id || 'anonymous'
|
||||
};
|
||||
|
||||
if (res.statusCode >= 400 && res.statusCode < 500) {
|
||||
reqLogger.warn('API Response - Client Error', responseData);
|
||||
} else if (res.statusCode >= 500) {
|
||||
reqLogger.error('API Response - Server Error', responseData);
|
||||
} else {
|
||||
reqLogger.info('API Response - Success', responseData);
|
||||
}
|
||||
|
||||
return originalSend.call(this, body);
|
||||
};
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
module.exports = apiLogger;
|
||||
@@ -1,5 +1,6 @@
|
||||
const jwt = require("jsonwebtoken");
|
||||
const { User } = require("../models"); // Import from models/index.js to get models with associations
|
||||
const logger = require("../utils/logger");
|
||||
|
||||
const authenticateToken = async (req, res, next) => {
|
||||
// First try to get token from cookie
|
||||
@@ -43,7 +44,13 @@ const authenticateToken = async (req, res, next) => {
|
||||
});
|
||||
}
|
||||
|
||||
console.error("Auth middleware error:", error);
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.error("Auth middleware error", {
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
tokenPresent: !!token,
|
||||
userId: req.user?.id
|
||||
});
|
||||
return res.status(403).json({
|
||||
error: "Invalid token",
|
||||
code: "INVALID_TOKEN",
|
||||
|
||||
33
backend/middleware/errorLogger.js
Normal file
33
backend/middleware/errorLogger.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
const errorLogger = (err, req, res, next) => {
|
||||
// Create a request-specific logger with request ID
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
|
||||
// Log the error with context
|
||||
const errorContext = {
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
userAgent: req.get('User-Agent'),
|
||||
ip: req.ip,
|
||||
userId: req.user?.id || 'anonymous',
|
||||
body: logger.sanitize(req.body),
|
||||
params: req.params,
|
||||
query: req.query,
|
||||
statusCode: err.statusCode || 500,
|
||||
stack: err.stack,
|
||||
};
|
||||
|
||||
if (err.statusCode && err.statusCode < 500) {
|
||||
// Client errors (4xx)
|
||||
reqLogger.warn(`Client error: ${err.message}`, errorContext);
|
||||
} else {
|
||||
// Server errors (5xx)
|
||||
reqLogger.error(`Server error: ${err.message}`, errorContext);
|
||||
}
|
||||
|
||||
// Pass error to next middleware
|
||||
next(err);
|
||||
};
|
||||
|
||||
module.exports = errorLogger;
|
||||
@@ -1,3 +1,5 @@
|
||||
const logger = require('../utils/logger');
|
||||
|
||||
// HTTPS enforcement middleware
|
||||
const enforceHTTPS = (req, res, next) => {
|
||||
// Skip HTTPS enforcement in development
|
||||
@@ -20,11 +22,13 @@ const enforceHTTPS = (req, res, next) => {
|
||||
|
||||
// Log the redirect for monitoring
|
||||
if (req.headers.host !== allowedHost) {
|
||||
console.warn("[SECURITY] Host header mismatch during HTTPS redirect:", {
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.warn("Host header mismatch during HTTPS redirect", {
|
||||
requestHost: req.headers.host,
|
||||
allowedHost,
|
||||
ip: req.ip,
|
||||
url: req.url,
|
||||
eventType: 'SECURITY_HOST_MISMATCH'
|
||||
});
|
||||
}
|
||||
|
||||
@@ -70,34 +74,21 @@ const addRequestId = (req, res, next) => {
|
||||
|
||||
// Log security events
|
||||
const logSecurityEvent = (eventType, details, req) => {
|
||||
const reqLogger = logger.withRequestId(req.id || "unknown");
|
||||
|
||||
const logEntry = {
|
||||
timestamp: new Date().toISOString(),
|
||||
eventType,
|
||||
requestId: req.id || "unknown",
|
||||
ip: req.ip || req.connection.remoteAddress,
|
||||
userAgent: req.get("user-agent"),
|
||||
userId: req.user?.id || "anonymous",
|
||||
...details,
|
||||
};
|
||||
|
||||
// In production, this should write to a secure log file or service
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
console.log("[SECURITY]", JSON.stringify(logEntry));
|
||||
} else {
|
||||
console.log("[SECURITY]", eventType, details);
|
||||
}
|
||||
reqLogger.warn(`Security event: ${eventType}`, logEntry);
|
||||
};
|
||||
|
||||
// Sanitize error messages to prevent information leakage
|
||||
const sanitizeError = (err, req, res, next) => {
|
||||
// Log the full error internally
|
||||
console.error("Error:", {
|
||||
requestId: req.id,
|
||||
error: err.message,
|
||||
stack: err.stack,
|
||||
userId: req.user?.id,
|
||||
});
|
||||
|
||||
// Send sanitized error to client
|
||||
const isDevelopment =
|
||||
process.env.NODE_ENV === "dev" || process.env.NODE_ENV === "development";
|
||||
|
||||
Reference in New Issue
Block a user