2012-02-08 66 views
9

我有一个node.js脚本,它使用WriteStream对文件执行一些日志记录。在某些事件中,我想停止脚本的执行,即警告在此之后立即登录并退出。作为asyncronious node.js中不允许我们这样做直线前进,如:用日志消息退出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这个脚本不做任何处理的文件,而不是。处理“退出”事件和冲洗不起作用。写了这么远之前exitting找到的最后一个日志消息的唯一途径是包装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); 

然而,在这种形式,它不会立即停止执行脚本和脚本将运行一段重大事件发生后的时间。所以我想知道是否有其他方法来退出脚本与日志消息?

回答

11

由于您想阻止,并且已经在使用流,您可能需要自己处理写作。

var data = new Buffer('Something bad happened\n'); 
fs.writeSync(stream.fd, data, 0, data.length, stream.pos); 
process.exit(); 
+0

谢谢!这是setTimeout()调用的一个变体,它不会阻止脚本执行。如果有一个代码不应该在异常之后执行,这个模式可能会成为一个问题。 – nab 2012-02-08 16:48:35

+0

更新了我的答案。 – fent 2012-02-08 17:56:00

+1

在我的特殊情况下,我使用WriteStream进行日志记录,这样实际的调用将会是log.error('发生了什么坏事'),它会使用适当的日志级别添加其他一些东西来格式化消息。因此,在不改变记录器界面的情况下很难实现此片段。我正在发布我的解决方法作为替代解决方案。最初的问题完全回答。谢谢! – nab 2012-02-08 22:34:48

0

我会主张只是写在这个事件标准错误 - e.g简单的例子

console.error(util.inspect(exception)); 

,然后让监督*工艺处理日志持久性。根据我现在的理解,在节点退出之前,您不必担心stdout和stderr不会刷新(尽管我在0.2.x版本的某些版本中看到了有问题的相反行为)。

(*)为监督过程从supervisord,神,monit的,永远的,pswatch等你挑......

这也提供了使用的PaaS提供商,比如Heroku的和dotcloud等清洁路径...让基础设施管理日志

+1

我宁愿解决它(以某种方式)程序化。我有许多不同种类的简短运行脚本。他们中有些人只是向STDERR发出警告,一些日志数据到文件系统。我需要的是一种统一的方法,可以在不依赖外部软件的情况下使用日志消息退出脚本。无论如何感谢提示:) – nab 2012-02-08 16:40:04

+0

它不会被刷新。 – zupa 2013-01-11 21:21:51

0

我认为这是正确的方式:

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'); 
}); 
3

要exitting一个可能要包装在一个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; 
    } 
} 
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,我只是对它进行了美化。

相关问题