La primera tarea a la que se enfrentan con mayor frecuencia los desarrolladores que comienzan a programar en JavaScript es cómo registrar eventos en el registro de la 
console.log utilizando el método 
console.log . En la búsqueda de información sobre la depuración del código JavaScript, encontrará cientos de artículos de blog, así como instrucciones sobre StackOverflow, que le aconsejan que "simplemente" envíe datos a la consola a través del método 
console.log . Esta es una práctica tan común que tuve que introducir reglas para el control de calidad del código, como 
no-console , para no dejar entradas de registro aleatorias en el código de producción. Pero, ¿qué sucede si necesita registrar específicamente un evento para proporcionar información adicional?
Este artículo analiza varias situaciones en las que necesita mantener registros; Muestra la diferencia entre los métodos 
console.log y 
console.error en Node.js y muestra cómo pasar la función de registro a las bibliotecas sin sobrecargar la consola del usuario. 

Fundamentos teóricos de trabajar con Node.js
Los métodos 
console.log y 
console.error se pueden usar tanto en el navegador como en Node.js. Sin embargo, al usar Node.js, hay una cosa importante para recordar. Si crea el siguiente código en Node.js usando un archivo llamado 
index.js ,

y luego ejecutarlo en la terminal usando el 
node index.js , luego los resultados de la ejecución del comando se ubicarán uno encima del otro:

A pesar de que parecen similares, el sistema los procesa de manera diferente. Si mira la sección sobre el funcionamiento de la 
console en la 
documentación de Node.js , resulta que 
console.log imprime el resultado a través de 
stdout , y 
console.error imprime a través de 
stderr .
Cada proceso puede funcionar con tres flujos ( 
stream ) de forma predeterminada: 
stdin , 
stdout y 
stderr . La secuencia 
stdin procesa la entrada para un proceso, por ejemplo, clics de botón o salida redirigida (más sobre esto a continuación). El flujo de salida estándar 
stdout es para la salida de datos de la aplicación. Finalmente, el flujo de error estándar 
stderr está diseñado para mostrar mensajes de error. Si necesita averiguar para qué 
stderr y cuándo usarlo, lea 
este artículo .
En resumen, se puede usar para usar los operadores de redirección ( 
> ) y de canalización ( 
| ) para trabajar con errores e información de diagnóstico por separado de los resultados reales de la aplicación. Si el operador 
> permite redirigir la salida del resultado del comando a un archivo, entonces usando el operador 
2> puede redirigir la salida de la secuencia de error 
stderr a un archivo. Por ejemplo, este comando envía 
Hello al archivo 
hello.log y 
Bye bye al archivo 
error.log .


¿Cuándo necesito escribir eventos en el registro?
Ahora que hemos revisado los aspectos técnicos que subyacen en el registro, pasemos a varios escenarios en los que necesita registrar eventos. Por lo general, estos escenarios se dividen en una de varias categorías:
Este artículo solo trata los últimos tres escenarios basados en Node.js.
Registro para aplicaciones de servidor
Existen varios motivos para registrar eventos que ocurren en el servidor. Por ejemplo, el registro de solicitudes entrantes le permite obtener estadísticas sobre la frecuencia con la que los usuarios encuentran errores 404, cuál podría ser la razón de esto o qué aplicación de cliente de 
User-Agent se está utilizando. También puede averiguar la hora en que ocurrió el error y su causa.
Para experimentar con el material proporcionado en esta parte del artículo, debe crear un nuevo catálogo para el proyecto. En el directorio del proyecto, cree 
index.js para el código que se utilizará y ejecute los siguientes comandos para iniciar el proyecto e instalar 
express :

Configuramos un servidor con middleware, que registrará cada solicitud en la consola utilizando el método 
console.log . Ponemos las siguientes líneas en el archivo 
index.js :

Esto usa 
console.log('%O', req) para registrar todo el objeto en el registro. Desde el punto de vista de la estructura interna, el método 
util.forma usa 
util.forma t, que, además de 
%O admite otros marcadores de posición. Se puede encontrar información sobre ellos en la 
documentación de Node.js.Al ejecutar el 
node index.js para iniciar el servidor y cambiar a 
localhost : 3000, la consola muestra mucha información innecesaria:

Si en su lugar usa 
console.log('%s', req) para no mostrar el objeto por completo, no obtendrá mucha información:

Puede escribir su propia función de registro, que generará solo los datos necesarios, pero primero debe decidir qué información se necesita. A pesar de que el enfoque generalmente está en el contenido del mensaje, en realidad a menudo es necesario obtener información adicional, que incluye:
- marca de tiempo - para saber cuándo ocurrieron los eventos;
- nombre de la computadora / servidor: si se está ejecutando un sistema distribuido;
- identificador de proceso: si se ejecutan varios procesos de Nodo utilizando, por ejemplo, pm2;
- mensaje: un mensaje real con cierto contenido;
- seguimiento de pila: si se registra un error;
- Variables / información adicional.
Además, dado que, en cualquier caso, todo se envía a las secuencias 
stdout y 
stderr , es necesario mantener un diario en diferentes niveles, así como configurar y filtrar las entradas de diario según el nivel.
Esto se puede lograr obteniendo acceso a diferentes partes del 
process y escribiendo varias líneas de código en JavaScript. Sin embargo, Node.js es notable porque ya tiene un ecosistema 
npm y varias bibliotecas que se pueden usar para estos fines. Estos incluyen:
- pino
- winston;
- roarr
- bunyan (esta biblioteca no se ha actualizado durante dos años).
A menudo se prefiere el pino porque es rápido y tiene su propio ecosistema. Veamos cómo 
pino puede ayudar con el registro. Otra ventaja de esta biblioteca es el paquete 
express-pino-logger , que le permite registrar solicitudes.
Instale 
pino y 
express-pino-logger :

Después de eso, actualizamos el archivo 
index.js para usar el registrador de eventos y el middleware:

En este fragmento, creamos una instancia del 
logger eventos para 
pino y se lo pasamos a 
express-pino-logger para crear un nuevo software de registro de eventos multiplataforma con el que puede llamar a 
app.use . Además, 
console.log reemplazado en 
logger.info por 
logger.info y 
logger.debug agregado a la ruta para mostrar diferentes niveles del registro.
Si reinicia el servidor ejecutando repetidamente el 
node index.js , obtendrá un resultado diferente en la salida, en el que cada línea / línea se generará en formato JSON. Nuevamente, vaya a 
localhost : 3000 para ver otra nueva línea en formato JSON.

Entre los datos en formato JSON, puede encontrar la información mencionada anteriormente, como una marca de tiempo. También tenga en cuenta que el mensaje 
logger.debug no se mostró. Para hacerlo visible, debe cambiar el nivel de registro predeterminado. Después de crear una instancia del registro de eventos del registrador, se estableció el valor 
process.env.LOG_LEVEL . Esto significa que puede cambiar el valor o aceptar el valor de 
info predeterminado. 
LOG_LEVEL=debug node index.js ejecutar 
LOG_LEVEL=debug node index.js , cambiamos el nivel de registro.
Antes de hacer esto, es necesario resolver el problema del formato de salida, que no es muy conveniente para la percepción en este momento. Este paso es intencional. De acuerdo con la filosofía 
pino , por razones de rendimiento, es necesario transferir el procesamiento de entradas de diario a un proceso separado, pasando la salida (utilizando el operador 
| ). El proceso implica traducir el resultado a un formato más conveniente para la percepción humana, o subirlo a la nube. Esta tarea se realiza mediante herramientas de transferencia llamadas 
transports . Consulte la 
documentación del kit de herramientas de transports y vea por qué los errores de 
pino no se 
stderr través de 
stderr .
Para ver una versión más legible de la revista, use la herramienta 
pino-pretty . Ejecutar en la terminal:

Todas las entradas de registro se transfieren mediante 
| a disposición de 
pino-pretty , debido a que la salida se "borra", que contendrá solo información importante que se muestra en diferentes colores. Si consulta 
localhost : 3000 nuevamente, debería aparecer un mensaje de 
debug depuración.

Para hacer que las entradas del diario sean más legibles o convertirlas, existen muchas herramientas de transmisión. Incluso se pueden mostrar usando emojis con 
pino-colada . Estas herramientas serán útiles para el desarrollo local. Cuando el servidor está en producción, puede ser necesario transferir datos de registro usando 
otra herramienta , escribirlos en el disco usando 
> para su posterior procesamiento, o hacer dos operaciones al mismo tiempo usando un comando específico, por ejemplo 
tee .
El 
documento también habla sobre la rotación de archivos de registro, el filtrado y la escritura de datos de registro en otros archivos.
Diario de la biblioteca
Al explorar formas de organizar eficientemente el registro para las aplicaciones del servidor, puede usar la misma tecnología para sus propias bibliotecas.
El problema es que, en el caso de la biblioteca, es posible que deba mantener un registro con fines de depuración sin cargar la aplicación cliente. Por el contrario, el cliente debería poder activar el registro si es necesario depurarlo. De manera predeterminada, la biblioteca no debe registrar la salida, lo que le otorga al usuario este derecho.
Un buen ejemplo de esto es el marco 
express . Muchos procesos tienen lugar en la estructura interna del marco 
express , lo que puede causar interés en estudiarlo más profundamente durante la depuración de la aplicación. La 
documentación del marco express dice que puede agregar 
DEBUG=express:* al comienzo del comando de la siguiente manera:

Si aplica este comando a una aplicación existente, puede ver una gran cantidad de resultados adicionales que ayudarán con la depuración:

Esta información no se puede ver a menos que el registro de depuración esté activado. Hay un paquete de 
debug para esto. Se puede usar para escribir mensajes en el "espacio de nombres", y si el usuario de la biblioteca incluye este espacio de nombres o un comodín que coincida con su 
variable de entorno DEBUG , se mostrarán los mensajes. Primero necesita instalar la biblioteca de 
debug :

Cree un nuevo archivo llamado 
random-id.j s que simule la biblioteca y coloque el siguiente código:

Como resultado, se creará un nuevo registrador de eventos de 
debug con el 
mylib:randomid , en el que se registrarán dos mensajes. Lo usamos en 
index.js de la sección anterior:

Si inicia el servidor nuevamente, agregando 
DEBUG=mylib:randomid node index.js esta vez, se mostrarán las entradas del registro de depuración para nuestra "biblioteca":

Si los usuarios de la biblioteca desean poner información de depuración en las entradas de registro de 
pino , pueden usar una biblioteca llamada 
pino-debug creada por el comando 
pino para formatear estas entradas correctamente.
Instala la biblioteca:

Antes de usar la 
debug por primera vez, se debe inicializar 
pino-debug . La forma más fácil de hacer esto es usar los 
indicadores -r o --require para solicitar un módulo antes de ejecutar el script. Reiniciamos el servidor usando el comando (siempre que 
pino-colada instalado 
pino-colada ):

Como resultado, las entradas del registro de depuración de la biblioteca aparecerán igual que en el registro de la aplicación:

Salida de la interfaz de línea de comando (CLI)
El último caso que trata este artículo es el registro de la interfaz de línea de comandos. Preferiblemente, el registro que registra eventos relacionados con la lógica del programa se mantiene separado del registro para registrar datos de la interfaz de línea de comandos. Para registrar cualquier evento relacionado con la lógica del programa, debe usar una biblioteca específica, por ejemplo, 
debug . En este caso, puede reutilizar la lógica del programa sin limitarse a un escenario utilizando la interfaz de línea de comandos.
Al crear una interfaz de línea de comando usando Node.js , puede agregar varios colores, bloques de valores variables o herramientas de formato para darle a la interfaz un aspecto visualmente atractivo. Sin embargo, debe tener en cuenta varios escenarios.
Según uno de ellos, la interfaz se puede utilizar en el contexto de un sistema de integración continua (CI), en cuyo caso es mejor abandonar el formato de color y la presentación de resultados visualmente sobrecargada. Algunos sistemas de integración continua tienen establecido el indicador 
CI . Puede verificar que está en un sistema de integración continua utilizando el paquete 
is-ci , que admite varios de estos sistemas.
Algunas bibliotecas, como la 
chalk , definen sistemas de integración continua y anulan la salida de texto en color a la consola. Veamos como funciona.
Instale 
chalk con el comando npm 
install chalk y cree un archivo llamado 
cli.js Ponga las siguientes líneas en el archivo:

Ahora, si ejecuta este script usando el 
node cli.js , los resultados se presentarán con diferentes colores:

Pero si ejecuta el script usando 
CI=true node cli.js , el formato de color de los textos se cancelará:

En otro escenario que vale la pena recordar, 
stdout ejecuta en modo terminal, es decir los datos se envían al terminal. En este caso, los resultados se pueden mostrar muy bien con 
boxen . De lo contrario, lo más probable es que la salida se redirija a un archivo o a otro lugar.
Puede comprobar el funcionamiento de las secuencias 
stdin , 
stdout o 
stderr en modo terminal mirando el atributo 
isTTY de la secuencia correspondiente. Por ejemplo, 
process.stdout.isTTY . 
TTY significa "teletipo" y en este caso está diseñado específicamente para el terminal.
Los valores pueden variar para cada uno de los tres subprocesos, dependiendo de cómo se iniciaron los procesos Node.js. Se puede encontrar información detallada sobre esto en la 
documentación de Node.js, en la sección "Entrada / salida de procesos" .
Veamos cómo el valor de 
process.stdout.isTTY varía en diferentes situaciones. 
cli.js archivo 
cli.js para verificarlo:

Ahora ejecute el 
node cli.js en el terminal y vea la palabra 
true , después de lo cual el mensaje se muestra en letra de color:

Después de eso, volvemos a ejecutar el comando, pero redirigimos la salida a un archivo y luego vemos el contenido:

Esta vez, la palabra 
undefined apareció en la terminal, seguida de un mensaje que se muestra en una fuente incolora, ya que la secuencia 
stdout redirigió fuera del modo terminal. Aquí la 
chalk utiliza la herramienta de 
supports-color , que desde el punto de vista de la estructura interna verifica el 
isTTY secuencia correspondiente.

Las herramientas como la 
chalk hacen estas cosas por su cuenta. Sin embargo, al desarrollar una interfaz de línea de comandos, siempre debe estar atento a las situaciones en las que la interfaz funciona en un sistema de integración continua o la salida se redirige. Estas herramientas lo ayudan a usar la interfaz de línea de comandos en un nivel superior. Por ejemplo, los datos en el terminal se pueden organizar de una manera más estructurada, y si 
isTTY undefined está 
undefined , cambie a una forma más simple de análisis.
Conclusión
Comenzar a usar JavaScript e ingresar la primera línea en el registro de la consola usando 
console.log bastante simple. Pero antes de implementar el código en producción, debe considerar varios aspectos del uso del registro. Este artículo es solo una introducción a los diversos métodos y soluciones utilizados en la organización del registro de eventos. No contiene todo lo que necesita saber. Por lo tanto, se recomienda prestar atención a los proyectos exitosos de código abierto y monitorear cómo resolvieron el problema de registro y qué herramientas se utilizan. Y ahora intente iniciar sesión sin generar datos en la consola.
Si conoce otras herramientas que vale la pena mencionar, escríbalas en los comentarios.