Node.js console.log - Ist es möglich, eine Zeile zu aktualisieren, anstatt eine neue Zeile zu erstellen?


80

Meine node.jsAnwendung verfügt über viele Konsolenprotokolle, die für mich wichtig sind (es ist eine ziemlich große App, läuft also lange und ich muss wissen, dass die Dinge noch im Gange sind), aber am Ende habe ich Tausende von Zeilen Konsolenprotokolle.

Ist es irgendwie möglich, console.updateeine Konsolenzeile zu löschen / zu ersetzen, anstatt eine neue Leitung zu erstellen?


1
Warum nicht in eine Protokolldatei schreiben, die Sie überwachen oder durchsuchen können?
Nelson

1
Ich kann das in PowerShell leicht genug tun, aber es ist mehr so, dass ungefähr 5.000 Zeilen Konsole geschrieben werden, die leicht 10 Zeilen aufnehmen können (das meiste davon sind nur Anrufe, die mich wissen lassen, dass die Dinge voranschreiten, was wichtig ist Die App läuft ungefähr 20 Minuten und ich brauche Feedback, ob die Dinge kaputt gehen / noch laufen.
JVG

Antworten:


123

Versuchen Sie stattdessen, mit process.stdout-Methoden auf der Konsole zu spielen:

process.stdout.write("Hello, World");
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write("\n"); // end the line

10
TypeError: process.stdout.clearLine ist keine Funktion. Kann nicht im Webstorm ausgeführt werden, wenn jemand anderes darauf stößt.
Trevor

@ TrevorD Mein Ansatz dazu war es, webstorm=truein Application Parameter in der Webstorm-Knotenkonfiguration hinzuzufügen und zu überprüfen, ob process.argv.find(x => x.startsWith('webstorm=true')diese Antwort verwendet wird
Luiz Eduardo

1
@Luiz Eduardo Wäre es nicht einfacher, sich einfach einzuwickeln if (process.stdout.clearLine) { process.stdout.clearLine() }?
Trevor

Guter Fang! Aus irgendeinem Grund habe ich nicht einmal daran gedacht. Da ich ein kleines einfaches Tool für die Ausführung in der Konsole erstellt habe, habe ich es zwar nicht gründlich behandelt, aber ich werde es definitiv ändern, danke!
Luiz Eduardo

Ich würde dies tun: node -e "for(let i=1;i<=1000;i++){process.stdout.write('Hello, World'); if(i<10)process.stdout.clearLine(); process.stdout.cursorTo(0);}"odernode -e "for(let i=1;i<=1000;i++){process.stdout.clearLine(); process.stdout.cursorTo(0); process.stdout.write('hello, world')}"
Cerberus

54

Nach der Antwort von @ michelek können Sie eine Funktion wie diese verwenden:

function printProgress(progress){
    process.stdout.clearLine();
    process.stdout.cursorTo(0);
    process.stdout.write(progress + '%');
}

1
Wenn Sie dies mit einer for-Schleife verwenden, flackert es. Gibt es eine Möglichkeit, dies zu beheben?
Ank i zle

1
Um das Flimmern zu beheben, process.stdout.clearLine()
entfernen Sie

Ich erkannte, dass das Hinzufügen zu einer großen Schleife die Berechnungszeit drastisch erhöht. Zum Beispiel führe ich 100mil zufällige Versuche aus und weise Variablen zu. Es sollte 3 Sekunden dauern. mit dieser Funktion. es dauert wie eine Minute
Mj Jameel

Vergiss meinen obigen Kommentar. Ich denke, alle Konsolenprotokolle kosten viel. und da ich versuchte, einen Fortschritt prozentual zu drucken, musste ich eine Funktion schreiben, die nur in bestimmten Intervallen wie 1% 2% usw.
druckt

19

Natürlich können Sie dies mit einem Modul tun, das ich erstellt habe: fknsrs / jetty

Installieren über

npm install jetty

Hier ist ein Anwendungsbeispiel

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

Anlegestelle ist nicht besonders nützlich, wenn sie alleine verwendet wird. Es ist viel effektiver, wenn Sie eine Abstraktion darauf aufbauen, um Ihre Anlegestellen weniger ausführlich zu gestalten.


3
Ich habe dies wegen der restriktiven Lizenz für dieses Paket abgelehnt.
mmmeff

15
Es ist ein Standard- BSD-3-Klausel-Lizenz . Ziemlich schlechter Grund für eine Ablehnung, imo.
Danke

6
@mmmeff, wenn Sie der Meinung sind, dass eine BSD 3-Klausel-Lizenz restriktiv ist, werden Sie wahrscheinlich sterben, wenn Sie von GPL- und AGPL-Lizenzen erfahren.
Michael Pfaff

14

Eine Teilzeile schreiben.

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

Wenn das Ausgabevolumen das eigentliche Problem ist, müssen Sie wahrscheinlich Ihre Protokollierung überdenken. Sie können ein Protokollierungssystem verwenden, das eine selektive Laufzeitprotokollierung ermöglicht, um Ihre Ausgabe auf das zu beschränken, was Sie benötigen.

// 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

6

Verwenden Sie einfach \ r, um Ihre Leitung zu beenden:

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

Hier ist ein einfaches Beispiel (Wanduhr):

setInterval(() => process.stdout.write(`clock: ${new Date()}\r`), 1000);

Dies funktioniert, aber wenn die 'geänderte' Zeile kürzer als die vorherige Zeile ist, bleiben einige der alten Zeichen im Terminal erhalten.
Matthijn

5

Wenn Sie Standardausnahmen wie TypeError: process.stdout.clearLine is not a functionim Debug Console-Fenster von Visual Studio Code (oder Webstorm) sehen, führen Sie die App als externe Terminalanwendung anstelle der internen Konsole aus. Der Grund ist, dass das Debug Console-Fenster nicht TTY ist ( process.stdout.isTTYfalsch ist). Aktualisieren Sie daher Ihre Startkonfiguration launch.jsonmit der "console": "externalTerminal"Option.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.