bithavoc / express-winston

express.js middleware for winstonjs
https://www.npmjs.com/package/express-winston
MIT License
796 stars 187 forks source link

Formatting not working in v3 #189

Closed DRoet closed 5 years ago

DRoet commented 5 years ago

Maybe I am missing something, but it seems like the new formatting stuff from winston v3 gets ignored:

app.use(expressWinston.logger({
   format: format.combine(
      format.timestamp(),
      format.colorize(),
      format.prettyPrint(),
   ),
   transports: [
       new transports.File({
           filename: '/var/log/node/fe-access.log',
           maxsize: 1000000,
           maxFiles: 2,
           tailable: true,
           eol: '\r\n\r\n'
       })
   ]
}))

Am I doing something wrong here? it seems like most of the readme examples are still for express-winston 2.x

edit: seems like https://github.com/bithavoc/express-winston/pull/190 takes care of the format being ignored

meszaros-lajos-gyorgy commented 5 years ago

I have the same issue. I use this configuration:

const expressLogger = expressWinston.logger({
  transports: [
    consoleTransport
  ],
  meta: false,
  expressFormat: true,
  colorize: false
})

With Winston 2.x you had to specify, that you don't want json in the transport, but now that is part of the logger:

const consoleTransport = new winston.transports.Console()

const logger = winston.createLogger({
  transports: [
    consoleTransport
  ],
  format: winston.format.combine(
    winston.format.colorize(),
    winston.format.simple()
  ),
  levels: config.levels
})

Now all my express lines are in JSON, no matter what I set in the expressWinston's configuration: ( note that the 1st line is produced by the new 3.x winston logger )

info: Server started @ 0.0.0.0:3000
{"level":"info","message":"GET / 200 25ms","meta":{}}
{"level":"info","message":"GET /reload/reload.js 304 1ms","meta":{}}
{"level":"info","message":"GET /presetlist 304 10ms","meta":{}}

My previous console transport looked like this with Winston 2.x:

const consoleTransport = new (winston.transports.Console)({
  prettyPrint: true,
  colorize: true,
  silent: false,
  timestamp: true
})
meszaros-lajos-gyorgy commented 5 years ago

The new transports do take configuration objects, but the formatting options are completely gone:

https://github.com/winstonjs/winston/blob/HEAD/docs/transports.md#console-transport

imdoroshenko commented 5 years ago

I solved this problem by using winstonInstance option.

const
  { createLogger, transports, format, config } = require('winston'),
  expressWinston = require('express-winston')

const
  customFormatter = format(customFormatterHandler),
  logger = createLogger({
    level: 'debug',
    levels: config.syslog.levels,
    format: format.combine(customFormatter(), format.json()),
    transports: [new transports.Console()]
  }),
  httpLogger = expressWinston.logger({
    winstonInstance: logger
  })
meszaros-lajos-gyorgy commented 5 years ago

What is the contents of the customFormatterHandler variable inside your example?

meszaros-lajos-gyorgy commented 5 years ago

By the way, using the logger with a formatting to the winstonInstance option seems to improve the situation. My current configuration is as below:

const winston = require('winston')
const expressWinston = require('express-winston')

const config = {
  levels: {
    info: 0,
    warn: 1,
    error: 2
  },
  colors: {
    info: 'green',
    warn: 'yellow',
    error: 'red'
  }
}

winston.addColors(config.colors)

const consoleTransport = new winston.transports.Console()

const logger = winston.createLogger({
  transports: [
    consoleTransport
  ],
  format: winston.format.combine(
    winston.format.colorize(),
    winston.format.simple()
  ),
  levels: config.levels
})

const expressLogger = expressWinston.logger({
  transports: [
    consoleTransport
  ],
  meta: false,
  expressFormat: true,
  colorize: true,
  winstonInstance: logger // The magic!
})

Note: even though I have the colorize formatting option set for the logger, I still need to set colorize to true in the expressWinston options.

crellison commented 5 years ago

Using a winstonInstance is currently the only way to solve the bug. With the 3.x release of winston, formatting was extracted from transformers and now must be set separately. The only workaround for this package is to pass everything through in a winstonInstance. Any formatting done in transporters will be ignored.

This is fixed in my PR #190, referenced by @DRoet above.

See https://github.com/winstonjs/winston/blob/master/UPGRADE-3.0.md#removed-winstontransportsfileconsolehttp-formatting-options

crellison commented 5 years ago

@DRoet @imdoroshenko @meszaros-lajos-gyorgy #190 is now merged to master. The 3.0.1 release will solve this issue. Feel free to look at the docs now or avoid this problem by passing your formatters in through a winstonInstance

meszaros-lajos-gyorgy commented 5 years ago

Thanks for the update, will check it!

DRoet commented 5 years ago

thanks!

galenweber commented 5 years ago

@crellison I'm still running into this issue, even with the 3.0.1 release.

I'm using the example from the docs verbatim (only with TypeScript), but I'll paste below:

import { Request, Response } from 'express';

import expressWinston from 'express-winston';
import winston from 'winston';

expressWinston.requestWhitelist.push('body');
expressWinston.responseWhitelist.push('body');

export default expressWinston.logger({
  transports: [
    new winston.transports.Console(),
  ],
  format: winston.format.combine(
    winston.format.colorize(),
    winston.format.json(),
  ),
  meta: true, // optional: control whether you want to log the meta data about the request (default to true)
  msg: 'HTTP {{req.method}} {{req.url}}', // optional: customize the default logging message. E.g. "{{res.statusCode}} {{req.method}} {{res.responseTime}}ms {{req.url}}"
  expressFormat: true, // Use the default Express/morgan request formatting. Enabling this will override any msg if true. Will only output colors with colorize set to true
  colorize: false, // Color the text and status code, using the Express/morgan color palette (text: gray, status: default green, 3XX cyan, 4XX yellow, 5XX red).
  ignoreRoute: (req: Request, res: Response) => { return false; }, // optional: allows to skip some log messages based on request and/or response
} as any);

The output to my console is unformatted, and looks like this (truncated for brevity):

{"level":"\u001b[32minfo\u001b[39m","message":"GET /ping 200 4ms","meta":{"res":{"statusCode":200,"body":"ping ding dong"},"req":{"url":"/ping","headers":{"host":"localhost:4000","connection":"keep-alive","cache-control":"max-age=0","upgrade-insecure-requests":"1","user-agent":..

Exporting this as middleware and then passing it into my Express app. Let me know if there is any other information I can provide, until then I think I'll revert to the 2.6.0 release.

crellison commented 5 years ago

@galenweber Thanks for letting us know. I've run our example locally and experienced the same issue. I think our example code doesn't show off the best starting options. Please try the 3.0.1 release again with the options below for format. I also noticed you have colorize set to false. You may want that set to true if you want the status codes colored too.

...
  format: format.combine(
    format.colorize(),
    format.simple(),
  ),
...

I changed those two things and got the following output to my console

screen shot 2018-12-05 at 11 02 19 pm
happy-machine commented 4 years ago

I have this problem. I'm using winston with fluentd and elasticsearch, so i need the levels to be logged to fluentd without the console log color formatting, but i want them colorized in the console. The format options in the transport dont seem to have any effect, so you can only set a global format setting.

If you use the above instance approach then you need to call multiple log commands which doesnt work for this problem.