DEV Community

Bryan
Bryan

Posted on • Originally published at devlogbook.com

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
Enter fullscreen mode Exit fullscreen mode

Setup Logging

  1. Install Winston

    npm install winston
    
  2. To be able to write daily logs instead of a single log, install Winston Daily Rotate File

    npm install winston-daily-rotate-file
    
  3. 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
    
  4. 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;
    
  5. 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` and `localhost:3000/log`, the log file can be found in **storage/logs** (example below)
Enter fullscreen mode Exit fullscreen mode
```log
[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
```
Enter fullscreen mode Exit fullscreen mode

Top comments (0)