Files
oldvine_cms/utils/logger.js
Talal Sharabi a3308a26e2 Initial commit: CMS backend for Old Vine Hotel
- Complete Express.js API server
- MongoDB integration with Mongoose
- Admin authentication and authorization
- Room management (CRUD operations)
- Booking management system
- Guest management
- Payment processing (Stripe integration)
- Content management (pages, blog, gallery)
- Media upload and management
- Integration services (Booking.com, Expedia, Opera PMS, Trip.com)
- Email notifications
- Comprehensive logging and error handling
2026-01-06 12:21:56 +04:00

132 lines
3.4 KiB
JavaScript

const winston = require('winston');
const path = require('path');
// Define custom log format
const logFormat = winston.format.combine(
winston.format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss'
}),
winston.format.errors({ stack: true }),
winston.format.json()
);
// Create logs directory if it doesn't exist
const fs = require('fs');
const logDir = 'logs';
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir);
}
// Create Winston logger
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: logFormat,
defaultMeta: { service: 'old-vine-hotel-api' },
transports: [
// Write all logs with level 'error' and below to 'error.log'
new winston.transports.File({
filename: path.join(logDir, 'error.log'),
level: 'error',
maxsize: 5242880, // 5MB
maxFiles: 5,
}),
// Write all logs with level 'info' and below to 'combined.log'
new winston.transports.File({
filename: path.join(logDir, 'combined.log'),
maxsize: 5242880, // 5MB
maxFiles: 5,
}),
// Write only booking-related logs
new winston.transports.File({
filename: path.join(logDir, 'bookings.log'),
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json(),
winston.format((info) => {
return info.type === 'booking' ? info : false;
})()
),
}),
// Write only payment-related logs
new winston.transports.File({
filename: path.join(logDir, 'payments.log'),
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json(),
winston.format((info) => {
return info.type === 'payment' ? info : false;
})()
),
}),
],
});
// If we're not in production, log to the console as well
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple(),
winston.format.printf(info => {
return `${info.timestamp} [${info.level}]: ${info.message} ${info.stack ? '\n' + info.stack : ''}`;
})
)
}));
}
// Custom logging methods for specific contexts
logger.bookingLog = (message, meta = {}) => {
logger.info(message, { ...meta, type: 'booking' });
};
logger.paymentLog = (message, meta = {}) => {
logger.info(message, { ...meta, type: 'payment' });
};
logger.integrationLog = (message, meta = {}) => {
logger.info(message, { ...meta, type: 'integration' });
};
logger.securityLog = (message, meta = {}) => {
logger.warn(message, { ...meta, type: 'security' });
};
// Error logging with context
logger.logError = (error, context = {}) => {
logger.error(error.message, {
error: {
message: error.message,
stack: error.stack,
name: error.name
},
context
});
};
// Request logging middleware
logger.requestLogger = (req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
logger.info('HTTP Request', {
method: req.method,
url: req.originalUrl,
statusCode: res.statusCode,
duration: `${duration}ms`,
userAgent: req.get('User-Agent'),
ip: req.ip || req.connection.remoteAddress,
type: 'http'
});
});
next();
};
module.exports = logger;