В практике фронтенд-инженеров на каждом шагу возникают ситуации, когда пользователи сообщают об аномальном выполнении функций. Для обнаружения проблем специалисты изо всех сил пытаются воспроизвести на месте эти аномалии, но результат оказывается нулевым. С другой стороны, операционная среда фронтенд-кода, такая как браузеры ПК, мобильные браузеры и пр., является сложной и неконтролируемой. Это означает, что в коде могут возникать различные непредсказуемые ошибки.

Для создания полноценной системы мониторинга фронтенд-исключений необходимо решить три первостепенные задачи.

  • Как вовремя перехватывать исключения?
  • Как определить точное местоположение исключений и ошибок?
  • Как своевременно уведомить персонал после обнаружения аномалии?

Выбор решения

Начнем с рассмотрения распространенных решений по фронтенд-мониторингу.

Вариант 1. Самостоятельное исследование

Специфика работы заключается в следующем.

  • Самостоятельно переписать методы onerror и onunhandledrejection в объекте Window.
  • Собрать информацию об ошибке.
  • Загрузить эту информацию через интерфейс сервера.
  • Написать файл сервера.
  • С помощью файла Sourcemap восстановить исходный код для устранения проблемы.

Кроме того, можно создать платформу для просмотра аномальной информации. Очевидно, что этот метод имеет массу недостатков и требует много усилий. Но есть у него и одно преимущество: его легко расширить, например добавив функции мониторинга производительности к фронтенд-мониторингу, что облегчит последующую оптимизацию производительности страниц.

Вариант 2. Использование сторонних инструментов, например Sentry

Этот метод не требует интенсивной разработки при достаточной конфигурации доступа.

Если у вас нет времени на проведение самостоятельного исследования, используйте сторонние инструменты.

Особого внимания среди них достоин Sentry. Этот инструмент отслеживания ошибок с открытым исходным кодом предлагает следующие возможности.

  • Помогает выявлять и исправлять системные ошибки в режиме реального времени.
  • Поддерживает восстановление стека вызовов JS-ошибок через файл Sourcemap.
  • Обладает функцией уведомления о завершении сбора исключений в режиме реального времени через Telegram и электронную почту.
  • Позволяет создавать приватные сервисы на серверах, что дает разработчикам возможность бесплатно использовать продвинутый функционал Sentry и избежать риска утечки исходного кода.
Это изображение визуально демонстрирует эффективность сбора аномальной информации Sentry

Как обеспечить своевременный захват исключений

Развертывание Sentry

В качестве первого шага необходимо развернуть Sentry. Поскольку Docker официально рекомендован для развертывания и относительно прост в эксплуатации, будем использовать его в качестве примера того, как создать сервис Sentry с нуля.

Сначала установим Docker и Docker-Compose. После завершения установки запустим Docker, извлечем код репозитория sentry-onpremise, который является официальной программой установки, предоставляемой Sentry, а затем запустим скрипт установки внутри. Он поможет создать аккаунт участника управления и запустить сервиса Sentry. Соответствующие команды отражены в этом коде:

git clone https://github.com/getsentry/onpremise
cd onpremise
./install.sh
$ docker-compose up -d

Когда процесс запуска будет успешно выполнен, нужно ввести http://ip:9000 в браузере, чтобы получить доступ к странице входа в систему Sentry. Это позволит войти в систему с только что созданными именем пользователя и паролем администратора.

Доступ к фронтенд-проекту

После выполнения вышеуказанных операций развертывание сервера Sentry полностью завершено. Теперь можно интегрировать клиентский SDK Sentry в приложение, чтобы сообщать в режиме реального времени об ошибках в коде фронтенда.

Sentry  —  продвинутый инструмент, поддерживающий различные фронтенд-фреймворки, такие как Vue, Angular, React и т. д. Vue  —  популярный фронтенд-фреймворк, отличающийся легковесностью, высокой производительностью и компонентностью. Поэтому возьмем проект Vue в качестве примера для подробного руководства.

Создание проекта

Сначала кликнем на первый пункт Projects в левой навигационной панели страницы Sentry. Затем нажмем Create Project button в правом верхнем углу страницы, выберем Vue под Browser и снова нажмем CreateProject, чтобы создать проект. После этого откроется пошаговое руководство по настройке проектов Vue, предоставленное Sentry.

Следование руководству

Сначала установим два пакета npm, от которых зависит Sentry в проекте, с помощьюnpm, а именно: @sentry/browser и @sentry/integrations. Затем импортируем их в main.js, после чего используем Sentry.init для инициализации и настройки Sentry. При настройке код инициализации будет предоставлен в руководстве  —  можно просто скопировать его и вставить в main.js. Наконец, нажмем кнопку подтверждения в нижней части руководства и автоматически перейдем на страницу проекта Issue error.

Обратите особое внимание на то, что DSN-адрес совпадает с проектом и не может быть изменен произвольно.

import * as Sentry from '@sentry/browser'
import { Vue as VueIntegration } from '@sentry/integrations'

Sentry.init({
  dsn: 'https://[email protected]/2',
  integrations: [new VueIntegration({
    Vue,
    attachProps: true
  })]
})

Проверка

Пока на странице Issue error видим только пустую форму без указания задачи, связанной с захватом исключений. Поэтому создадим отчет о JS-ошибках и посмотрим, как работает Sentry.

Сначала добавляем строку кода в созданный метод App.vue: this.test(), чтобы вызвать метод, которого нет в текущем компоненте, и принудительно сгенерировать JS-ошибку. Через сеть в Chrome DevTools видим, что при каждом обновлении страницы отправляется Post-запрос, связанный с Sentry. Это означает, что Sentry собирает аномальную информацию. Перейдя на страницу Issue error, обнаружим, что Sentry уже отобразил захваченное исключение:

Как известно, Sentry рассматривает каждое сообщение об исключении как событие (Event), а каждое событие имеет свою идентификационную метку (Fingerprint), которая по умолчанию генерируется алгоритмом группировки Sentry. События с одной и той же идентификационной меткой будут автоматически объединены в одну проблему (Issue). С соответствующей специфической логикой генерации можно ознакомиться в официальной документации.

Список проблем позволяет получить следующую информацию:

  • тип исключения;
  • имя исключения;
  • местоположение триггера;
  • время последнего триггера;
  • время первого триггера.

Нажмите, чтобы перейти на страницу Issue details (Сведения о проблеме). В средней части страницы можно увидеть конкретную информацию о последнем событии, включая следующие данные:

  • IP-адрес пользователя;
  • информация о браузере;
  • системная информация;
  • информация о стеке вызовов исключений.

Как определить точное местоположение обнаруженной ошибки

Итак, Sentry захватил информацию о стеке вызовов исключений. Однако, чтобы узнать, какая строка кода сообщает об ошибке, придется начать с глобального поиска ключевых слов (поскольку весь онлайн-код находится в сжатом и скрытом виде), а затем перейти к поиску их в соответствии с контекстом сжатого кода.

Так как же определить точное местоположение обнаруженной ошибки?

Для начала настроим в фоновом режиме Sentry AuthToken, который является необходимым параметром настройки выгрузки Sourcemap. Итак, создадим этот токен.

Нажимаем на Username (Имя пользователя) в левом верхнем углу страницы, а затем  —  на User Settings (Пользовательские настройки). После этого в меню выбираем пункт Auth Tokens, чтобы создать новый токен. Далее активируем конфигурацию Sourcemap, когда код будет собран и скомпилирован, а затем создаем новый файл .sentryclirc в корневом каталоге.

Наконец, скачиваем и устанавливаем в проект Webpack-плагин @sentry/webpack-plugin и добавляем конфигурацию выгрузки Sourcemap в Sentry в файл конфигурации упаковки.

Получить данную конфигурацию поможет приведенный ниже код:

[auth]
token=exxxxxxxxxxxx

[defaults]
project=xiaoan-web
org=sentry
url=https://sentry.xxxxx.com/
view raw

Атрибут Release соответствует версии кода. Вместе с аномальной информацией Sentry собирает и данные о версии кода пользователя. Это позволяет узнать, какой релиз вызвал новую проблему.

Следует отметить, что значение атрибута UrlPrefix не является фиксированным, а связано со статическим путем доступа к ресурсам проекта.

После завершения настройки Sentry может восстановить расположение кода на основе загруженного Sourcemap:

Как быстро уведомить персонал после получения исключения

Когда Sentry захватывает исключение, он должен уведомить об этом разработчиков в режиме реального времени. Для этого Sentry предоставляет функцию уведомления по электронной почте. Необходимо только добавить соответствующую конфигурацию в конфигурационный файл Sentry.

Поскольку не всегда есть возможность своевременно проверить электронную почту, можно также воспользоваться сторонним Telegram-плагином и получать сообщения в режиме реального времени.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи fatfish: How to Catch Frontend Exceptions with Sentry

Предыдущая статьяНовичкам на заметку: реализация шаблона Singleton в Ruby
Следующая статьяТипы операций обновления в MongoDB с использованием Spring Boot