- Оригинальный адрес:A Guide to Node.js Logging
- Оригинальный автор:dkundel
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:fireairforce
Когда вы начинаете работать с JavaScript, первое, чему вы должны научиться, — это передаватьconsole.log()
Записывать вещи в консоль. Если вы ищете, как отлаживатьJavaScript
, вы найдете сотни сообщений в блогах и статей о StackOverflow, которые расскажут вам об очень «простом» использованииconsole.log()
для завершения отладки. Поскольку это такая распространенная практика, мы даже начали использоватьlinter
правила, такие какno-console
, чтобы гарантировать, что мы не оставим непредвиденные записи в производственном коде. Но что, если мы действительно хотим записать что-то, чтобы предоставить больше информации?
В этом сообщении блога я расскажу о некоторых различных ситуациях, когда вы хотите регистрировать информацию, и о том, как это сделать в Node.js.console.log
иconsole.error
и как отправить журнал в библиотеку, не затрагивая консоль пользователя.
console.log(`Let's go!`);
Сначала теория: важные детали Node.js
Хотя вы можете использовать в браузере и Node.jsconsole.log
илиconsole.error
, но при работе с Node.js следует помнить одну важную вещь. в названномindex.js
файл напишите следующий код:
console.log('Hello there');
console.error('Bye bye');
а затем использовать в терминалеnode index.js
чтобы запустить его, вы увидите эти два вывода непосредственно ниже:
Однако, хотя они могут выглядеть одинаково, система на самом деле обрабатывает их по-разному. если ты пойдешь проверишьВ документации Node.jsconsole
часть,ты увидишьconsole.log
это использоватьstdout
печататьconsole.error
использоватьstderr
печатать.
Каждый процесс может использовать три значения по умолчанию.streams
приходить на работу. они соответственноstdin
,stdout
иstderr
.stdin
Потоки для обработки вывода, связанного с вашим процессом. Например, нажатие кнопки или перенаправление вывода (мы сделаем это через секунду).stdout
Потоки используются для вывода вашего приложения. Наконецstderr
для сообщений об ошибках. Если вы хотите знатьstderr
почему он существует и когда его использовать,Вы можете просмотреть эту статью.
Короче говоря, это позволяет нам использовать перенаправление(>
) и труба (|
) для обработки ошибок и диагностической информации отдельно от фактических результатов приложения. Несмотря на то что>
позволяет нам перенаправить вывод команды в файл,2>
позвольте намstderr
Вывод перенаправляется в файл. Например, следующая команда передаст «Привет!»hello.log
файл и передать «До свидания» файлу с именем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('%O', req)
записать весь объект.console.log
Использование под капотомutil.format
, который также поддерживает%O
и другие заполнители. ты сможешьПрочтите их в документации Node.js.
когда ты бежишьnode index.js
Запустите сервер и перейдите кhttp://localhost:3000, вы заметите, что он выведет много информации, которая нам на самом деле не нужна.
Если вы измените код наconsole.log('%s', req)
Мы также не получим много информации без вывода всего объекта.
Мы могли бы написать собственную функцию печати, которая просто выводила бы то, что нас интересует, но давайте сделаем шаг назад и обсудим то, что нас обычно волнует. Хотя эта информация часто находится в центре нашего внимания, на самом деле нам может понадобиться другая информация. Например:
- Временная метка - раньше знала, когда что-то произошло
- имя компьютера/сервера - если вы используете распределенную систему
- Идентификатор процесса - если вы используете что-то вроде
pm2
инструмент для запуска нескольких процессов Node. - message - фактическое сообщение с некоторым содержимым
- трассировка стека - на случай, если мы зарегистрируем ошибку
- возможно, некоторые дополнительные переменные/информация
Кроме того, поскольку мы знаем, что все идет кstdout
иstderr
, то нам могут понадобиться разные уровни логов и возможность настраивать и фильтровать логи на их основе.
Мы можем получить доступ к различным разделамprocess
и написать целую кучу кода JavaScript, чтобы получить это, но самое лучшее в Node.js то, что мы получаемnpm
экосистемы, и в нашем распоряжении уже есть множество библиотек. Некоторые из них:
лично мне нравится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
создалlogger
экземпляр и передать егоexpress-pino-logger
для создания нового промежуточного программного обеспечения и передачиapp.use
назвать это. Кроме того, где мы запускаем сервер сlogger.info
заменитьconsole.log
, и добавим строку к нашему маршрутуlogger.debug
для отображения дополнительного уровня журнала.
если прошлоnode index.js
Запустите сервер перезапуска еще раз, и вы увидите совершенно другой вывод, который печатает JSON для каждой строки. Перейдите снова кhttp://localhost:3000, вы увидите еще одну добавленную строку JSON.
Если вы изучите этот JSON, вы увидите, что он содержит всю ранее упомянутую информацию, например временные метки. Вы также можете заметить нашуlogger.debug
Заявление не печатается. Это потому, что нам пришлось изменить уровень журнала по умолчанию, чтобы сделать его видимым. когда мы создаемlogger
например, мы устанавливаем значениеprocess.env.LOG_LEVEL
означает, что мы можем изменить значение через него или принять значение по умолчаниюinfo
. мы можем бежатьLOG_LEVEL=debug node index.js
для настройки уровня журнала.
Прежде чем мы это сделаем, давайте проясним тот факт, что вывод прямо сейчас не очень читаем. Это сделано намеренно.pino
Следуя философии, для повышения производительности вы должны передавать (используя|
) вывод перемещает любую обработку журнала в отдельный процесс. Это включает в себя создание его для чтения или загрузку на облачный хост. мы называем это传输
. Проверятьо传输
документацияпонять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
пакет для завершения. Это позволяет нам писать сообщения в «пространствах имен», если пользователь библиотеки включает пространство имен или в егоDEBUG
переменная средыподстановочные знаки, соответствующие ему в , он выведет их. использовать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
изdebug
Затем регистратор зарегистрирует оба сообщения. Тогда мы в предыдущем разделе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
журналы, они могут использоватьpino
Команда под названиемpino-debug
библиотека для правильного форматирования этих журналов.
Используйте следующую команду для установки этой библиотеки:
npm install pino-debug
pino-debug
Его нужно инициализировать один раз, прежде чем мы используем его в первый раз.debug
. Проще всего использовать перед запуском скриптаNode.js-r
или--require
идентификатордля инициализации. Используйте следующую команду, чтобы перезапустить сервер (при условии, что вы установилиpino-colada
):
DEBUG=mylib:randomid node -r pino-debug index.js | ./node_modules/.bin/pino-colada
Теперь вы можете просматривать журнал отладки библиотеки в том же формате, что и журнал приложения.
ваш вывод CLI
Последний случай, который я рассмотрю в этом сообщении блога, — это частный случай ведения журнала для CLI, а не для библиотеки. Моя философия состоит в том, чтобы отделить логические журналы от выходных «журналов» CLI. Для любого логического журнала вы должны использовать что-то вродеdebug
библиотека. Это позволяет вам или другим лицам повторно использовать логику, не привязываясь к конкретному варианту использования CLI.
Когда вы создаете CLI с Node.js, вы можете сделать так, чтобы все выглядело красиво, добавив цвет, счетчики или отформатировав содержимое особым визуально привлекательным способом. Однако есть несколько ситуаций, которые следует учитывать при построении CLI.
Одним из случаев является то, что ваш CLI может использоваться в контексте системы непрерывного наследования (CI), поэтому вы можете захотеть удалить цвета или любой причудливый декоративный вывод. Некоторые системы CI устанавливают флаг среды под названием «CI». Если вы хотите безопаснее проверить, находитесь ли вы в CI, вы можете использовать пакет, который уже поддерживает несколько систем CI, например.is-ci
.
Некоторые библиотеки, такие какchalk
CI был обнаружен для вас и удалены цвета для вас. Давайте посмотрим, как это выглядит.
использоватьnpm install chalk
установитьchalk
, и создайтеcli.js
документ. Поместите в него следующее:
const chalk = require('chalk');
console.log('%s Hi there', chalk.cyan('INFO'));
Теперь, если вы используетеnode cli.js
Запустите этот скрипт, и вы увидите соответствующий цветной вывод.
но ты используешьCI=true node cli.js
чтобы запустить его, вы увидите, что цвета удалены:
Другой сценарий, который вы должны помнить, этоstdout
Может работать в терминальном режиме. Означает запись содержимого в терминал. Если это так, мы можем использовать что-то вродеboxen
что-то, чтобы отобразить весь красивый вывод. В противном случае выходные данные могут быть перенаправлены в файл или переданы в другое место.
Ты можешь проверитьisTTY
соответствующие свойства потока для проверкиstdin
,stdout
илиstderr
Находится в терминальном режиме. Например:process.stdout.isTTY
, в этом случае используется специально для терминалов,TTY
Расшифровывается как «телетайп».
В зависимости от того, как был запущен процесс Node.js, значение для каждого из трех потоков может быть разным. ты сможешьРаздел «Процесс ввода-вывода» документации Node.jsУзнайте больше об этом.
покажи намprocess.stdout.isTTY
Изменение стоимости в различных ситуациях. обновить свойcli.js
файл для проверки:
const chalk = require('chalk');
console.log(process.stdout.isTTY);
console.log('%s Hi there', chalk.cyan('INFO'));
затем используйтеnode cli.js
запустите в своем терминале, вы увидитеtrue
За ним последует наше красочное сообщение после печати.
После этого запустите то же самое, но перенаправьте вывод в файл, затем проверьте содержимое, запустив:
node cli.js > output.log
cat output.log
На этот раз вы увидите, что он напечатаетundefined
За ним следует простое бесцветное сообщение. так какstdout
режим закрытого терминалаstdout
перенаправление. так какchalk
использовалsupports-color
, так что под капотом проверки наisTTY
.
Однако, какchalk
Такие инструменты уже обрабатывают это поведение за вас, и при разработке CLI вы всегда должны знать о ситуациях, когда ваш CLI может работать в режиме CI или вывод перенаправляется. Это также может помочь вам сделать шаг вперед в работе с CLI. Например, вы можете красиво упорядочить данные в терминале, еслиisTTY
даundefined
Если это так, переключитесь на более простой способ разбора.
Суммировать
Начните с JavaScript и используйтеconsole.log
Регистрация вашей первой строки выполняется быстро, но вам следует больше думать о регистрации, когда вы запускаете свой код в производство. В этой статье описываются только различные доступные методы и решения для ведения журналов. Он не содержит всего, что вам нужно знать. Я предлагаю вам проверить некоторые из ваших любимых проектов с открытым исходным кодом, чтобы увидеть, как они решают проблемы ведения журналов и инструменты, которые они используют. Иди записывай все сейчас, не распечатывай свой журнал 😉
Если вы знаете или найдете какие-либо инструменты, которые я должен упомянуть явно, или если у вас есть какие-либо вопросы, пожалуйста, не стесняйтесь обращаться ко мне. Я не могу дождаться, чтобы увидеть, что вы делаете.
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.