спецификация журнала nodejs
Как правило, студенты, изучающие фронтенд-разработку, не очень чувствительны к логам, ведь в большинстве случаев фронтенд мало заботится о логах. Даже если есть, он может вызвать какую-то стороннюю статистику, например статистику Baidu или другие. существуетNode.js
(именуемый в дальнейшемnode
) В процессе продвижения мы также обнаружили, что мы обычно регистрируем слишком небрежно, журналы, которые должны быть зарегистрированы, не регистрируются, а в некоторых ключевых журналах, которые регистрируются, отсутствует необходимая контекстная информация, что затрудняет обнаружение проблем в Интернете.
В этой статье в основном разбираются проблемы, существующие в журнале нашей команды при разработке nodejs, и какой эффект мы надеемся достичь, унифицируя спецификацию журнала.
вопрос
- Журнал узла не стандартизирован, и журнал слишком произвольный
- Нет хорошего формата журнала, согласованных полей, в
ELK
не может быть хорошо проанализирован и извлечен (PS:ELK
Статья в пути) - Из-за внутренней службы стыковки узла цепочка вызовов не ясна, и локализовать проблему сложно.
- Нет четких записей об использовании журналов узлов отделом данных. Node изменяет журнал, что приводит к ненормальной статистике
Цель
- Поля и форматы печати журнала Canonical для удобства
ELK
забрать - Усовершенствованный формат журнала восходящего и нисходящего потоков узлов (nginx/backend), добавление уникальных
requestId
, что удобно для локализации проблем в микросервисах - Статистика работы приложения и данные производительности
- Поддерживать использование журналов узла отделом данных
План реализации
тип журнала
Ссылаясь на некоторые рекомендации по ведению журналов, журналы узлов в настоящее время делятся на следующие типы (scope
):
-
desc
: Во время запуска и работы системы отображаются журналы с указанием некоторых журналов запуска, параметров запуска и т. д. системы, включая журналы, отображаемые, когда контекст http не может быть захвачен. -
stat
: журнал статистики производительности системы, приложение будет периодически собирать некоторую информацию о производительности, что удобно для запроса текущего состояния приложения. -
visit
: журнал, относящийся к каждому HTTP-запросу, будет содержать уникальный идентификатор запроса, чтобы найти все журналы, связанные с запросом. -
biz
: журналы, связанные с бизнес-данными, в основном для использования в статистике данных.
уровень журнала
использовать толькоFATAL
,ERROR
,WARN
,INFO
а такжеDEBUG
оценка.
- FATAL — серьезная ошибка системного уровня, вызвавшая выход из программы, неисправимая, при возникновении ошибки системный администратор должен вмешаться немедленно, общий код приложенияНе делайтеиспользовать.
- ERROR - исключения во время выполнения и непредвиденные ошибки, с которыми также нужно бороться немедленно, но они менее срочные, чем FATAL.При возникновении ошибок они влияют на правильное выполнение программы. Следует отметить, что эти два уровня относятся к собственным ошибкам сервиса и требуют вмешательства администратора.Ошибки пользовательского ввода не попадают в эту категорию, запросить бэкэнд, чтение файла, база данных и т. Д. Тайм-аут, обратную структуру ошибки, принадлежат к ошибке
- ПРЕДУПРЕЖДЕНИЕ. Непредвиденное состояние выполнения, указывающее на возможную проблему в системе. Для тех ситуаций, которые не являются ошибками в настоящее время, но станут ошибками, если их вовремя не устранить, они также могут быть записаны как ПРЕДУПРЕЖДЕНИЕ, например, на диске слишком мало места.
- INFO — значимая информация о событии, фиксирующая нормальное рабочее состояние программы, например, получение запроса и его успешное выполнение. Просматривая ИНФОРМАЦИЯ, вы можете быстро найти ПРЕДУПРЕЖДЕНИЕ, ОШИБКУ и ФАТАЛЬНУЮ ошибку. INFO не должно быть слишком много, обычно не более 10% от DEBUG.
- DEBUG — Подробная информация о ходе выполнения программы и текущем состоянии переменных.
формат/поля журнала
Единый формат журналаJSON,легкоELK
Обработка разбора.
Значение каждого поля в логе должно использоваться максимальноанглийский, не используйте китайский язык.
Конкретные поля журнала разделены на основные данные + расширенные данные. Базовые данные поставляются с базовой структурой журналов, и все журналы будут включены. Расширенные данные, разные типы журналов, содержат разные поля.
данные базы журнала
в настоящее время используетсяnode-bunyan
библиотека журналов,официальная документация, базовые поля содержат следующее:
- v: целое число. номер версии журнала bunyan
- уровень: целый. Число, соответствующее уровню журнала
- имя: строка. наименование услуги
- имя хоста: строка. Имя процессора
- идентификатор: целое число. Идентификатор процесса
- время: строка.UTCдата в формате
- сообщение: строка. информация о теле журнала
регистрировать расширенные данные
Расширенные данные для каждого типа данных, определенного ниже,нетВсе поля, включая только обязательные поля для этого типа журнала. Эти обязательные поля расширения должны бытьELK
Создайте индекс, чтобы облегчить поиск различных проблем.
-
desc
Введите журнал, расширенное поле: TODO -
stat
Введите журнал, расширенные поля:{ perf: {rss: xxxx, cpu: xxx} }
-
visit
Введите журнал, расширенные поля: biz
{
///////////// 基础数据 ////////
v: 1,
level: 20,
///////////// 扩展字段 ////////
// 标志日志类型
scope: "visit",
//事件类型:在 visit 的日志类型下,还会细分不同的事件,比如 client-req、client-res、 普通trace、请求后端service-start, service-end, service-err等。
event: "trace",
//客户端ID,追踪用户、设备会话。在web端,可以是长期的cookie;在APP端,可以是device-id等
rrdid: "",
//本次请求的惟一ID,串联本次请求的所有相关日志
req_id: "some-uuid-for-request",
//本次请求的用户ID
uid: "",
//本次请求的客户端相关数据,通过 ctx.logger 打日志时,自动加上
d: {
url: "/some/path?include-query",
//客户端ip
ip: "10.138.10.1",
//客户端的 userAgent
ua: ""
},
//本次node请求的处理时间,毫秒
tm: 500,
//该日志相关的上下文数据,尽量拼成一个字符串,放在 extra 里
extra: "",
//ERROR 级别日志,最好包含error相关信息,比如请求后端相关参数等
err: {
msg: "",
stack: ""
},
//调用后端服务相关参数和响应
service_req: {
host: "",
path: "",
payload: ""
},
service_res: {
//http状态码
http_code: 200,
//响应时间
tm: 100,
//响应的body
body: "",
//异常信息
err: ""
}
}
когда войти
В настоящее время разработчики заботятся только оvisit
Тип журнала, то есть журнал, связанный с определенным http-запросом.desc
а такжеstat
Типы логов, унифицированные фреймворком разработки после инкапсуляции, развитие бизнесаНе нужноУход. Следующее дляvisit
тип журнала.
HTTP-запрос выводит серию связанных журналов. На уровне узла запрос обычно перенаправляется на N внутренних служб, затем выполняются некоторые операции, такие как обработка и слияние внутренних данных, и, наконец, отображается страница или выводится JSON. Поэтому логи, связанные с запросом, можно условно разделить на следующие типыevent
:
-
client-req
: клиентский запрос поступает на уровень узла, а платформа унифицирована для регистрации и разработки.Не делайтеуход -
service-start
: Node инициирует запрос к серверной службе, а общая библиотека запросов отвечает за регистрацию и разработкуНе делайтеуход -
service-end
: Узел запрашивает завершение серверной службы, а общая библиотека запросов отвечает за регистрацию и разработку.Не делайтеуход -
service-err
: Бэкенд-сервис запроса ноды работает ненормально, а общая библиотека запросов отвечает за регистрацию и разработкуНе делайтеУход. Серверная служба вызывается ненормально, а уровень журналаWARN
,нетERROR
-
trace
: журнал бизнес-уровня в узле, если он ненормальный, может помочь найти проблему, связанную с этим запросом. -
client-res
: Завершить запрос клиента, вывести http-код этого запроса, время обработки этого запроса и т. д., которые единообразно типизированы и разработаны фреймворком.Не делайтеуход
Разработчики должны тщательно выбирать уровень при регистрации.INFO
(Включительно) выше уровня, должны быть в состоянии иметь требования для определения проблем и конкретных потребностей бизнес-статистики, прежде чем их можно будет использовать. В большинстве случаев можно использоватьDEBUG
уровень, онлайнНе будетвключиDEBUG
уровень.
вызов конкретного метода
для печатиvisit
введите журнал, позвонитеctx.logger
(на основеKoa
Атрибут framework) в лог, передаются рекомендуемые параметрыJSON
, конкретный метод заключается в следующем:
ctx.logger.debug({msg: "", "extra": "a=1 b=2 c=value"});
ctx.logger.info({msg: "xxx", "extra": "其他的额外字段"});
ctx.logger.warn({msg: "xxx", "extra": "额外上下文数据"});
//ERROR级别日志,应该提供 Error 对象
ctx.logger.error({msg: 'xxx', err: error, extra: ""});
Примечание 1, дополнительные параметры рекомендуются хранить вextra
В поле единое написаниеstring
; если действительно необходимо выделить каждое поле,запретитьДополнительные параметры занимают указанные выше общие имена полей! !
Примечание 2, в основных данныхmsg
поле,запретитьСодержит определенные контекстные данные, а контекстные данные, относящиеся к журналу, должны быть записаны в виде строки и помещены в отдельныйextra
в поле. Например, если пользователь входит в интерфейс и хочет подсчитать количество вызовов, это можно распечатать так:
ctx.logger.info({msg: "user login", "extra": 'mobile=18712387101 code=xxxx k3=value3'});
использованная литература
- Лучшие методы ведения журналов (v2.0)
- Node framework доступ к сводке практики ELK
- Нормализация журнала Dasouche NodeJS и мониторинг анализа
- Пожалуйста, проверьте сами! Сколько из этих хороших методов ведения журнала вы достигли?
- Лучшие практики ведения журналов
- When to use the different log levels
- Лучшие практики управления журналами Java
- Несколько предложений и не лучших практик для печати журнала
- Лучшие практики для ведения журнала