Node.js console.log: ¿es posible actualizar una línea en lugar de crear una nueva?

83

Mi node.jsaplicación tiene muchos registros de consola, que es importante para mí ver (es una aplicación bastante grande, por lo que se ejecuta durante mucho tiempo y necesito saber que las cosas aún están progresando) pero estoy terminando con miles de líneas de registros de la consola.

¿Es posible de alguna manera hacer algo console.updateque borre / reemplace una línea de consola en lugar de crear una nueva línea?

JVG
fuente
1
¿Por qué no escribir en un archivo de registro que pueda supervisar o buscar?
Nelson
1
Puedo hacerlo con bastante facilidad en PowerShell, pero es más que tengo alrededor de 5,000 líneas de consola escritas que fácilmente podrían ocupar 10 líneas (la mayoría son solo llamadas que me permiten saber que las cosas están progresando, lo cual es importante ya que el La aplicación se ejecuta durante unos 20 minutos y necesito comentarios sobre si las cosas se están interrumpiendo o aún funcionan).
JVG
¿Responde esto a tu pregunta? Cómo borrar caracteres impresos en la consola
Wex

Respuestas:

127

Intente jugar con los métodos process.stdout en su lugar en la consola:

process.stdout.write("Hello, World");
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write("\n"); // end the line
michelek
fuente
10
TypeError: process.stdout.clearLine no es una función. No se puede ejecutar en webstorm si alguien más encuentra esto.
Trevor
@TrevorD, mi enfoque para esto fue agregar un webstorm=trueen los parámetros de la aplicación en la configuración del nodo webstorm y verificar el process.argv.find(x => x.startsWith('webstorm=true')uso de esta respuesta
Luiz Eduardo
1
@Luiz Eduardo ¿No sería más sencillo simplemente terminar if (process.stdout.clearLine) { process.stdout.clearLine() }?
Trevor
¡Buena atrapada! Por alguna razón, ni siquiera pensé en eso. Como estaba construyendo una pequeña herramienta simple para ejecutar en la consola, no le di un detalle, pero definitivamente la cambiaré, ¡gracias!
Luiz Eduardo
Yo haría esto: node -e "for(let i=1;i<=1000;i++){process.stdout.write('Hello, World'); if(i<10)process.stdout.clearLine(); process.stdout.cursorTo(0);}"onode -e "for(let i=1;i<=1000;i++){process.stdout.clearLine(); process.stdout.cursorTo(0); process.stdout.write('hello, world')}"
Cerberus
55

Siguiendo la respuesta de @ michelek, puede usar una función como esta:

function printProgress(progress){
    process.stdout.clearLine();
    process.stdout.cursorTo(0);
    process.stdout.write(progress + '%');
}
Bruno Peres
fuente
1
Cuando se usa con un bucle for, parpadea, ¿hay alguna forma de solucionarlo?
Ank i zle
1
para corregir el parpadeo, deshacerse deprocess.stdout.clearLine()
decoder7283
Me di cuenta de que agregar esto a un ciclo grande aumenta el tiempo de cálculo drásticamente aaaa. Por ejemplo, estoy ejecutando 100 mil intentos aleatorios y asignando variables. Debería tomar 3 segundos. con esta función. toma como un minuto
Mj Jameel
no importa mi comentario anterior. Supongo que todos los registros de la consola cuestan mucho. y como estaba tratando de imprimir un progreso por porcentaje, tuve que escribir una función que solo imprime en ciertos intervalos como 1% 2%, etc.
Mj Jameel
21

Claro, puedes hacer esto usando un módulo que ayudé a crear: fknsrs / jetty

Instalar a través de

npm install jetty

Aquí hay un ejemplo de uso

// Yeah, Jetty!
var Jetty = require("jetty");

// Create a new Jetty object. This is a through stream with some additional
// methods on it. Additionally, connect it to process.stdout
var jetty = new Jetty(process.stdout);

// Clear the screen
jetty.clear();

// write something
jetty.text("hello world");
jetty.moveTo([0,0]);
jetty.text("hello panda");

Jetty no es muy útil cuando se usa solo. Es mucho más efectivo cuando construyes algo de abstracción encima para hacer que tus llamadas al embarcadero sean menos detalladas.

Gracias
fuente
3
He votado en contra de esto debido a la licencia restrictiva de este paquete.
mmmeff
17
Es un licsense estándar BSD de 3 cláusulas . Bastante mala razón para un voto negativo, en mi opinión.
Gracias
6
@mmmeff, si cree que una licencia BSD de 3 cláusulas es restrictiva, me temo que morirá cuando se entere de las licencias GPL y AGPL.
Michael Pfaff
15

Escribir una línea parcial.

process.stdout.write("text");
process.stdout.write("more");
process.stdout.write("\n"); // end the line

Si el volumen de salida es el problema real, probablemente reconsidere su registro. Puede utilizar un sistema de registro que permita el registro en tiempo de ejecución selectivo para limitar su salida a lo que necesita.

// The sections we want to log and the minimum level
var LOG_LEVEL = 4;
var LOG_SECTIONS = ["section1","section2","section3"];

function logit(msg, section, level) {
  if (LOG_SECTIONS.indexOf(section) > -1 && LOG_LEVEL >= level) {
    console.log(section + ":" + msg);
  }
}

logit("message 1", "section1", 4); // will log
logit("message 2", "section2", 4); // will log
logit("message 3", "section3", 2); // wont log, below log level
logit("message 4", "section4", 4); // wont log, not in a log section
Empalme
fuente
6

Simplemente use \ r para terminar su línea:

process.stdout.write('text\r');

Aquí hay un ejemplo simple (reloj de pared):

setInterval(() => process.stdout.write(`clock: ${new Date()}\r`), 1000);
Bart Theeten
fuente
Esto funciona, pero si la línea 'cambiada' es más corta que la línea anterior, mantendrá algunos de los caracteres antiguos en la terminal.
Matthijn
5

Si ve excepciones de stdout como TypeError: process.stdout.clearLine is not a functionen la ventana Debug Console de Visual Studio Code (o Webstorm), ejecute la aplicación como una aplicación de terminal externa en lugar de una consola interna. La razón es que la ventana de la consola de depuración no es TTY ( process.stdout.isTTYes falsa). Por lo tanto, actualice su configuración de lanzamiento launch.jsoncon la "console": "externalTerminal"opción.

Maksim Shamihulau
fuente