В Superface мы используем платформу NestJS для серверной части и AppSignal APM для мониторинга и отслеживания ошибок. Хотя AppSignal обеспечивает интеграцию с Node.js, его запуск и работа с NestJS оказались довольно сложными.

В этом сообщении блога я расскажу, как нам удалось заставить AppSignal работать с NestJS.

Фрагменты кода, использованные в этом сообщении блога, являются частью нашего пример проекта.

Инициализация и настройка AppSignal

AppSignal использует автоматическое инструментирование, которое прикрепляет хуки к инструментам и платформам Node.js (Express, Koa, PostgreSQL, Redis и т. д.) и отслеживает вызовы определенных функций. После вызова функций инструментарий автоматически собирает диапазоны трассировки от имени вашего приложения.

У AppSignal есть следующие требования (взятые из документов AppSignal), чтобы автоинструмент работал:

Для автоматической настройки модулей модуль Appsignal должен быть обязательным и инициализированным перед любым другим пакетом.

Стандартный способ создания экземпляров объектов в NestJS — использование контейнера внедрения зависимостей (DI).

Чтобы выполнить требование, мы не можем использовать NestJS DI Container для создания экземпляра AppSignal. AppSignal должен быть создан как глобальная переменная, что также означает, что мы не можем использовать преимущества NestJS ConfigModule.

Пример создания и настройки AppSignal с использованием переменных среды:

Вам также необходимо зарегистрировать промежуточное ПО AppSignal при инициализации Express в загрузочном коде приложения NestJS:

Вот и все, как только вы установите переменную среды APPSIGNAL_PUSH_API_KEY в действительный ключ AppSignal и настроите переменные среды APPSIGNAL_NAME, APPSIGNAL_ACTIVE, AppSignal начнет собирать метрики из всех HTTP-запросов, обрабатываемых вашим приложением.

Отслеживание ошибок

Nest поставляется со встроенным уровнем исключений, который отвечает за обработку всех необработанных исключений в приложении. Подробнее см. в разделе Nest Документация по фильтрам исключений.

Чтобы отслеживать ошибки, обрабатываемые фильтрами исключений Nest, мы создали AppsignalExceptionFilter, который реализует интерфейс Nest ExceptionFilter.

AppsignalExceptionFilter отслеживает HttpException исключения с кодом состояния 5xx и любые другие типы исключений.

Вы можете использовать AppsignalExceptionFilter, расширив его в собственной реализации фильтра исключений и зарегистрировав свой фильтр исключений в приложении Nest.

Пример расширения AppsignalExceptionFilter:

Пример регистрации глобального фильтра:

Мониторинг @nestjs/bull процессов

Помимо NestJS мы также используем Bull для обработки фоновых заданий. NestJS предоставляет пакет @nestjs/bull в качестве оболочки для Bull.

AppSignal не отслеживает вакансии Bull автоматически. К счастью, мы можем использовать Пользовательские инструменты Appsignal, чтобы справиться с трассировкой самостоятельно.

Для отслеживания заданий Bull мы создали декоратор процессов Bull ProcessMonitor:

Декоратор метода ProcessMonitor создает новый спан в пространстве имен worker, собирает идентификатор задания, устанавливает спан с ошибкой в ​​случае возникновения исключения.

Как только вы добавите декоратор ProcessMonitor в свою кодовую базу, начните использовать его, украсив метод обработчика очереди Bull:

Изящная остановка AppSignal

По умолчанию @appsignal/nodejs запускает минутные проверки, которые отслеживают статистику кучи Node.js V8. Эта функция дает вам представление о внутреннем устройстве Node.js.

К сожалению, при включенных ежеминутных проверках вы должны явно остановить проверки, вызвав метод stop. В противном случае процесс вашего приложения не будет остановлен изящно.

Nest поставляется с onApplicationShutdown событием жизненного цикла, которое является подходящим местом для вызова метода остановки AppSignal. См. пример реализации AppsignalShutdownService ниже:

Не забудьте добавить AppsignalShutdownService в модуль приложения Nest.

Первоначально опубликовано на https://superface.ai 20 мая 2022 г.