Node.js console.log - можно ли обновить строку, а не создать новую?

83

В моем node.jsприложении много консольных журналов, которые мне важно видеть (это довольно большое приложение, поэтому оно работает долго, и мне нужно знать, что все еще продолжается), но в итоге у меня появляются тысячи строк журналы консоли.

Возможно ли как-то сделать, console.updateчто стирает / заменяет строку консоли, а не создает новую строку?

JVG
источник
1
Почему бы не записать в файл журнала, который можно отслеживать или искать?
Нельсон
1
Я могу сделать это достаточно легко в PowerShell, но более того, у меня написано около 5000 строк консоли, которые могут легко занять 10 строк (большинство из них - это просто вызовы, которые сообщают мне, что дела идут, что важно, поскольку приложение работает около 20 минут, и мне нужна обратная связь о том, работает ли что-то или все еще работает).
JVG
Отвечает ли это на ваш вопрос? Как стереть символы, напечатанные в консоли
Wex

Ответы:

127

Попробуйте вместо этого поиграть с методами process.stdout на консоли:

process.stdout.write("Hello, World");
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write("\n"); // end the line
Михелек
источник
10
TypeError: process.stdout.clearLine не является функцией. Невозможно запустить в webstorm, если кто-то еще столкнется с этим.
Trevor
@TrevorD, мой подход к этому заключался в добавлении webstorm=trueпараметров приложения в конфигурацию узла webstorm и проверке process.argv.find(x => x.startsWith('webstorm=true')использования этого ответа
Луис Эдуардо,
1
@Luiz Eduardo Не было бы проще просто закончить if (process.stdout.clearLine) { process.stdout.clearLine() }?
Trevor
Хороший улов! Почему-то я об этом даже не подумал. Поскольку я создавал небольшой простой инструмент для запуска в консоли, я не вдавался в подробности, но я обязательно его изменю, спасибо!
Луис Эдуардо
Я бы сделал это: node -e "for(let i=1;i<=1000;i++){process.stdout.write('Hello, World'); if(i<10)process.stdout.clearLine(); process.stdout.cursorTo(0);}"илиnode -e "for(let i=1;i<=1000;i++){process.stdout.clearLine(); process.stdout.cursorTo(0); process.stdout.write('hello, world')}"
Цербер
55

Следуя ответу @ michelek, вы можете использовать примерно такую ​​функцию:

function printProgress(progress){
    process.stdout.clearLine();
    process.stdout.cursorTo(0);
    process.stdout.write(progress + '%');
}
Бруно Перес
источник
1
При использовании этого с циклом for он мигает, есть ли способ исправить это?
Ank i zle
1
исправить мерцание, избавиться отprocess.stdout.clearLine()
decoder7283
Я понял, что добавление этого к большому циклу резко увеличивает время вычислений. Например, я выполняю 100 миллионов случайных попыток и присваиваю переменные. Это должно занять 3 секунды. с этой функцией. это займет минуту
Mj Jameel
не обращайте внимания на мой вышеупомянутый комментарий. Я думаю, что все журналы консоли стоят очень дорого. и поскольку я пытался распечатать прогресс в процентах, мне пришлось написать функцию, которая печатает только с определенными интервалами, например 1% 2% и т. д.
Mj Jameel
21

Конечно, вы можете сделать это с помощью модуля, который я помог создать: fknsrs / jetty

Установить через

npm install jetty

Вот пример использования

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

Сама пристань не очень полезна. Гораздо эффективнее, если вы создадите поверх него некоторую абстракцию, чтобы сделать ваши вызовы на причале менее подробными.

Спасибо
источник
3
Я отказался от этого из-за ограничительной лицензии на этот пакет.
mmmeff
17
Это стандартная лицензия BSD с тремя пунктами . Довольно плохая причина для голосования против, имо.
Спасибо
6
@mmmeff, если вы считаете, что лицензия BSD с тремя пунктами является ограничительной, я боюсь, что вы умрете, когда услышите о лицензиях GPL и AGPL.
Майкл Пфафф
15

Чтобы написать частичную строку.

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

Если объем вывода является реальной проблемой, вам, вероятно, придется переосмыслить ведение журнала. Вы можете использовать систему регистрации, которая позволяет выборочное ведение журнала во время выполнения, чтобы сузить вывод до того, что вам нужно.

// 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
SpliFF
источник
6

Просто используйте \ r для завершения вашей строки:

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

Вот простой пример (настенные часы):

setInterval(() => process.stdout.write(`clock: ${new Date()}\r`), 1000);
Барт Титен
источник
Это работает, но если «измененная» строка короче предыдущей, некоторые старые символы в терминале сохранятся.
Matthijn
5

если вы видите исключения stdout, например, TypeError: process.stdout.clearLine is not a functionв окне консоли отладки кода Visual Studio (или Webstorm), запустите приложение как приложение внешнего терминала, а не внутреннюю консоль. Причина в том, что окно консоли отладки не является TTY ( process.stdout.isTTYневерно). Поэтому обновите конфигурацию запуска launch.jsonс помощью "console": "externalTerminal"option.

Максим Шамигулау
источник