Защита исходных карт и улучшение отладки веб-приложений в производственной среде

Сегодня мой день начался с электронного письма с отчетом об исключении, исходящим от интерфейса GO2CINEMA:

Электронное письмо создается sentry.io и включает дополнительную информацию, такую ​​как URL-адрес запроса, IP-адрес пользователя, информацию о браузере, время запроса и т. Д.

Отказ от ответственности: когда я думаю о том, что я собираюсь написать дальше, это все больше и больше начинает звучать как реклама sentry.io. У меня нет другого аффилированного лица с sentry.io, кроме того, что я их клиент.

К сожалению, трассировка стека сама ссылается на минимизированный код. Это связано с тем, что ошибка произошла в производственной среде, где код минимизирован, а исходные карты не были опубликованы из-за соображений IP. Ничего необычного.

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

На этот раз все было иначе. Я не мог воспроизвести проблему, и у меня не было настроения проходить непонятную трассировку стека. Несомненно, должен быть способ получше.

Что ж, есть.

Обеспечение доступа к исходным картам

Самое простое решение - загрузить исходные карты в продакшн и ограничить доступ с помощью аутентификации по токену, например.

app.get(/\.js\.map/, (req, res, next) => {
  if (req.headers['x-source-map-access-token'] !== 'secret-value') {
    res
      .status(401)
      .send('Authentication access token is required to access the source map.');
return;
  }
next();
});

По крайней мере, теперь, если вы столкнетесь с ошибкой в ​​производственной среде, вы можете вставить требуемый заголовок в запрос вашего браузера и проанализировать трассировку стека ошибок в производственной среде.

Это хорошо, но не решает проблему сообщения об ошибках.

Остальная часть статьи специфична для sentry.io.

Предоставление исходных карт сервису Sentry.io

Sentry.io - это агент / служба отслеживания ошибок с открытым исходным кодом, работающая как на сервере, так и в браузере. Я использую sentry.io для всех ключевых сервисов Node.js - он выполняет свою работу. Совсем недавно я включил его на сайте GO2CINEMA. Однако, когда я начал получать сообщения об ошибках во внешнем интерфейсе, отсутствие исходных карт стало большой проблемой. Оказывается, часовой об этом подумал.

Sentry.io документирует два способа поделиться исходными картами с агентом. Во-первых, это то, что я уже представил - использование заголовка x-sentry-token для предоставления доступа только агенту sentry.io. Оно работает. Однако есть даже лучший способ - вы можете загрузить исходные карты на sentry.io в вашем конвейере CI / CD. Это то, что я выбрал. Я просто генерирую RELEASE_ID, который передается образу докера и используется для инициализации клиента Raven.

# The CD pipeline generates a RELEASE_ID
- apt-get update -y && apt-get install -y python-pip && pip install python-ulid && export RELEASE_ID=$(python -c 'from ulid import ULID; print ULID.new().str')
- docker build --cache-from $CONTAINER_IMAGE:latest --build-arg RELEASE_ID=$RELEASE_ID -t $CONTAINER_IMAGE:$BUILD_TAG -t $CONTAINER_IMAGE:latest .
# Which is then picked up in the Dockerfile
ARG RELEASE_ID
ENV RELEASE_ID $RELEASE_ID
# Which is then picked up by the web app
import Raven from 'raven-js';
Raven.config(DSN, {
  release: process.env.RELEASE_ID
});

В качестве последнего шага в CI / CD вам необходимо использовать инструмент sentry-cli, чтобы загрузить исходные файлы с исходной картой и связать их с идентификатором выпуска.

Теперь каждый раз, когда Raven записывает ошибку, эта ошибка связана с идентификатором выпуска, и вы получаете четкий отчет об ошибке.

Это заставило меня задуматься - что еще я упускаю.

Использование Sentry.io в полной мере с интеграцией React, Redux и redux-saga

Нет ничего особенного в сервисе Sentry.io для React, Redux или redux-saga. Однако Sentry.io предоставляет четкую документацию по интеграции с React. Тем не менее, концепция хлебных крошек в Sentry.io - замечательный компаньон, если вы используете Redux.

Видите ли, каждое действие Redux фактически является цепочкой навигации, и существует созданное сообществом промежуточное программное обеспечение (raven-for-redux), которое регистрирует последние действия и включает их в каждый отчет об ошибках в качестве цепочки навигации. На практике это позволяет воссоздать точное состояние приложения до возникновения ошибки.

Помните ту предыдущую ошибку списка? Я не мог найти его происхождение до тех пор, пока не активировал сборку хлебных крошек. С панировочными сухарями - это было легко.

Я не только знаю каждое действие до ошибки, я знаю, с каким пользователем взаимодействовал непосредственно перед тем, как ошибка произошла.

В следующий раз, когда пользователь купит билет в кино и возникнет ошибка, у меня будет четкое представление о том, как он дошел до этой точки. Да, и как будто этого было недостаточно - sentry.io предоставляет пользователю возможность предоставить дополнительную обратную связь в случае ошибки, которая может быть использована службой поддержки, чтобы связаться с клиентом.

Конец объявления.

Что еще я упустил в мире отчетов об ошибках, мониторинга и профилирования веб-приложений?