我有一个node.js脚本,它使用WriteStream对文件进行一些日志记录。在某些事件上,我想停止执行脚本,即警告记录并在此之后立即退出。 asyncronious node.js不允许我们直接这样做:
#!/usr/local/bin/node
var fs = require('fs');
var stream = fs.createWriteStream('delme.log', { flags: 'a' });
stream.write('Something bad happened\n');
process.exit(1);
这个脚本不对文件附加消息,而是对delme.log附加消息。处理'退出'事件和刷新不起作用。到目前为止,在退出之前写入最后一条日志消息的唯一方法是将process.exit(1)
包裹在setTimeout()
中:
#!/usr/local/bin/node
var fs = require('fs');
var stream = fs.createWriteStream('delme.log', { flags: 'a' });
stream.write('Something bad happened\n');
setTimeout(function(){
process.exit(1);
}, 30);
但是在这种形式下,它不会立即停止脚本执行,并且在关键事件发生后脚本将运行一段时间。所以我想知道是否有其他方法可以通过日志消息退出脚本?
答案 0 :(得分:12)
由于你想要阻止,并且已经在使用流,你可能想要自己处理写作。
var data = new Buffer('Something bad happened\n');
fs.writeSync(stream.fd, data, 0, data.length, stream.pos);
process.exit();
答案 1 :(得分:3)
要在退出之前将所有日志消息刷新到文件,可能需要在try-catch块中包装脚本执行。一旦发生了坏事,它就会被记录并抛出一个异常,这个异常将被外部try
捕获,从中可以安全地异步退出:
#!/usr/local/bin/node
var fs = require('fs');
var stream = fs.createWriteStream('delme.log', { flags: 'a' });
var SOMETHING_BAD = 'Die now';
try {
// Any code goes here...
if (somethingIsBad) {
stream.write('Something bad happened\n');
throw new Error(SOMETHING_BAD);
}
} catch (e) {
if (e.message === SOMETHING_BAD) {
stream.on('drain', function () {
process.exit(1);
});
} else {
throw e;
}
}
答案 2 :(得分:3)
<强>改进。强>
var fs = require('fs');
var stream = fs.createWriteStream('delme.log', {flags: 'a'});
// Gracefully close log
process.on('uncaughtException', function () {
stream.write('\n'); // Make sure drain event will fire (queue may be empty!)
stream.on('drain', function() {
process.exit(1);
});
});
// Any code goes here...
stream.write('Something bad happened\n');
throw new Error(SOMETHING_BAD);
try-catch块工作但很难看。学分仍然是@nab,我只是美化了它。
答案 3 :(得分:1)
我主张在这个事件中写给stderr - 例如琐碎的例子
console.error(util.inspect(exception));
然后让监督*进程处理日志持久性。从我的理解来看,你现在不必担心stdout和stderr在节点退出之前没有刷新(尽管我确实在0.2.x版本的某些版本中看到了有问题的相反行为)。
(*)对于监督过程,请选择supervisord,god,monit,forever,pswatch等......
这也为使用Heroku和dotcloud等PaaS提供商提供了一条干净的道路......让基础设施管理日志记录
答案 4 :(得分:1)
我认为这是正确的方法:
process.on('exit', function (){
// You need to use a synchronous, blocking function, here.
// Not streams or even console.log, which are non-blocking.
console.error('Something bad happened\n');
});