nakama/backend/middleware/logger.js

100 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const fs = require('fs');
const path = require('path');
const config = require('../config');
// Создать директорию для логов если её нет
const logsDir = path.join(__dirname, '../logs');
if (!fs.existsSync(logsDir)) {
fs.mkdirSync(logsDir, { recursive: true });
}
// Функция для логирования
const log = (level, message, data = {}) => {
const timestamp = new Date().toISOString();
const logMessage = `[${timestamp}] [${level.toUpperCase()}] ${message}`;
// Логирование в консоль
if (level === 'error') {
console.error(logMessage, data);
} else if (level === 'warn') {
console.warn(logMessage, data);
} else {
console.log(logMessage, data);
}
// Логирование в файл (только в production)
if (config.isProduction()) {
const logFile = path.join(logsDir, `${level}.log`);
const fileMessage = `${logMessage} ${JSON.stringify(data)}\n`;
fs.appendFile(logFile, fileMessage, (err) => {
if (err) {
console.error('Ошибка записи в лог файл:', err);
}
});
}
};
// Middleware для логирования запросов
const requestLogger = (req, res, next) => {
const start = Date.now();
// Логировать после завершения запроса
res.on('finish', () => {
const duration = Date.now() - start;
const logData = {
method: req.method,
path: req.path,
status: res.statusCode,
duration: `${duration}ms`,
ip: req.ip,
userAgent: req.get('user-agent'),
userId: req.user?.id || 'anonymous'
};
if (res.statusCode >= 400) {
log('error', 'Request failed', logData);
} else if (res.statusCode >= 300) {
log('warn', 'Request redirect', logData);
} else {
log('info', 'Request completed', logData);
}
});
next();
};
// Логирование подозрительной активности
const logSecurityEvent = (type, req, details = {}) => {
const securityData = {
type,
ip: req.ip,
userAgent: req.get('user-agent'),
path: req.path,
method: req.method,
userId: req.user?.id || 'anonymous',
...details
};
log('warn', 'Security event', securityData);
// В production можно отправить уведомление
if (config.isProduction()) {
const securityLogFile = path.join(logsDir, 'security.log');
const message = `[${new Date().toISOString()}] [SECURITY] ${type}: ${JSON.stringify(securityData)}\n`;
fs.appendFile(securityLogFile, message, (err) => {
if (err) {
console.error('Ошибка записи в security лог:', err);
}
});
}
};
module.exports = {
log,
requestLogger,
logSecurityEvent
};