Nodejsdebugging生产中的错误

我有一个nodejs脚本在生产中运行

我不可能(千次)得到像这样的错误:

TypeError: value is out of bounds at checkInt (buffer.js:1009:11) at Buffer.writeUInt16LE (buffer.js:1067:5) at Object.foo.bar (/fake/path/name.js:123:1); at Object.foo.bar2 (/fake/path/name2.js:123:1); at Object.foo.bar3 (/fake/path/name3.js:123:1); 

导致生产服务器崩溃…

太棒了,我有一个堆栈跟踪! 但是我想知道当前数据是针对每个呼叫还是所有数据?

什么是一些很棒的工具或代码,用于生产代码的错误日志logging(使用当前数据)?

我强烈build议使用WinstonBunyan 。 npm包的select是你的应用程序的决定。

您可以通过查看npm页面中的统计信息来对可用的npm包进行基准testing。 统计基本如下。

  1. 在最后一天下载
  2. 在上周下载
  3. 在上个月下载
  4. 打开问题并打开请求。

最近有更多的下载次数表明对长期使用的模块有很大的支持。 所以这很重要。

Winstan和Bunyan都是市场上最好的npm软件包,主要的区别在于,Winstan对于正常的日志logging来说是非常棒的。 当然,Winstan提供了大量的日志function。 但是,如何能够利用这些能力,还需要努力一下比较邦扬。

本文另一方面则特别支持“ 分析日志 ”的事实。 所以基本上Bunyan是用于日志处理的。 所以,如果你想分析你的日志,日志文件,强烈build议使用Bunyan。 与Bunyan调整日志相对于Winstan来说相当容易。

我仔细比较了class扬和温斯坦。 请查看下面的链接,查看Winstan和Bunyan可以如何使用,取决于对Node应用程序进行日志logging的范围,用例和必要性。 链接: https : //docs.google.com/document/d/1pD9PLyxlcHVxxOvserNLO9tAz-QA_Co-xo6cWLhLghc/edit?usp =分享

另外在生产环境中 ,请确保明智地使用日志logging级别。 生产环境中最常用的日志级别是:

  • 错误
  • 信息
  • debugging

你可以使用温斯顿或皮诺

随着温斯顿你可以加载许多模块的日志你想要的,也许在线存储日志。 我从来没有使用皮诺,但我已经读了好东西。

设置envvariables来select输出你的日志的地方,例如,只有当你正在开发和在线存储,只有当应用程序正在生产时,你才会显示在标准输出上的输出。

处理node.jsasynchronous函数的一个好方法是使用decofundebugging工具

它的主要特点是根据上下文parsing匿名函数的代码和名称。

您可以通过使用deco filename.js运行匿名函数来匿名化匿名函数

文档中提到了一个简单的例子

 function gravy() { return function returnedᅠfromᅠgravyᅠㅣlineᅠ2 () { return { prop: function asᅠpropertyᅠpropᅠㅣlineᅠ4 () { setTimeout(function passedᅠintoᅠsetTimeoutᅠㅣlineᅠ5 () { console.trace('Getting a trace...'); }, 10) } } } } Trace: Getting a trace... at passedᅠintoᅠsetTimeoutᅠㅣlineᅠ5 [as _onTimeout] (/home/ubuntu/workspace/node_modules/decofun/examples/loadable/index.js:6:22) at Timer.listOnTimeout (timers.js:92:15) 

由于它带有embedded式可爱堆栈库,它将当前目录的path进行标准化

通过应用命令deco examples/loadable --cute table ,输出将显示为

在这里输入图像描述

我喜欢的最好的东西就是它把基于他们的调用的function转换成原来的function,就像从这个例子中看到的那样

  function one (a, cb) { } one('blah', function () { }) function two () { return function () { } } function three () { return { shoe: function () {} } } function four () { return function () { return function () { } } } function five () { return function () { return function () { return function () { foo('blue', function () { }) } } } } var six = function () { } var seven = function (err, cb) { return function () { cb(function () { }) } } var o = {}; o.eight = function (cb) { } o.eight(function () { }) o.eight.nine = function () {} o.eight.nine(function () { }) var o2; o2 = function () { } ;(function () {}()) !function () { }() function toodeep () { return function () { return function () { return function () { return function () { return function () { return function () { return function () { return function () { return function () { return function () { } } } } } } } } } } } 

进入这个

 function one (a, cb) { } one('blah', function passedᅠintoᅠoneᅠㅣlineᅠ6 () { }) function two () { return function returnedᅠfromᅠtwoᅠㅣlineᅠ11 () { } } function three () { return { shoe: function asᅠpropertyᅠshoeᅠㅣlineᅠ17 () {} } } function four () { return function returnedᅠfromᅠfourᅠㅣlineᅠ22 () { return function returnedᅠfromᅠᐸᅠreturnedᅠfromᅠfourᅠᐳᅠㅣlineᅠ23 () { } } } function five () { return function returnedᅠfromᅠfiveᅠㅣlineᅠ30 () { return function returnedᅠfromᅠᐸᅠreturnedᅠfromᅠfiveᅠᐳᅠㅣlineᅠ31 () { return function returnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠfiveᅠᐳᅠᐳᅠㅣlineᅠ32 () { foo('blue', function passedᅠintoᅠfooᅠㅣlineᅠ33 () { }) } } } } var six = function asᅠvarᅠsixᅠㅣlineᅠ42 () { } var seven = function asᅠvarᅠsevenᅠㅣlineᅠ47 (err, cb) { return function returnedᅠfromᅠᐸᅠasᅠvarᅠsevenᅠᐳᅠㅣlineᅠ49 () { cb(function passedᅠintoᅠcbᅠㅣlineᅠ50 () { }) } } var o = {}; o.eight = function asᅠpropertyᅠeightᅠㅣlineᅠ58 (cb) { } o.eight(function passedᅠintoᅠoːeightᅠㅣlineᅠ61 () { }) o.eight.nine = function asᅠpropertyᅠnineᅠㅣlineᅠ63 () {} o.eight.nine(function passedᅠintoᅠeightːnineᅠㅣlineᅠ64 () { }) var o2; o2 = function asᅠvarᅠo2ᅠㅣlineᅠ68 () { } ;(function IIFEᅠㅣlineᅠ71 () {}()) !function IIFEᅠㅣlineᅠ73 () { }() function toodeep () { return function returnedᅠfromᅠtoodeepᅠㅣlineᅠ78 () { return function returnedᅠfromᅠᐸᅠreturnedᅠfromᅠtoodeepᅠᐳᅠㅣlineᅠ79 () { return function returnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠtoodeepᅠᐳᅠᐳᅠㅣlineᅠ80 () { return function returnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠtoodeepᅠᐳᅠᐳᅠᐳᅠㅣlineᅠ82 () { return function returnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠtoodeepᅠᐳᅠᐳᅠᐳᅠᐳᅠㅣlineᅠ83 () { return function returnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠtoodeepᅠᐳᅠᐳᅠᐳᅠᐳᅠᐳᅠㅣlineᅠ84 () { return function returnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠᐸᅠreturnedᅠfromᅠtoodeepᅠᐳᅠᐳᅠᐳᅠᐳᅠᐳᅠᐳᅠㅣlineᅠ86 () { return function () { return function () { return function () { } } } } } } } } } } } 

希望这可能会有所帮助! 干杯!

我正在使用pm2 ,它是node.js的进程pipe理器,也是rollbar错误报告。 我想你应该为你的代码的一部分定义一些这个错误来自的指标。

对于任何uncaughtException服务器将停止,以便使服务器保持运行,即使有一个未捕获的exception我所做的是创build一个单独的集合用于存储错误,一旦未捕获的exception发生并返回时保存错误。

采集

 var ErrorSchema = new mongoose.Schema({ err_Message:{type:String}, err_Stack:{type:String}, date:{type:Date} }); 

调节器

 process.on('uncaughtException', function (err) { console.log(err); console.error((new Date).toUTCString() + ' uncaughtException:', err.message); console.error(err.stack); var newError = new Error; newError.err_Message = err.message; newError.err_Stack = err.stack; newError.date = moment(); newError.save(function(saveErr,errData){ if(!saveErr) console.log('New Error is saved'); else console.log('Error in saving error'); }); //process.exit(1) }); 

上述方法将未捕获的exception存储在Error集合中,并且进程/服务器不停止。

希望这可以帮助。