Last active
August 29, 2015 14:09
-
-
Save hayes/20d6013c139f495c6577 to your computer and use it in GitHub Desktop.
Most loggers write to streams in a risky way, here is a simple demonstration, and way to avoid the issue.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs') | |
var http = require('http') | |
var count = 0 | |
// using fs.createWriteStream directly will cause massive memory and cpu ussage | |
// var log = fs.createWriteStream('test.log') | |
// if you want to make your computer feel bad, replace this with the line above | |
var log = new Logger('test.log') | |
// a simple server that sends an empty response and logs a message. | |
http.createServer(function(req, res) { | |
count += 1 | |
res.end() | |
log.write('handled a request\n ') | |
}).listen(9876) | |
// make a few simultainous requests to our server | |
for(var i = 0; i < 10; ++i) { | |
makeRequest() | |
} | |
// make a requests, on response, setup anotger request | |
function makeRequest() { | |
http.request('http://localhost:9876', function(res) { | |
res.on('end', makeRequest) | |
res.resume() | |
}).end() | |
} | |
// log out some performance stats | |
setInterval(function() { | |
console.log(count, 'requests/s.', 'memory ussage:', process.memoryUsage()) | |
count = 0 | |
}, 1000) | |
// A simple logger that ovoids this issue | |
function Logger(path) { | |
if(!(this instanceof Logger)) { | |
return new Logger(path) | |
} | |
// this will overwrite the previous file. Appending | |
// in this test is an unnessisary waist of disk space | |
this.stream = fs.createWriteStream(path) | |
// a place to store logs if the stream cant keep up | |
this.buffer = '' | |
// we will pause if the stream falls behind | |
this.paused = false | |
} | |
Logger.prototype.write = function write(msg) { | |
var logger = this | |
// if we are paused, add message to the buffer, we can deal with it later | |
if(logger.paused) { | |
return logger.buffer += msg | |
} | |
// writing to a stream returns a boolean, if it returns false we should pause | |
logger.paused = !logger.stream.write(msg) | |
// if we paused, wait for the stream to catch up | |
if(logger.paused) { | |
logger.stream.once('drain', function() { | |
// reset the state, then log out our accumulated messages | |
var msg = logger.buffer | |
logger.paused = false | |
logger.buffer = '' | |
logger.write(msg) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment