- 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
132 lines
3.4 KiB
JavaScript
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; |