console.log
Вывести содержимое на консоль. Если вы будете искать, как отлаживать JavaScript, вы найдете сотни блогов и статей StackOverflow, указывающих наconsole.log
. Поскольку это такой распространенный метод, мы даже начали использовать что-то вродеno-console
Такие правила линтера гарантируют, что мы не оставим неожиданных операторов журнала в производственном коде. Но что, если мы действительно хотим предоставить больше информации, напечатав что-нибудь?
В этой статье мы рассмотрим различные сценарии, в которых необходимо распечатать информацию в Node.js.console.log
а такжеconsole.error
В чем разница и как войти в библиотеку, не нарушая пользовательскую консоль.
console.log(`Let's go!`);
Первая теория: важные детали Node.js
Если мы можем использовать в браузере или Node.jsconsole.log
илиconsole.error
, то при работе с Node.js следует помнить об одной важной вещи. При написании следующего кода в Node.js в файле с именем index.js:
console.log('Hello there');
console.error('Bye bye');
и в терминальном использованииnode index.js
Выполните его, и вы увидите, что они выводятся рядом:
Однако, несмотря на то, что они выглядят одинаково, система обрабатывает их по-разному. ПроверитьДокументация Node.js о представлении консоли,Мы видим, что,console.log
вывод кstdout
,console.error
вывод вstderr
.
Каждый процесс имеет три потока, доступных по умолчанию:stdin
, stdout
а такжеstderr
.stdin
Поток обрабатывает ввод, поступающий в программу. Например, нажатия кнопок или перенаправление вывода (о чем мы поговорим позже).stdout
Потоки используются для вывода приложения. наконец,stderr
для сообщений об ошибках. Если вы хотите понять, почему он существуетstderr
и когда его использовать, см. этостатья.
Короче говоря, мы можем использовать перенаправление (>
) и трубы (|
) оператор разделяет ошибки приложения и результаты диагностической информации.>
оператор позволяет намstdout
перенаправить вывод в файл, а2>
позвольте намstderr
Вывод перенаправляется в файл. Например, эта команда импортирует "Hello there" в файл с именемHello.log
файл и импортировать "Bye Bye" в файл с именемerror.log
документ.
node index.js > hello.log 2> error.log
Когда нам нужен лог?
Теперь, когда мы немного знаем об основных технических аспектах ведения журнала, давайте обсудим сценарии, в которых может потребоваться ведение журнала. Обычно эти сценарии делятся на следующие категории:
- Быстрая отладка исключений во время разработки
- Ведение журнала в браузере для анализа или диагностики
- Журналы приложений службы регистрации для записи входящих запросов и любых сбоев, которые могли произойти.
- Дополнительные журналы отладки для библиотеки, чтобы помочь пользователям в устранении неполадок
- Печать хода выполнения, подтверждающих сообщений или ошибок через интерфейс командной строки
Ниже мы пропустим первые два сценария и сосредоточимся на последних трех сценариях, связанных с Node.js.
Журнал приложений службы
Причин регистрации на сервере может быть много. Например, регистрируя входящие запросы, мы можем использовать такую статистику, как количество запросов 404, с которыми столкнулся пользователь, какими могут быть эти запросы или что они используют.User-Agent
. Мы также хотим знать, когда что-то пошло не так и почему.
Если вы хотите попробовать следующий контент, создайте новый каталог проекта. Создать в каталоге проектаindex.js
Запись выполнения программы для написания кода. Запустите следующий код, чтобы инициализировать проект и установитьexpress
:
npm init -y
npm install express
Давайте настроим сервер с ПО промежуточного слоя console.log. Поместите следующее в файл index.js:
const express = require('express');
const PORT = process.env.PORT || 3000;
const app = express();
app.use((req, res, next) => {
console.log('%O', req);
next();
});
app.get('/', (req, res) => {
res.send('Hello World');
});
app.listen(PORT, () => {
console.log('Server running on port %d', PORT);
});
Мы используемconsole.log('$0',req)
Используется для записи всего объекта.console.log
нижнее использованиеutil.format
Поддержка метода%O
Заполнитель. Подробности можно найти наОфициальная документация Node.jsпонять в.
при исполненииnode index.js
Когда мы запустим сервер и посетим http://localhost:3000, вы заметите, что он распечатает много информации, которая нам на самом деле не нужна.
даже если мы изменим его наconsole.log('%s', req)
Вы не получите много полезной информации без печати всего объекта.
Мы можем написать собственную функцию журнала, которая выводит только то, что нас интересует. Но перед этим поговорим о том, что вообще волнует. Хотя слишком много информации отвлекает наше внимание, на самом деле нам нужно достаточно информации. Такие как:
- Временная метка - знать, когда что-то произошло
- имя компьютера/сервера - если вы используете распределенную систему
- Идентификатор процесса — если вы используете что-то вроде pm2 для запуска нескольких узловых процессов.
- message - фактическое сообщение с некоторым содержимым
- трассировка стека — используется для регистрации сценариев ошибок
- некоторые другие дополнительные переменные/информация
Кроме того, теперь, когда мы знаем, что все идет в потоки stdout и stderr, мы можем использовать их для реализации различных уровней логирования, а также возможности настраивать и фильтровать логи на их основе.
Мы могли бы сделать все это, обратившись к частям процесса и написав кучу JavaScript, но самое лучшее в Node.js — это то, что он имеет экосистему npm и уже есть различные библиотеки, доступные для использования. Например:
- pino
- winston
- roarr
- bunyan (примечание: это не обновлялось два года)
мне лично нравитсяpino
, потому что это быстро и экологически хорошо. Давайте посмотрим, как мы можем использовать pino, чтобы помочь нам с ведением журнала. Удивительно, что он уже естьexpress-pino-logger
package, мы можем использовать его для регистрации запросов.
Установитьpino
а такжеexpress-pino-logger
:
npm install pino express-pino-logger
затем обновитеindex.js
файл, используя регистратор и промежуточное ПО:
const express = require('express');
const pino = require('pino');
const expressPino = require('express-pino-logger');
const logger = pino({ level: process.env.LOG_LEVEL || 'info' });
const expressLogger = expressPino({ logger });
const PORT = process.env.PORT || 3000;
const app = express();
app.use(expressLogger);
app.get('/', (req, res) => {
logger.debug('Calling res.send');
res.send('Hello World');
});
app.listen(PORT, () => {
logger.info('Server running on port %d', PORT);
});
В этом фрагменте кода мы создаемpino
экземпляр регистратора и передать егоexpress-pino-logger
создать новое промежуточное программное обеспечение регистратора, чтобыapp.use
передача. Кроме того, при запуске службы мы используемlogger.info
заменятьconsole.log
, и добавил в маршрут дополнительнуюlogger.debug
, чтобы отобразить различные уровни журналов.
Если снова запуститьnode index.js
Запустите сервер. Вы увидите совсем другой вывод, один JSON в строке. Посетите http://localhost:3000 еще раз, и вы увидите добавленную новую строку JSON.
Если вы изучите этот JSON, вы увидите, что он содержит всю информацию, упомянутую ранее, например временные метки. Вы также можете заметить нашуlogger.debug
Заявления не печатаются. Это потому, что мы используем уровень журнала по умолчанию. При создании экземпляра регистратора мы устанавливаемprocess.env.LOG_LEVEL
Значение изменяет уровень журнала, по умолчаниюinfo
. запустивLOG_LEVEL=debug node index.js
, мы можем настроить уровень журнала для отображения журналов типа отладки.
Перед этим давайте обсудим тот факт, что теперь вывод на самом деле очень читабелен. Однако это намеренно. Пино следует принципу более высокой производительности. Мы также можем передать (используя|
) вынести логи всех процессов в отдельный процесс для улучшения его читабельности или выгрузки данных на облачный сервер. Этот процесс называетсяtransports. ПроверитьДокументация по транспорту, а также понять, почемуpino
Ошибка не была написанаstderr
.
давайте использовать инструментыpino-pretty
См. более удобочитаемую версию журнала. Выполните следующую команду в терминале:
npm install --save-dev pino-pretty
LOG_LEVEL=debug node index.js | ./node_modules/.bin/pino-pretty
Теперь используйте|
оператора, все журналы будут передаваться наpino-pretty
, ваш вывод должен быть четким, содержать ключевую информацию и быть цветным. Посетите http://localhost:3000 еще раз, и вы сможете увидетьdebug
сообщения уровня.
Существует множество готовых к использованию инструментов переноса, которые могут украшать или преобразовывать бревна. ты даже можешь использоватьpino-colada
инструмент для поддержки отображения смайликов. Они будут очень полезны для вашего местного развития. После запуска сервера в производственной среде вы можете захотеть импортировать журналы в другой транспорт, используя>
Записывайте журналы на диск, чтобы их можно было обработать позже, или используйтеtee
такие как команды.
официальная документацияТакже охватывает архивирование файлов журналов, фильтрацию и запись журналов в различные файлы.
журнал вашей библиотеки
Теперь, когда мы увидели, как эффективно писать журналы для серверных приложений, почему бы не использовать ту же технику для библиотеки, которую мы пишем?
Проблема в том, что мы хотим распечатать, что такое библиотека для отладки, но при этом не запутать приложение потребителя. Пользователи должны иметь возможность включить ведение журнала, если им нужно что-то отладить. Ваша библиотека должна по умолчанию быть тихой и предоставить пользователю право решать, печатать ли журналы.
express
хороший пример.express
Базовый уровень выполняет множество функций, и при отладке приложения вам может понадобиться знать, что происходит под капотом. Если мы посмотрим вверхexpress
документацию, вы заметите, что журналы, связанные с запуском, нужно добавить только перед командойDEBUG=express:*
:
DEBUG=express:* node index.js
Запустите команду с существующим приложением, и вы увидите много дополнительных выходных данных, которые помогут вам отладить проблему.
Если ведение журнала отладки не включено, вы их не увидите. Это делается черезdebug
пакет для достижения. Это позволяет нам писать сообщения в указанном «пространстве имен», которые будут выводиться, если потребитель библиотеки включает соответствующее пространство имен или подстановочный знак в переменную среды отладки.
Чтобы использовать библиотеку отладки, сначала установите ее:
npm install debug
Давайте попробуем, создав новый файл, который будет имитировать нашу библиотеку.random-id.js
, и поместите в него следующий код:
const debug = require('debug');
const log = debug('mylib:randomid');
log('Library loaded');
function getRandomId() {
log('Computing random ID');
const outcome = Math.random()
.toString(36)
.substr(2);
log('Random ID is "%s"', outcome);
return outcome;
}
module.exports = { getRandomId };
Приведенный выше код создает пространство имен какmylib:randomid
Новый экземпляр журнала отладки, который печатает два сообщения. Переходим к предыдущей главеindex.js
использовать его в:
const express = require('express');
const pino = require('pino');
const expressPino = require('express-pino-logger');
const randomId = require('./random-id');
const logger = pino({ level: process.env.LOG_LEVEL || 'info' });
const expressLogger = expressPino({ logger });
const PORT = process.env.PORT || 3000;
const app = express();
app.use(expressLogger);
app.get('/', (req, res) => {
logger.debug('Calling res.send');
const id = randomId.getRandomId();
res.send(`Hello World [${id}]`);
});
app.listen(PORT, () => {
logger.info('Server running on port %d', PORT);
});
Перезапустите сервер, но на этот раз с помощьюDEBUG=mylib:randomid node index.js
, который распечатает журнал отладки для нашей «библиотеки».
Интересно, если потребители вашей библиотеки захотят поместить эту отладочную информацию в своиpino
log, они могут использовать предоставленную команду pinopino-debug
библиотека для правильного форматирования этих журналов.
Установите библиотеку, используя:
npm install pino-debug
Прежде чем использовать отладку в первый раз, ее необходимо инициализировать.pino-debug
. Самый простой способ — использовать Node.js перед запуском скрипта.-r
или——require
логотипдля импорта модуля. Перезапустите сервер с помощью следующей команды (при условии, что он уже установленpino-colada
):
DEBUG=mylib:randomid node -r pino-debug index.js | ./node_modules/.bin/pino-colada
Теперь вы увидите журнал отладки для библиотеки в том же формате, что и журнал приложений.
Вывод CLI (интерфейс командной строки)
Последний случай, который мы обсудим в этом посте, — это специальный случай ведения журнала для CLI, а не для библиотек. Мой принцип состоит в том, чтобы отделить логический журнал от «журнала», выводимого CLI. Для любой логической регистрации следует использовать такую библиотеку, как отладка. Таким образом, вы или другие пользователи можете повторно использовать логику, не ограничиваясь конкретным вариантом использования CLI.
Когда ваше приложение Node.js создано с помощью интерфейса командной строки, вы можете сделать его более красивым, добавив цвет, разметку или отформатировав содержимое определенным визуально привлекательным способом. Однако есть несколько сценариев, о которых следует помнить при создании с помощью CLI.
Один из сценариев заключается в том, что ваш интерфейс командной строки может использоваться в контексте системы непрерывной интеграции (CI), поэтому вам может потребоваться удалить цвета или любой причудливый декоративный вывод. Некоторые системы CI устанавливают флаг среды под названием CI. Если вы хотите более безопасно проверить, находитесь ли вы в CI, вы можете использоватьis-CI
Такой пакет уже поддерживает многие системы CI.
некоторые библиотеки, такие какchalk
, уже определяет, подходит ли вам среда CI, и удаляет цвета за вас. Давайте посмотрим, как он выглядит после использования.
Установите мел с помощью npm и создайте файл с именемclip .js
документ. Вставьте следующий код:
const chalk = require('chalk');
console.log('%s Hi there',chalk.cyan('INFO'));
Теперь, если вы используетеnode clip.js
Запустите этот скрипт, и вы увидите цветной вывод.
Но если вы используетеCI=true node clip .js
Запустите его, и вы увидите, что цвета подавлены:
Другой сценарий, который вы должны иметь в виду, — это если ваш стандартный вывод работает в режиме терминала, то есть содержимое записывается на терминал. Если это так, мы можем использоватьboxenЧто-то вроде этого, чтобы отобразить весь красивый вывод. Если нет, скорее всего, вывод куда-то перенаправляется в файл или канал.
Вы можете сделать это, проверив соответствующий потокisTTYсвойства для проверкиstdin
,stdout
илиstderr
Будь то в терминальном режиме, например: process.stdout.isTTY. TTY означает «телетайп», что в данном случае относится конкретно к терминалу.
В зависимости от того, как был запущен процесс Node.js, значения для этих трех потоков могут различаться. ты сможешь«процесс ввода-вывода» из документации Node.jsраздел, чтобы узнать больше.
покажи намprocess.stdout
ценность .isTTY
В разных ситуациях по-разному. обновить свойclil.js
файл для проверки:
const chalk = require('chalk');
console.log (process.stdout.isTTY);
console.log('%s Hi there',chalk.cyan('INFO'));
Теперь запустите в своем терминалеnode clip.js
, вы увидите true, за которым следует наше цветное сообщение.
После этого запустите то же самое, но перенаправьте вывод в файл, и после проверки содержимого запустите:
node clip .js > output.log
cat output.log
Вы увидите, что на этот раз он печатает undefined, за которым следует сообщение сплошного цвета, потому что перенаправление stdout отключает режим терминала stdout.chalk
использовалsupport-color
Проверьте, поддерживается ли TTY в соответствующем потоке.
аналогичныйchalk
Такой инструмент уже обрабатывает этот сценарий за вас. Однако при разработке CLI всегда следует помнить о ситуациях, в которых CLI может работать в режиме CI или перенаправлять вывод. Это также поможет вам расширить свой опыт работы с CLI. Например, вы можете упорядочить данные в терминале удобным способом и переключиться на что-то более простое для анализа, если isTTY не определен.
Суммировать
Начать работу с JavaScript и зарегистрировать первую строку кода с помощью console.log довольно быстро, но когда вы запускаете свой код в производство, вам следует больше думать о журналировании. Этот пост просто описывает различные доступные методы и решения для ведения журнала. Но он не содержит всего, что вам нужно знать. Я предлагаю вам ознакомиться с некоторыми проектами с открытым исходным кодом, которые вас больше всего интересуют, чтобы увидеть, как они решают проблемы ведения журналов и какие инструменты они используют. Теперь запишите всю информацию, а не просто распечатывайте журнал 😉.
оригинал:A Guide to Node.js Logging