[英]Nodejs debug errors in production
我有一個在生產中運行的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);
導致生產服務器崩潰......
太棒了我有一個堆棧跟蹤! 但我想知道每個電話或所有數據的當前數據是什么?
有什么好的工具或代碼可用於生產代碼的錯誤記錄(使用它的當前數據)?
我強烈建議使用Winston或Bunyan 。 選擇npm包是您的應用程序的決定。
您可以通過瀏覽npm頁面中可用的統計信息來對可用的npm包進行基准測試。 統計數據基本上如下。
最近有更多的下載量表明從長遠來看,您正在使用的模塊有很大的支持。 所以這很重要。
Winstan和Bunyan都是市場上最好的npm軟件包,主要區別在於,Winstan對於正常的日志記錄來說非常棒和靈活。 當然,Winstan提供了大量的日志記錄功能。 但是,與Bunyan相比,要想利用這些功能,需要付出一些努力。
另一方面,Bunyan特別支持“ 分析日志 ”的事實。 所以基本上Bunyan用於日志處理。 因此,如果您想分析日志,日志文件,強烈建議您使用Bunyan。 使用Bunyan調整日志對Winstan來說相當容易。
我對Bunyan和Winstan進行了徹底的比較。 請查看下面的鏈接,查看Winstan和Bunyan如何使用,具體取決於記錄到Node應用程序的范圍,用例和必要性。 鏈接: https : //docs.google.com/document/d/1pD9PLyxlcHVxxOvserNLO9tAz-QA_Co-xo6cWLhLghc/edit?usp=sharing
同樣在生產環境中 ,請確保明智地使用日志記錄級別。 生產環境中最常用的日志記錄級別是:
處理node.js
的異步函數的一種好方法是使用decofun調試工具 。
它的主要特征是根據其上下文解析代碼和匿名函數的名稱。
您可以通過使用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)
因為它帶有嵌入式可愛堆棧庫,可以規范化當前目錄的路徑
通過應用命令deco examples/loadable --cute table
,輸出將顯示為
我最喜歡它的是它根據它們對原始函數的調用來轉換函數 ,如下例所示
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 () {
}
}
}
}
}
}
}
}
}
}
}
希望這可能會有所幫助! 干杯!
對於任何uncaughtException,服務器將停止以使服務器繼續運行,即使存在未捕獲的異常,我所做的是創建一個單獨的集合來存儲錯誤,一旦發生未捕獲的異常並保存錯誤並返回。
采集
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)
});
上述方法將未捕獲的異常存儲在Error集合中,並且進程/服務器不會停止。
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.