Дави жуков

c0713574bf539cc2ceb54f26c0647f45.jpg

Существует много курсов программирования и повышения IT-квалификации, но ни на одном из них не учат системно искать и исправлять ошибки. В реальных крупных проектах до 30% времени может уходить не на написание нового кода и фич, а на поиск первопричин неисправностей и их устранения. Именно недочёты и ошибки будут мешать вашему клиенту составить положительное впечатление о продукте, а в некоторых случаях они полностью блокируют процесс. Кроме того, инженер, который только пишет новый код и не решает ошибки, не получает архитектурный опыт и не расширяет кругозор, что приводит к появлению новых недочётов в проектах. Я опишу наш инструментарий для исправления ошибок в веб-приложениях и поделюсь опытом.

Причины возникновения ошибок

3a9edf3acb2e412eb8f403e3395420f6.png

Субъективно я выделяю три причины появления багов:

  • Архитектурная. Плохо спроектированная архитектура может привести к ошибкам в понимании процессов, некорректному взаимодействию компонентов или потере производительности. Кроме того, из-за недостатка знаний о проекте или опыта, а также при неправильном понимании бизнес-требований программист может не учесть все нюансы, и именно они станут первопричиной неявных ошибок.

  • Человеческий фактор. Причин для ошибок может быть великое множество — от неудачных названий переменных, которые при изменении кода будут неправильно поняты и использованы, до случайных опечаток при использовании сохранённых данных.

  • Изменение внешних факторов. Нередко возникает ситуация, когда система проектировалась под одни требования, а потом стала использоваться в новых условиях (пример: одна из самых дорогостоящих компьютерных ошибок в мире — авария ракеты‑носителя «Ариан 5»). Даже в давно работающих системах могут возникать неожиданные ошибки, когда какая-нибудь из смежных систем после обновления стала присылать данные в изменённом формате.

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

Просмотр логов

2e05c822404cb49d68a8221dfcd0521c.png

К сожалению, не во всех компаниях разработчики имеет доступ к логам в production и вынуждены их запрашивать у службы сопровождения. Для поиска неисправности может понадобиться просмотреть как сетевые логи (nginx или других маршрутизаторов), так и логи самих веб-приложений.

Какие логи обязательно должны быть у приложения:

  • Логи ошибок и непредвиденных ситуаций (log.error). Ошибки должны сопровождаться трассировкой стека вызовов функции (traceback).

  • Логи с предупреждениями (log.warning) о нестандартном поведении какой-либо функции. Они оставляются разработчиками и помогают внимательнее отнестись к записанным данным при разборе ошибок.

  • Логи информационного характера (log.info).

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

Для поиска ошибок в логах необходимо в голове сформулировать проблемную ситуацию и последовательными запросами к системе вывода логов пройти пошагово процесс, в котором могла появиться ошибка. Во многих случаях достаточно начинать с просмотра логов с ошибками (найти которые можно по request_id запроса или другим сохранённым идентификаторам), прежде чем глубоко закопаться в info- и warning-логи. Если же существующих данных недостаточно для понимания и исправления проблемы, необходимо добавить в проблемный процесс новые логи и после его внедрения в production повторить поиск. В самых исключительных случаях может помочь включение debug-логи (самый низкий уровень логирования). Но стоит помнить, что постоянно включённым этот режим в production держать нельзя из-за слишком избыточного количества сохраняемых сообщений, что приводит к быстрому исчерпанию места на жёстком диске в системах логирования приложения.

Эффективным инструментом для внедрения системы сбора логов в веб-приложениях является так называемый ELK-stack (Elastic, Logstash, Kibana). При его внедрении в ваши проекты постарайтесь продумать формат сохраняемых логов: помимо сообщения он точно должен содержать дату и время, имя функции (из которой пишется логов), request_id (описанный выше) и основной текст сообщения. Многострочные сообщения (например, трассировку) необходимо записывать одним массивом текста, иначе система логирования засорится и станет бесполезна в поиске ошибок.

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

Sentry

7fac6df1f56ba1e2ee7bb17ef2da5a66.png

Этот инструмент я вынес в отдельный пункт, так как хочется о нём рассказать подробнее. Sentry — это инструмент для мониторинга и анализа ошибок в приложениях. Его можно настроить на реагирование на error-логи, и добавить к ним оповещения, например в Telegram или Slack. Sentry умеет группировать ошибки, поэтому после релиза крайне желательно сортировать их по времени. Также полезность инструмента увеличивает удобный просмотр traceback-ошибок, с возможностью посмотреть, чему была равна каждая из используемых переменных при этом вызове. Если сообщений об ошибках в какой-то период времени будет слишком много, то в настройках Sentry стоит заранее ограничить их количество в час. Основные преимущества внедрения инструмента в вашу инфраструктуру:

  • Повышение скорости реагирования на возникающие ошибки.

  • Повышение информативности ошибок.

  • Снижение затрат на разработку (особенно если развернуть Sentry и на dev-стендах. Чем раньше выявлена ошибка, тем дешевле она обходится).

88e4347297db903171a5399de2d6d4c4.png

Аудит по базам данных

bdac90c4928c9ccb697f7dc31f034efc.png

Если в ваших базах помимо основных таблиц есть таблицы со всеми изменениями данных (их аудит), то можно будет аналитически найти, в чём была первопричина ошибки. Крайне рекомендуется для всех критичных процессов сразу проектировать такие таблицы, так как логи хранятся относительно недолго, аудит же можно до ротации хранить по другим политикам (например, 13 месяцев). Также для определения первопричины бага очень важно наличие колонок «какой пользователь или техпользователь совершил изменение» и «вызов из какого сервиса привёл к изменениям». Ниже приведу примерный алгоритм поиска ошибок по аудиту:

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

  • Проанализировать содержимое этих таблиц и выявить место с ошибочным изменением данных, делая последовательные поиски.

  • Сделать выводы и разработать план действий по исправлению найденных ошибок, включая устранение причин и предотвращение их повторного возникновения.

Воспроизведение на тестовом стенде

6fa6593c3e2dc0049431e902be57c83d.png

Для воспроизведения ошибочной ситуации на тестовых стендах необходимо выполнить следующий набор действий:

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

  • Настроить окружение, создав необходимые записи в базах данных или же поставив заглушки с заранее известным ответом от внешних систем. Если у вас качественный тестовый стенд и на нём регулярно проводится тестирование перед релизами в production, то настройка окружения займёт минимум времени.

  • Сделайте запрос (или отправьте сообщение в брокер сообщений), прочитайте логи с ошибкой или же остальные логи, появившиеся при вызове. В случае необходимости добавьте новые логи.

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

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

Заключение

99634c49bcba7eedddf54e53aff4d0ce.png

Стоит понимать, что поиск ошибок — это процесс, который требует терпения и систематичного подхода. Иногда ошибки могут быть очевидными, а иногда могут потребоваться дополнительные инструменты или опыт. Надеюсь, что статья поможет систематизировать уже имеющиеся у вас знания и подскажет пару новых инструментов. Если же в вашей компании борьба с багами находится на более высоком уровне, пожалуйста поделитесь опытом в комментариях.

P.S. В тексте использованы русскоязычные версии картинок с commitstrip.com.

© Habrahabr.ru