40

I'm making a Node.js app and I am using Winston for most of my logging purposes. I also aware of the Connect/Express logger function and know it has a stream option... Is it at all possible to output the stuff from Connect/Express's logger function to Winston? ...then I can have all the useful logging I need?

I find the logging that Connect/Express useful, but at the moment the two are sort of separate... I would must prefer to have it all running through Winston and it's transports.

How is that possible?

Chenmunka
  • 685
  • 4
  • 21
  • 25
littlejim84
  • 9,071
  • 15
  • 54
  • 77

2 Answers2

69

Here is what i did to solve this very issue. Basically use the stream option in the connect/express logger module to pipe the messages through to winston. I chose to use winston.info logging level, use whatever level makes sense for you.

var winston = require('winston');
var express = require('express');

var app = express.createServer();

// enable web server logging; pipe those log messages through winston
var winstonStream = {
    write: function(message, encoding){
        winston.info(message);
    }
};
app.use(express.logger({stream:winstonStream}));

// now do the rest of your express configuration...
Andrew De Andrade
  • 3,606
  • 5
  • 32
  • 37
sethpollack
  • 1,348
  • 1
  • 12
  • 13
  • 3
    Remember to chomp the message lest you get newlines in your logs – nflacco Sep 25 '12 at 20:06
  • 10
    Concretely, it should be `winston.info(message.slice(0, -1));` – yhpark Nov 15 '13 at 14:00
  • Worth noting that, as of now, `logger` is no longer bundled with Express, and should be installed separately. You could try [morgan](https://github.com/expressjs/morgan) for these matters, in this fashion: `app.use(require('morgan')('combine'));` – elussich Jun 16 '16 at 20:04
3

I had the same problem, I looked into the internals of the logger module and pretty much replicated what is there, in this custom middleware (warning, coffeescript).

As a bonus, it logs data using metadata fields as well.

(req, res, next) ->
  sock = req.socket
  req._startTime = new Date
  req._remoteAddress = sock.socket && sock.socket.remoteAddress || sock.remoteAddress;

  _url = () -> req.originalUrl || req.url
  _method = () -> req.method
  _respTime = () -> String(Date.now() - req._startTime)
  _status = () -> res.headerSent && res.statusCode || null
  _remoteAddr = () -> req.ip || req._remoteAddress || (req.socket?.socket? && req.socket.socket.remoteAddress) || req.socket.remoteAddress
  _usrAgent = () -> req.headers['user-agent']

  logRequest = () ->
    res.removeListener 'finish', logRequest
    res.removeListener 'close', logRequest
    winston.info "#{_method()} #{_url()} #{_status()} #{_remoteAddr()} #{_usrAgent()} #{_respTime()}",
      http_access:
        method: _method()
        url: _url()
        status: _status()
        remote_address: _remoteAddr()
        user_agent: _usrAgent()
  res.on 'finish', logRequest
  res.on 'close', logRequest

  next()
tuxpiper
  • 3,329
  • 2
  • 17
  • 6