Защита исходных карт и улучшение отладки веб-приложений в производственной среде
Сегодня мой день начался с электронного письма с отчетом об исключении, исходящим от интерфейса 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 предоставляет пользователю возможность предоставить дополнительную обратную связь в случае ошибки, которая может быть использована службой поддержки, чтобы связаться с клиентом.
Конец объявления.
Что еще я упустил в мире отчетов об ошибках, мониторинга и профилирования веб-приложений?