baseapp provides all the boilerplate to get your JavaScript web application started off right, this Part 8.
- Intro to baseapp
- Client-Side Unit Tests
- Server-Side Unit Tests
- WebDriver Integration Tests
- Other Grunt Goodies
- Authentication
- Continuous Integration
- Administration
Logging
Bunyan provides very flexible JSON-based logging solution. Here is its config:
Bunyan = require('bunyan')
, log = Bunyan.createLogger({
name: "YOUR_APP"
, serializers : Bunyan.stdSerializers
, streams: [{
type: 'rotating-file'
, path: 'logs/http.log'
, period: '1d'
, count: 3
}]
})
All server logs are are kept in the 'logs' directory, rolled over every day, and 3 previous logs are kept. Bunyan's standard serializers handle serializing the request and response objects.
The logging routine is here:
app.set('logger', log);
// bunyan logging
app.use(function(req, res, next) {
var end = res.end;
req._startTime = new Date();
res.end = function(chunk, encoding){
res.end = end;
res.end(chunk, encoding);
log.info({req: req, res: res, total_time: new Date() - req._startTime}, 'handled request/response');
};
next();
});
This is the second Express 'use' statement - make sure it's near or at the top (only below the 'favicon' use) to log everything! This is taken directly from the 'connect.Logger' middleware - it basically hooks itself into the response 'end' method to record the total time the request took and the request and response objects.
Note we also stash the 'log' object in Express so other middleware can access it.
Starting and Stopping the Server
baseapp uses the awesome forever module to handle the start, restart, and stop of our server. Take a look at our 'start' and 'stop' commands in package.json:
"start": "node_modules/.bin/forever -a -p logs --minUptime 2000 --spinSleepTime 1000 -l forever.log -o logs/out.log -e logs/err.log start app.js",
"stop": "node_modules/.bin/forever stop app.js",
They delegate the handling of starting and stopping our websever to forever - which once started will monitor the process forever (Hmmm) and restart it if it crashes. However our server must be up for at least 2 seconds before forever will try to restart it - remember our server will kill itself off if it cannot connect to 'redis' so in that case we do not want forever always trying to restart it.
The '--spinSleepTime' option just says wait 1 second before trying to start up the server if it died (the forever default). We use the 'append' option (-a) and put all of forever's logs into our 'logs' directory and that's it!.
Executing:
% npm start
Will keep our webserver up even when/if it crashes subject to sane constraints. Plus we have a clean way to stop it via:
% npm stop
The server gets its HOST and PORT values to listen on from the environment. Here are its defaults:
app.set('port', process.env.PORT || 3000);
app.set('host', process.env.HOST || '0.0.0.0');
To change this:
% PORT=9999 HOST=localhost npm start
Now your server is listening on http://localhost:9999 (your shell may vary!). npm config variables is another way to go.
Forever has a couple more tricks up its sleeve - want to know what process forever has spawned off for you - 'forever list' to the rescue:
% node_modules/.bin/forever list
info: Forever processes running
data: uid command script forever pid logfile uptime
data: [0] OlRc /usr/local/bin/node app.js 54323 54324 logs/forever.log 0:0:0:3.727
You can edit the columns this command displays but you can read the forever documentation for that.
Finally note the index number '[0]' of our process - want to see the 'forever.log' for it but too lazy to load it up yourself? Here ya go:
% node_modules/.bin/forever logs 0
data: app.js:54324 - Express server listening on http://0.0.0.0:3000
data: app.js:54324 - Express server listening on http://0.0.0.0:9999
data: app.js:54324 - Express server listening on http://0.0.0.0:9999
data: app.js:54324 - Express server listening on http://localhost:9999
data: app.js:54324 - Express server listening on http://0.0.0.0:9999