0

I am using winston for logging in express project, with the following script:

At logger.js:

const {
  createLogger,
  transports,
  format
} = require('winston')


const logger = createLogger({
  transports: [
    new transports.File({
      filename: 'app.log',
      level: 'info',
      format: format.combine(format.colorize(),
        format.align(),
        format.timestamp(),
        format.json(),
      )
    })
  ]
});

And inside app.js:

const logger = require('~logger')
app.use((req, res, next) => {
  // const reqMsg = {
  //   'Request IP': req.ip,
  //   'Method': req.method,
  //   'URL': req.originalUrl,
  //   'statusCode': res.statusCode,
  //   'headers': req.headers,
  //   'Time': new Date(),
  //   'Response': JSON.stringify(res.send)
  // };
logger.logger.info((req.body))
next();

})

What I want to log is each API request data, and it's related response (colorized with timestamp).

The output is as following:

{"message":"\tundefined","level":"\u001b[32minfo\u001b[39m","timestamp":"2020-07-24T15:44:24.728Z"}

Or:

{"message":"[Object Object]","level":"\u001b[32minfo\u001b[39m","timestamp":"2020-07-24T15:44:24.728Z"}

I cannot see details of the request/response, and the output is not colorized as expected.

alim1990
  • 4,656
  • 12
  • 67
  • 130

2 Answers2

1

First of all, you have to know that a request body only comes on certain HTTP requests (like POST, PUT, etc), and it is undefined when there is no request body. Secondly, if you are using a body parser (like body-parser or the built-in one), req.body is an object, and winston may have some problems logging objects, so that may be why you can't see the request body when there is one. Lastly, winston colours logs with ANSI escape characters, and your terminal (or wherever you're seeing the output) may not be able to render those colours.

To log plain JavaScript objects with winston, you can refer to this question. To view colours correctly, you'll need a terminal that supports ANSI colours (e.g. bash, zsh, and cmd on Windows 10). And to colourize the entire log output, you have to tell the colorize function that, like so:

const logger = createLogger({
  transports: [
    new transports.File({
      filename: 'app.log',
      level: 'info',
      format: format.combine(
        format.colorize({all: true}),
        format.align(),
        format.timestamp(),
        format.json(),
      )
    })
  ]
});

Here is a link to the documentation of the colorize function: https://github.com/winstonjs/logform#colorize

Take-Some-Bytes
  • 918
  • 1
  • 8
  • 21
  • can you answer this https://stackoverflow.com/questions/76198169/express-and-events-with-winston-logger-set-up-halts-logging-to-file-on-error-occ – Alok May 14 '23 at 10:55
0

In addition to what @Take-Some-Bytes said, the following middleware function helped me logging everything I need:

const logging = require('~logger')
app.use((req, res, next) => {
    let oldSend = res.send
    res.send = function(data) {
      console.log(data)
      oldSend.apply(res, arguments)
      logging.logger.info(`Params: ${JSON.stringify(req.params)}, Body: ${JSON.stringify(req.body)}, Host: ${req.headers.host}, Route: ${req.originalUrl}, IP: ${req.ip}, Method: ${req.method}`, { ...req.body, status: res.statusCode, data: data })
    }
    next();
})
alim1990
  • 4,656
  • 12
  • 67
  • 130