Errores de depuración de Nodejs en producción.

Tengo un script nodejs ejecutándose en producción

Es improbable (una vez en mil veces) obtener errores como este:

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); 

Haciendo que el servidor de producción se bloquee …

Genial tengo un stacktrace! ¿Pero quiero saber cuáles son los datos actuales para cada llamada o todos los datos?

¿Cuáles son algunas de las grandes herramientas o códigos para usar para el registro de errores (con sus datos actuales) en el código de producción?

Recomiendo encarecidamente usar Winston o Bunyan . La selección del paquete npm es una decisión de su aplicación.

Puede comparar los paquetes de npm disponibles revisando las estadísticas en las páginas de npm disponibles. Las estadísticas son básicamente las siguientes.

  1. descargas en el último día
  2. descargas en la última semana
  3. descargas en el último mes
  4. Problemas abiertos y solicitudes de extracción abiertas.

Tener un número mayor de descargas recientemente indicará que hay un gran soporte para el módulo que está utilizando a largo plazo. Así que eso es importante.

Tanto Winstan como Bunyan son los mejores paquetes de npm de registro en el mercado, la principal diferencia es que Winstan es realmente impresionante y flexible para los propósitos de registro normal. Por supuesto, Winstan ofrece una gran cantidad de capacidades de registro. Pero como siempre, para hacer uso de estas capacidades, es necesario realizar algunos esfuerzos en comparación con Bunyan.

Bunyan, por otro lado, es especialmente compatible con el hecho de ” analizar registros “. Así que, básicamente, Bunyan es para el procesamiento de registros. Por lo tanto, si desea analizar sus registros, se recomienda encarecidamente el uso de Bunyan. Ajustar los registros con Bunyan es bastante fácil en comparación con Winstan.

Hice una comparación exhaustiva entre Bunyan y Winstan. Verifique el enlace a continuación para ver cómo pueden usar Winstan y Bunyan según el scope, el caso de uso y la necesidad de iniciar sesión en la aplicación Node. enlace: https://docs.google.com/document/d/1pD9PLyxlcHVxxOvserNLO9tAz-QA_Co-xo6cWLhLghc/edit?usp=sharing

También en el entorno de producción , asegúrese de utilizar los niveles de registro de forma inteligente. Los niveles de registro más utilizados en el entorno de producción son:

  • error
  • info
  • depurar

Puedes usar Winston o Pino

Con Winston puede cargar muchos módulos para el registro donde desee y tal vez almacenar los registros en línea. Nunca uso pino, pero he leído cosas buenas sobre él.

Establezca las variables env para elegir la salida del registro, por ejemplo, usted no mostrará la salida en la salida estándar solo si está en desarrollo y la tienda en línea solo si la aplicación está en producción.

Una buena manera de manejar las funciones asíncronas en node.js es usando la herramienta de depuración decofun .

Su principal característica es analizar el código y los nombres de las funciones anónimas de acuerdo con su contexto.

Puede desactivar cualquier función anónima ejecutándola con deco filename.js

Un ejemplo simple sería como se menciona en la documentación.

 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) 

Ya que viene con una biblioteca incrustada de stack linda que normaliza la ruta al directorio actual

Al aplicar el comando deco examples/loadable --cute table la salida se mostrará como

introduzca la descripción de la imagen aquí

Lo mejor que me gusta de esto es que transforma las funciones basadas en sus llamadas a la original como se ve en el ejemplo de este

  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 () { } } } } } } } } } } } 

dentro de esto

 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 () { } } } } } } } } } } } 

Espero que esto pueda ayudar un poco! ¡Aclamaciones!

Estoy usando pm2, que es un administrador de procesos para node.js y también informe de errores de la node.js de node.js . Creo que deberías definir algunas métricas para la parte de tu código de la que proviene este error.

Para cualquier excepción uncaughtException, el servidor se detendrá para hacer que el servidor siga funcionando, incluso cuando hay una excepción no detectada. Lo que he hecho es crear una colección separada para almacenar el error, guardar el error una vez que se produce una excepción no detectada y se devuelve.

Colección

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

Controlador

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

Los métodos anteriores almacenan la excepción no detectada en la recostackción de errores y el proceso / servidor no se detiene.

Espero que esto ayude.