I am building an application based on expressjs and I'd like to log all events in it. I could find winston, which seems to be cool. Anyway, I am looking for a way how to connect it to my expressjs app.
What I also want is logging inside the application. My reqeusts are not so simple, so I'd like to log everything inside my app (not only requests).
My current situation:
server.js (I'd like to log http requests on this level)
var express = require('express'); var app = express(); var fs = require('fs'); // Post parser app.configure(function(){ app.use(express.bodyParser()); }); // Load routes require('fs').readdirSync(__dirname + '/routes').forEach(function(file) { require(__dirname + '/routes/' + file)(app); }); // 404: Not found app.use(function(req, res, next){ res.json(404, {ERROR: 'Page not found.'}); }); // 500: Error reporing app.use(function(err, req, res, next){ console.error(err.stack); res.json(500, {ERROR: 'Internal server error.'} ); }); // Startup new server app.listen(900); routes/something.js
var something = require(__dirname + '/../controller/something.js'); module.exports = function(app) { app.get('/v1/something', function(req, res, next) { new something().getAll(req, res, next); }); }; controller/something.js (I'd like to use the same logger for debug logging)
/** * Constructor * */ function Something() { }; /** * Get all the data * */ Something.prototype.getAll = function(req, res, next) { // I want to log some very important information here res.json({result: true, data: ['hello', 'hi', 'ciao', 'buf']}); } module.exports = Something; The other thing I am thinking about is logging all the events in functions that are called from controllers (e.g. models or other libraries).
So I think, the good way might to create some logger library, that will be called using:
var logger = require(__dirname + '/../libraries/logger.js'); containing logger definition. The other issue I don't know how to solve is how to prefix data. You know, I have a lot of concurrent requests and I'd like to see which debug message was called by each request.
4 Answers
We use winston, it's probably the most robust logging package out there.
We ended up setting it up exactly like you suggested. Creating a common library used for wrapping the logger object around our definitions and transports, and then handling any other type of objects we want to be handled differently.
2If you're using express you may want to look at express-winston package. Then you can use winston as middleware and easily log requests/errors without making your code messy...
3I love the following Rails-style logging:
[2017-11-02T11:13:54.545 #07738a81] Started GET /api/url for 10.0.0.1 [2017-11-02T11:13:54.550 #07738a81] Completed 200 31739 in 5.635 ms The code below does it
addRequestId = require('express-request-id')(setHeader: false) app.use(addRequestId) morgan = require('morgan') morgan.token('id', (req) -> req.id.split('-')[0]) app.use(morgan( "[:date[iso] #:id] Started :method :url for :remote-addr", immediate: true)) app.use(morgan(" [:date[iso] #:id] Completed :status :res[content-length] in :response-time ms")) app.use('/api', router) 1I love Hirung103 answer, so here is the javascript version:
First, add express-request-id and morgan if those libs not listed in your package.json.
Then add these lines inside your server.js:
... const addRequestId = require('express-request-id')({ setHeader: false }) app.use(addRequestId) const morgan = require('morgan') morgan.token('id', (req) => { req.id.split('-')[0] }) app.use( morgan( "[:date[iso] #:id] Started :method :url for :remote-addr", { immediate: true } ) ) ... thanks to Hirung103