Create a Basic Framework with Express (Part 1)
We will be using Docker, Node 18, MySQL 8, and Redis. Following Setting Up Node App using Docker post express, nodemon, dotenv packages should be installed.
In this application, we will not be writing a rest app, it will be a basic full stack framework. Packages will be installed once we reach the point where we need to use them.
Create Project Structure
node_modules
public
controllers
database
helpers
middlewares
routes
storage
views
Setup Logging
Install Winston
npm install winston
To be able to write daily logs instead of a single log, install Winston Daily Rotate File
npm install winston-daily-rotate-file
Create a logger.js helper in helpers directory
We want to have it log into daily log files of max size of 1GB and will be kept for 10 days.
const winston = require('winston') const { format } = winston const { combine, timestamp, printf, splat } = format require('winston-daily-rotate-file') const dailyTransport = new winston.transports.DailyRotateFile({ // file name format filename: 'application-%DATE%.log', datePattern: 'YYYY-MM-DD', zippedArchive: true, // limit each log to 1GB maxSize: '1g', // format the log format: combine( timestamp(), splat(), printf((info) => { return `[${info.timestamp}] ${info.level}: ${info.message}` }) ), level: 'info', // save logs into storage/logs dirname: 'storage/logs', // save logs for 10 days maxFiles: '10d', }) const logger = winston.createLogger({ transports: [dailyTransport], }) module.exports = logger
Create a errorHandler.middleware.js helper in middlewares directory
Log the error and send a response to the user
// import logger helpers const loggerx = require('../helpers/logger') const errorHandler = { // log the error logger: (error, request, response, next) => { loggerx.error(`${error.message} %o`, error) next(error) // calling next middleware }, responder: (error, request, response, next) => { const status = error.statusCode || 500 // send status and error message return response.status(status).send(error.message) } } module.exports = errorHandler;
Add the error handler middleware to index.js and test it out!
... const express = require('express') const app = express() // import the logger helper so we can test the logging const logger = require('../helpers/logger') // import the error handler const errorHandler = require('./middlewares/errorHandler.middleware.js') ... // Cause an error app.get('/error', async (req, res, next) => { try { let error = new Error('This is a major issue!!') error.statusCode = 500 throw error } catch (error) { return next(error) } }) // Just logging app.get('/log', async (req, res, next) => { logger.info('hello from /log') res.send('hello') }) // log the error app.use(errorHandler.logger) // send error to user app.use(errorHandler.responder) ...
- Go to
localhost:3000/error
andlocalhost:3000/log
, the log file can be found in storage/logs (example below)[2023-03-20T00:41:29.652Z] error: This is a major issue!! Error: This is a major issue!! at /app/index.js:28:25 at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) at next (/app/node_modules/express/lib/router/route.js:144:13) at Route.dispatch (/app/node_modules/express/lib/router/route.js:114:3) at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) at /app/node_modules/express/lib/router/index.js:284:15 at Function.process_params (/app/node_modules/express/lib/router/index.js:346:12) at next (/app/node_modules/express/lib/router/index.js:280:10) at expressInit (/app/node_modules/express/lib/middleware/init.js:40:5) at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) { [stack]: 'Error: This is a major issue!!\n' + ' at /app/index.js:28:25\n' + ' at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)\n' + ' at next (/app/node_modules/express/lib/router/route.js:144:13)\n' + ' at Route.dispatch (/app/node_modules/express/lib/router/route.js:114:3)\n' + ' at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)\n' + ' at /app/node_modules/express/lib/router/index.js:284:15\n' + ' at Function.process_params (/app/node_modules/express/lib/router/index.js:346:12)\n' + ' at next (/app/node_modules/express/lib/router/index.js:280:10)\n' + ' at expressInit (/app/node_modules/express/lib/middleware/init.js:40:5)\n' + ' at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)', [message]: 'This is a major issue!!', statusCode: 500 } [2023-03-20T00:41:59.271Z] info: hello from /log
- Go to