KillWolfVlad

Как мы прокачали логирование в Node.js

Абстракция с надписью 'Новый npm пакет для логирования' и кубом 'Node Pino Logger Factory'

OpenSource кубики Byndyusoft™ пополнились библиотекой pino-logger-factory для настройки nestjs-pino, который мы используем для логирования. В честь этого события хотим предложить вам небольшое объяснение конфигурации по умолчанию на примере эволюции одного лога.

12 Factor учит нас тому, что логи должны быть в JSON формате и выводиться в stdout приложения:

json
{
  "level": "info",
  "time": "1970-01-01T00:00:00.000Z",
  "msg": "Hello World!"
}

В этом логе мы понимаем что произошло и когда, но нам катастрофически не хватает доп. информации о самом сервисе:

  • pid и hostname процесса
  • Имя сервиса, его версия и окружение в котором он запущен
  • Идентификатор места в программе, где была сделана запись в лог
json
{
  "level": "info",
  "time": "1970-01-01T00:00:00.000Z",
  "pid": 6986,
  "hostname": "host",
  "name": "service",
  "version": "1.2.3",
  "env": "prod",
  "context": "HelloWorldController",
  "msg": "Hello World!"
}

Если будет несколько логов в рамках одного запроса, то их нужно связать общим контекстом:

  • ID запроса
  • ID трассировки (например Jaeger)
json
{
  "level": "info",
  "time": "1970-01-01T00:00:00.000Z",
  "pid": 6986,
  "hostname": "host",
  "name": "service",
  "version": "1.2.3",
  "env": "prod",
  "context": "HelloWorldController",
  "req": {
    "id": 1
  },
  "traceId": "e977d97bd554314",
  "msg": "Hello World!"
}

Одинаковых логов может быть очень много, поэтому нам важно уметь их отличать:

  • По хешу шаблона сообщения
  • По хешу ошибки
json
{
  "level": "error",
  "time": "1970-01-01T00:00:00.000Z",
  "pid": 6986,
  "hostname": "host",
  "name": "service",
  "version": "1.2.3",
  "env": "prod",
  "context": "HelloWorldController",
  "req": {
    "id": 1
  },
  "traceId": "e977d97bd554314",
  "err": {
    "type": "Error",
    "message": "World doesn't exists",
    "stack": "Error: World doesn't exists"
  },
  "errHash": "72fe1bd7",
  "msgTemplateHash": "8569c34",
  "msg": "Hello World!"
}

В заключении для большей уверенности в том, что сейчас работает нужная версия приложения можно логировать информацию из CI/CD:

  • Ветка и/или тег
  • Короткий хеш коммита
  • Номер сборки
json
{
  "level": "info",
  "time": "1970-01-01T00:00:00.000Z",
  "pid": 6986,
  "hostname": "host",
  "name": "service",
  "version": "1.2.3",
  "env": "prod",
  "branch": "master",
  "tag": "v1.2.3",
  "commit": "e8da669",
  "buildId": "10",
  "context": "HelloWorldController",
  "req": {
    "id": 1
  },
  "traceId": "e977d97bd554314",
  "msgTemplateHash": "dc09357d",
  "msg": "Hello World!"
}

Следите за новыми репозиториями и обновлениями текущих на нашем https://github.com/Byndyusoft.