What's the best practice for expressjs logging?
node.jsLoggingExpressnode.js Problem Overview
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.
node.js Solutions
Solution 1 - node.js
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.
Solution 2 - node.js
If 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...
Solution 3 - node.js
I 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)
Solution 4 - node.js
I 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