diff --git a/backend/config/logger.js b/backend/config/logger.js new file mode 100644 index 00000000..da6a00ba --- /dev/null +++ b/backend/config/logger.js @@ -0,0 +1,21 @@ +// config/logger.js +const winston = require("winston"); + +const logger = winston.createLogger({ + level: "info", // Set the default logging level + format: winston.format.combine( + winston.format.timestamp(), // Include a timestamp + winston.format.colorize(), // Colorize the output + winston.format.printf(({ timestamp, level, message, stack, errors }) => { + return `${timestamp} [${level}] ${message}${ + stack ? `\nStack: ${stack}` : "" + }${errors ? `\nErrors: ${JSON.stringify(errors)}` : ""}`; // Custom format + }) + ), + transports: [ + new winston.transports.Console(), // Log to console + new winston.transports.File({ filename: "error.log", level: "error" }), // Log errors to a file + ], +}); + +module.exports = logger; diff --git a/backend/controller/feedback.controller.js b/backend/controller/feedback.controller.js index f8a2788e..5cdb36ec 100644 --- a/backend/controller/feedback.controller.js +++ b/backend/controller/feedback.controller.js @@ -1,5 +1,6 @@ const { z } = require("zod"); const { Feedback } = require("../models/feedback.model"); +const logger = require("../config/logger"); // Import your logger // Define the Zod schema for feedback validation const feedbackSchema = z.object({ @@ -13,7 +14,10 @@ async function createFeedback(req, res) { const validationResult = feedbackSchema.safeParse(req.body); if (!validationResult.success) { - console.error("Validation error:", validationResult.error.errors); + logger.error("Validation error:", { + errors: validationResult.error.errors, // Log the detailed validation errors + body: req.body, // Optionally log the request body for context + }); // Use logger for validation errors return res.status(400).json({ success: false, message: "Validation failed", @@ -29,7 +33,7 @@ async function createFeedback(req, res) { data: feedback, }); } catch (error) { - console.error("Error creating feedback:", error); + logger.error("Error creating feedback:", error); // Log the error using Winston res.status(500).json({ success: false, message: "An error occurred while creating the feedback", @@ -41,7 +45,7 @@ module.exports = { createFeedback, }; -//dummy api call for feedback +// Dummy API call for feedback // { // "name": "John Doe", // "email": "john@1212.com", diff --git a/backend/controller/reservation.controller.js b/backend/controller/reservation.controller.js index f5631326..4ee00658 100644 --- a/backend/controller/reservation.controller.js +++ b/backend/controller/reservation.controller.js @@ -1,5 +1,6 @@ const { z } = require("zod"); const Reservation = require("../models/reservation.model"); +const logger = require("../config/logger"); // Import your logger // Define the Zod schema for reservation validation const reservationSchema = z.object({ @@ -13,7 +14,10 @@ async function createReservation(req, res) { const validationResult = reservationSchema.safeParse(req.body); if (!validationResult.success) { - console.error("Validation error:", validationResult.error.errors); + logger.error("Validation error:", { + errors: validationResult.error.errors, + body: req.body, + }); return res.status(400).json({ success: false, message: "Validation failed", @@ -29,7 +33,12 @@ async function createReservation(req, res) { data: reservation, }); } catch (error) { - console.error("Error creating reservation:", error); + logger.error("Error creating reservation:", { + message: error.message, + stack: error.stack, + body: req.body, + }); + res.status(500).json({ success: false, message: "An error occurred while creating the reservation", diff --git a/backend/index.js b/backend/index.js index 30c9ee2c..89240258 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,10 +1,15 @@ const express = require("express"); const cors = require("cors"); -const app = express(); -const port = 3000; -require("dotenv").config(); const mongoose = require("mongoose"); +const dotenv = require("dotenv"); +const logger = require("./config/logger"); // Import your logger +const errorMiddleware = require("./middlewares/errrorMiddleware"); + +dotenv.config(); +const app = express(); +const port = process.env.PORT || 3000; +// CORS configuration app.use( cors({ origin: ["http://localhost:5173", "https://play-cafe.vercel.app"], @@ -13,22 +18,31 @@ app.use( app.use(express.json()); +// MongoDB connection mongoose .connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true, }) .then(() => { - console.log("Connected to MongoDB"); + logger.info("Connected to MongoDB"); // Log successful connection }) .catch((error) => { - console.error("Database connection failed:", error.message); - console.error(error.stack); + logger.error("Database connection failed:", error.message); // Use logger for connection error process.exit(1); }); +// API routes app.use("/api", require("./routes/index")); -app.listen(port, () => console.log(`Server is running on port ${port}!`)); +// Health Check Endpoint +app.get("/health", (req, res) => { + res.status(200).json({ status: "OK" }); +}); + +app.use(errorMiddleware); + +// Start server +app.listen(port, () => logger.info(`Server is running on port ${port}!`)); // Log server start module.exports = app; diff --git a/backend/middlewares/errrorMiddleware.js b/backend/middlewares/errrorMiddleware.js new file mode 100644 index 00000000..4c3afd5a --- /dev/null +++ b/backend/middlewares/errrorMiddleware.js @@ -0,0 +1,20 @@ +// middlewares/errorMiddleware.js +const logger = require("../config/logger"); // Assuming you have a logger set up + +function errorMiddleware(err, req, res, next) { + // Log the error details using logger + logger.error(err.message, { + stack: req.body, // Include stack trace + url: req.originalUrl, // Request URL + method: req.method, // HTTP method + body: req.body, // Request body + }); + + // Send the response + res.status(err.status || 500).json({ + success: false, + message: err.message || "An unexpected error occurred.", + }); +} + +module.exports = errorMiddleware; diff --git a/backend/package.json b/backend/package.json index 799d3463..2275182a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -17,6 +17,7 @@ "express": "^4.21.0", "mongoose": "^8.7.0", "validator": "^13.12.0", + "winston": "^3.14.2", "zod": "^3.23.8" }, "devDependencies": { diff --git a/backend/routes/feedbackRouter.js b/backend/routes/feedbackRouter.js index eff2d4e4..e02c3bab 100644 --- a/backend/routes/feedbackRouter.js +++ b/backend/routes/feedbackRouter.js @@ -1,17 +1,19 @@ const express = require("express"); -const { Feedback } = require("../models/feedback.model"); -const createFeedback = require("../controller/feedback.controller"); - +const { createFeedback } = require("../controller/feedback.controller"); const router = express.Router(); +const apiInfo = require("../config/api.info"); +const logger = require("../config/logger"); // Import your logger router.post("/create", createFeedback); -const apiInfo = require("../config/api.info"); - router.get("/", (req, res) => { try { res.json(apiInfo); } catch (error) { + logger.error("Error fetching API info:", { + message: error.message, + stack: error.stack, + }); res.status(500).json({ error: "Internal server error" }); } }); diff --git a/backend/routes/index.js b/backend/routes/index.js index 9e0b9c30..bbe44865 100644 --- a/backend/routes/index.js +++ b/backend/routes/index.js @@ -1,5 +1,6 @@ const express = require("express"); const Reservation = require("../models/reservation.model"); +const logger = require("../config/logger"); // Import your Winston logger const router = express.Router(); @@ -7,21 +8,24 @@ let feedbackRouter; try { feedbackRouter = require("./feedbackRouter"); } catch (error) { - console.error("Error loading feedbackRouter:", error); - feedbackRouter = (req, res, next) => { + logger.error("Error loading feedbackRouter:", error); // Log the error with Winston + feedbackRouter = (req, res) => { res .status(500) .json({ error: "Feedback functionality is currently unavailable" }); }; } + router.use("/feedback", feedbackRouter); router.use("/reservation", require("./reservationRouter")); + router.get("/", (req, res) => { res.json({ message: "Welcome to the restaurant API!", version: "1.0.0", endpoints: { Reservation: "/reservation", + Feedback: "/feedback", // Added feedback endpoint documentation }, documentation: "https://api-docs-url.com", });