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
This commit is contained in:
132
utils/logger.js
Normal file
132
utils/logger.js
Normal file
@@ -0,0 +1,132 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user