Pino: Cree un registrador estándar

Pino

Cree un registrador estándar de la industria para Node.js con Pino

Una guía para crear un registrador estándar de la industria para Node.js usando Pino.

Este artículo cubrirá el uso de la biblioteca Pino. Pino es una biblioteca de registro estándar de la industria que ayuda a imprimir sus registros en un formato mucho más significativo. Estos registros pueden contener muchas otras opciones asociadas con su único registro. Esta información puede contener y no se limita a:

  • La información de la solicitud HTTP, incluido el tipo de método y los parámetros de consulta.
  • El usuario conectado actual
  • El error de la base de datos y la marca de tiempo del servidor
  • El tipo de mensaje de error original e información adicional
  • La gravedad del registro

Seguir los pasos e implementar esta biblioteca elimina el menos poderoso console.log() (pero no impotente). Con esta configuración, es más fácil depurar los registros con más información adicional, también se puede usar junto con Prometheus y Grafana, que son herramientas de monitoreo del servidor.


Veamos la utilidad del Pino por el registro más simple que proporciona. Los registros son del tipo:

  • trace (rastro)
  • debug (depurar)
  • info (información)
  • warn (advertir)
  • error

Un fragmento para realizar los pasos:

const pino = require('pino');
log.info('This is info type log from pino');
log.warn('This is warn type log from pino');
log.error('This is error type log from pino');

// node pino-pretty.js

El código anterior resultará en:

Pino

Profundizando en Pino, supongamos que necesitamos una declaración de registro de la consola con los siguientes detalles:

 

formato JSON

Http req método, cuerpo, consulta, parámetros

detalles del usuario conectado actual

marca de tiempo del servidor y dirección IP

el nombre de la función donde se originó el error

el numero de linea

el nivel de registro

los detalles del error

 

Para construir la funcionalidad, necesitamos extender el uso y crear un registrador personalizado usando Pino. Creando un archivo “.js” logger.js con los siguientes contenidos:

const pino = require('pino');
const moment = require('moment');
const log = pino({});

log.customError = (error, details = '', LogLevel = process.env.LOG_LEVEL) => {
  // We can manage universal data using globals
  const req = global.reqInfo;
  // The error is parsed in a new Error(error: the error passed to this function)
  const e = new Error(error);
  // The error frame from origin error's stack
  const frame = e.stack.split('\n')[2];
  // the function where the error occured
  const functionName = frame.split(' ')[5];
  // The exact line number
  const lineNumber = frame.split(':').reverse()[1];
  // The final object to be logged in the console
  const errorInfo = {
    // If we have a request object then parse it otherwise it is null
    reqInfo: req
      ? {
          req: {
            req: req.method,
            path: req.path,
            body: req.body,
            query: req.query,
          },
          // If a req has a property with key user then extract relevant information otherwise return null
          user: req.user
            ? {
                id: req.user.id,
                name: req.user.name,
              }
            : null,
          // The server information at the moment of error handling
          server: {
            ip: req.ip,
            servertime: moment().format('YYYY-MM-DD HH:mm:ss'),
          },
        }
      : null,
    functionName,
    lineNumber,
    // Assuming that error is occured in application layer and not the database end.
    errorType: 'application error',
    stack: error.stack || e.stack,
    message: error.message || e.message,
    env: process.env.NODE_ENV,
    // defaults read from environment variable
    logLevel: LogLevel,
    process: details,
  };
  // Print appropriate level of log from [info, debug, warn, error]
  switch (LogLevel) {
    case 'info':
      log.info(errorInfo);
      break;
    case 'debug':
      log.debug(errorInfo);
      break;
    case 'warn':
      log.warn(errorInfo);
      break;
    case 'error':
      log.error(errorInfo);
      break;
    default:
      log.error(errorInfo);
  }
};

module.exports = {
  log,
};

He usado ampliamente los comentarios dentro del archivo, así que lo dejaré para su uso personal, comprensión e implementación. Los comentarios anteriores brindan toda la información que necesitará desde la perspectiva del código. El json que he construido para imprimir no se limita a la implementación anterior. Puede eliminar los valores innecesarios que no necesita para su uso personal.

Para usar el registrador anterior, actualicemos nuestro archivo principal desde donde podemos ver el registro real.

// To use the node environment and log level from env file.
require('dotenv').config();
const { log } = require('./logger');
// Function to test function name being printed out along with line number in the logs
const printMyError = () => {
  const error = new Error('A custom error is generated generated');
  log.customError(error, 'This was my custom message');
};
printMyError();

Pino

Los registros impresos tienen formato JSON y se pueden ver en línea en cualquier visor JSON (por el momento). En la visualización, da la siguiente imagen:

Pino

Como no usé los globales, el objeto req está vacío y no imprimió la información de HTTP, servidor y usuario. Esto se puede actualizar según las necesidades del proyecto. Para embellecer el registro, puede usar la biblioteca pino-pretty. Pero el inconveniente del enfoque es que deja de imprimir los registros en formato JSON. Todo lo que necesita para configurar pino-pretty es inicializar el registro con la siguiente configuración:

Este fue un ejemplo para configurar el mecanismo de registro básico y puede modificarse según los requisitos de su proyecto. Para tener una idea de cómo se ve un registro de aplicación de producción real, vea la siguiente imagen:

Pino

Todo lo que importa es la configuración que usa con el objeto de inicialización de Pino. Cuando ejecuta aplicaciones en varios entornos, como desarrollo/escenario/producción, también puede tener un escenario en el que desee utilizar pino-pretty en desarrollo y tener registros JSON en producción. Eso también depende del objeto de configuración donde puede tener una cláusula de prueba para verificar el entorno del nodo y luego aplicar los filtros apropiados. Para mantener este artículo corto y directo, me detendré aquí. Además, puede encontrar el código base del artículo aquí:

Otros enlaces útiles:


Y ahí lo tiene. Gracias por leer.

Recent Post