История создания Hawk — open-source трекера ошибок от команды CodeX

Это наш второй крупный open-source проект после Editor.js: 31 репозиторий, 4 года разработки, 100 миллионов ошибок в сутки. В этом материале расскажем историю создания Hawk — сервиса, который отлавливает ошибки в приложениях и помогает их исправлять.

Initial commit

CodeX — это клуб веб-разработки, он состоит из энтузиастов, объединившихся для создания open-source продуктов. Мы занимаемся экспериментами с современными технологиями, разработкой, DevOps и дизайном.

Помимо регулярной работы над нашими продуктами (а их уже более 120), мы иногда устраиваем офлайн встречи: митапы, кодовые марафоны, код кэмпы. На кодовых марафонах можно в сжатые сроки совместно проработать какую-нибудь идею и сделать прототип. Так появился и Hawk: 10 июня 2017 года был отправлен Initial commit.

Идея выглядела просто: специальный скрипт (Кэтчер) вешает глобальный обработчик ошибок в приложении и отправляет пойманные события в Гараж — сервис для просмотра собранной информации. Прототип был готов за два дня. Это было монолитное node.js приложение, а также несколько Кэтчеров под основные языки программирования.

Так выглядела первая версия Хоука

Следующие несколько месяцев ушли на доработку прототипа до полноценного сервиса: добавили авторизацию, систему воркспейсов и проектов, настройки команд. Попутно разработали Кэтчеры под базовые языки: PHP, JavaScript, Node.js, Python, Scala, Java и Kotlin.

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

Хайлоад вносит коррективы

Обкатать сервис помогли некоторые дружественные проекты, в том числе Комитет — мы подключили сборщик ошибок на vc.ru, TJ и DTF. Количество ивентов быстро достигло десятков и сотен тысяч в час, и это число продолжало расти.

Размер базы

Однажды ночью место на сервере закончилось и очистка не помогала — ивенты забивали все практически сразу. Той же ночью был спроектирован и создан Архивер, который удаляет выходящие за лимит ошибки по принципу FIFO. Место на диске перестало расти.

Онлайн

Вместе с тем росло и количество одновременных соединений с сервером, ведь JavaScript-кэтчеры присылали ошибки по протоколу WebSocket, а значит посетители сайтов клиентов одновременно открывали соединение с Хоуком. Проблема решилась небольшой настройкой nginx.

# # Количество воркеров (процессов), # выделенных под обработку запросов. # Рекомендованное значение: auto # — один воркер на одно ядро # процессора. # worker_processes auto; # # Количество доступных # файловых дескрипторов. # По два на каждое подключение # 2 * worker_connections * worker_processes # worker_rlimit_nofile 140000; events { # # Максимальное количество # соединений, которые сможет # обработать один воркер. # worker_connections 70000; # # Позволяем каждому воркеру # принимать несколько # подключений # multi_accept on; }

Нагрузка

Запись новых ивентов происходила каждую секунду безостановочно. Одновременно с этим базе приходилось осуществлять выборки и агрегации для просмотра ошибок в Гараже. Это делало использование сервиса не таким стабильным. Архитектура, при которой обработчик ивентов, API и веб-интерфейс находятся в одном сервисе, при таком трафике определенно не подходит.

Монолит

Проблемы монолитной архитектуры хорошо известны. Тем не менее, для первой версии продукта лучше использовать именно монолит (Monolith First) — это позволяет определить устоявшиеся части, которые можно выделить в микро-сервисы с ограниченным контекстом (Bounded Context). Цена ошибки в таких решениях высока — лучше чтобы понимание пришло в ходе использования продукта и развития кодовой базы, а не искусственно. Такой подход называется Evolutionary Design.

Микро-сервисы

Новая архитектура призвана решить проблемы первой версии: уменьшить связность сервисов и обеспечить устойчивость к нагрузке.

Новая архитектура Hawk
  • Узкое место — сервис приемки ивентов "Коллектор" — делает минимум операций. Его задача получить ивент, валидировать структуру и передать в очередь на обработку. Коллектор написан на Go.
  • Система воркеров позволяет создавать самостоятельные микро-сервисы для фоновой обработки задач. Воркеров можно масштабировать: увеличивать количество, выносить на мощные сервера и тд.
  • Трафик ивентов никак не влияет на работу клиентов (Web, Desktop, Mobile)
  • Публичный API, уведомления, обработчики ошибок, Архивер и остальные части не влияют на работу друг друга.
  • База ивентов и база аккаунтов (воркспейсов, проектов, настроек) разделены
  • У базы ивентов есть отдельные реплики для чтения.

Редизайн

Вместе с новой архитектурой и новым кодом появился и новый дизайн.

Мы решили две проблемы, которые присутствуют в большинстве сервисов, имеющих разделение на воркспейсы или подобные сущности.

Проблема воркспейсов

В сервисах, где пользователь состоит в нескольких воркспейсах, присутствует проблема с потерей контекста при переключении. По умолчанию открыт один раздел (Воркспейс, Проект), при этом не видно, что происходит в соседних. Максимум, что видно — бейдж с количеством уведомлений. Мониторить активность сразу в нескольких воркпейсах не получится. А при переключении между ними теряется контекст предыдущего.

В Slack, Discord, Jira, Sentry и прочих присутствует эта проблема. Мы видим только то, что происходит в одном выбранном воркспейсе

Мы дали возможность видеть сразу все воркспейсы одновременно. Лэйаут Хоука похож на мессенджер: слева выводится список проектов, которые поднимаются наверх при получении новых ивентов. Справа — список ивентов в проекте. Кнопки воркспейсов работают как фильтры — скрывают из списка проектов те, что не принадлежат воркспейсу.

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

Список ивентов

Ивенты в Хоуке группируются по дням: видно, сколько раз событие выпало в конкретный день, как развивается ситуация сегодня.

Страница ивента

Просмотр информации об ивенте тоже был доработан. Здесь выводятся собранные данные, которые помогают найти и устранить проблему.

Платежи

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

С ростом количества обрабатываемых ошибок растет и стоимость поддержки инфраструктуры. Чтобы проект окупал затраты, была разработана система тарифных планов. Хоук обрабатывает до 100 000 ошибок в месяц бесплатно — это подойдет для большинства небольших проектов. А для крупных клиентов, ощутимо влияющих на инфраструктуру, предусмотрены несколько платных планов.

Open Source

Исходных код всех частей Хоука открыт, задокументирован и опубликован на GitHub.

31 репозиторий
составляют кодовую базу Hawk. Все они имеют открытый исходный код.

Почему open source — это хорошо

Каждая часть Хоука доступна для изучения, улучшения и обсуждения инженерам со всего мира. Это делает сервис безопаснее, прозрачнее и качественнее.

Pricing в open source

Открытость кода и наличие документации позволяет поднять собственную версию Хоука командам, обладающим достаточными квалификациями в DevOps и SRE.

Второй вариант — использовать ready-to-use решение, которое обслуживается и поддерживается нашей командой.

CodeX Code Camp 2019

Переработка Хоука началась в начале 2019 года и тянулась несколько месяцев. Летом мы решили устроить очередной Code Camp — недельный кодовый марафон на природе, где команда сфокусируется на завершении работ и релизе проекта.

Мы спроектировали новую архитектуру, задизайнили и написали основные сервисы. Hawk 2.0 был готов к тестированию в виде MVP. Следующий год ушел на закрытый Beta-тест. Новая версия справлялась с нагрузкой, хоть и была сложнее в разработке и поддержке. Был создан собственный сервис Аккаунтинга, SDK к нему и много чего еще.

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

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

CodeX Code Camp 2021

И, хоть к маю 2021 проект был готов и анонсирован на ряде публичных выступлений, в том числе Samsung Open Source Conference, до релиза оставалось доделать последние задачи, допилить "упаковку", лендинг, сайт с документацией, решить ряд юридических вопросов. Снова выезжаем на Code Camp. На этот раз работы будут завершены.

Мы проделали большую работу: 4 года разработки, куча репозиториев, десятки тысяч строк кода. Команда молодых энтузиастов ежедневно решала сложные технические и продуктовые задачи. И сегодня долгожданный день релиза — мы представляем Hawk.

0
28 комментариев
Написать комментарий...
Dmitry S

Выглядит интересно)
Почему я, как разработчик, должен выбрать вас, а не Sentry?)

Ответить
Развернуть ветку
Пётр Савченко

Мы сделали упор на DX (Developer Experience). От удобства интеграции до работы с ивентами в админке. Особенно заметна разница, если у вас несколько воркспейсов и много проектов.

Бесплатный тариф больше в два раза без ограничений по фичам. Платные тарифы дешевле.

Ответить
Развернуть ветку
Аккаунт удален

Комментарий недоступен

Ответить
Развернуть ветку
Dmitry S

Вячеслав, спасибо за жизненный совет 🤝

Ответить
Развернуть ветку
Аккаунт удален

Комментарий недоступен

Ответить
Развернуть ветку
JÄÄKAAPPI

Переписали все на микросервисы, которые разнесены в отдельные репозитории

Ответить
Развернуть ветку
Никита

У вас там на https://github.com/codex-team запинена репа https://github.com/codex-team/hawk

Видимо, стоит её отпинить, в ридми дать ссылку на новую репу и старую заархиваровать

Ответить
Развернуть ветку
Аккаунт удален

Комментарий недоступен

Ответить
Развернуть ветку
Альберт Штерн

О, CodeX. Давно ждал от вас постов.
Может быть вы сосредоточитесь на editor.js?
Дойдете до B2B?
Жду ответика

Ответить
Развернуть ветку
Пётр Савченко

Недавно был крупный апдейт редактора. https://github.com/codex-team/editor.js/releases/tag/v2.23.0

Скоро будет еще один.

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

Ответить
Развернуть ветку
Dim Entelis

Ради интереса спробовал web версию https://garage.hawk.so/

Модуль для php на 8.1 сыпет пачкой ошибок, последний комит в ноябре 2021.
Ради интереса полечил часть локально - данные вроде ушли, в веб-морде не появились.

Ну такое.

Ответить
Развернуть ветку
Аккаунт удален

Комментарий недоступен

Ответить
Развернуть ветку
Пётр Савченко

Патч для 8.1 выпустили, проблема должна уйти после обновления

Ответить
Развернуть ветку
Dim Entelis

Потестил за вас - url по умолчанию https://hawk.so/catcher/php, ответ сервера 404 :)

Ответить
Развернуть ветку
Никита

В опенсорсе не бывает "за вас"

Ответить
Развернуть ветку
Dim Entelis

Я понимаю что "хочешь фичу - напиши её сам", это ok.

Тут ситуация несколько другая - всего то 6 модулей, из которых php очевидно будет на 1-2 месте по популярности.
И он тупо не работает потому что кто-то указал кривой url.

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

Если такое качество в элементарных вещах - страшно подумать что там внутри дальше, НЛ.

Ответить
Развернуть ветку
Dim Entelis

И кстати дока https://github.com/codex-team/hawk.php тоже не соответствует.
\Hawk\Catcher::init([
- там нет класса Catcher, есть только HawkCatcher
- у HawkCatcher тоже нет Init )

По коду в принципе понятно что вызывать, но выглядит как то...

Ответить
Развернуть ветку
Dim Entelis

Варнинги остались, событие не появляется

Ответить
Развернуть ветку
Пётр Савченко

Можете текст ошибок показать? Сейчас посмотрим

Ответить
Развернуть ветку
Dim Entelis
Ответить
Развернуть ветку
Андрей
последний комит в ноябре 2021

Вроде миллион правок за последнее время, не?
Или это именно про правки конкретных ошибок?

https://github.com/codex-team/hawk.garage

Ответить
Развернуть ветку
Dim Entelis
Ответить
Развернуть ветку
НищеBro

Вот это нормальные айти-чуваки. Меньше слов, больше дела.
А не смузи и тим-дилдинг.

Ответить
Развернуть ветку
Anton Khodakovsky

Выглядит годно, но не понимаю, как вы написали поддержку 6 фрейморков, но не добавили .net

Ответить
Развернуть ветку
Yurij Georgievich

В статье опечатка? LIFO : FIFO //надо же первый вошёл первый вышел, иначе архивер превращается в "терятель"

Ответить
Развернуть ветку
Макс Косинов

Нормальный дизайн, выглядит неплохо, ничего не скажешь

Ответить
Развернуть ветку

Комментарий удален модератором

Развернуть ветку
Alexey Smirnov

Как я понял у вас используется RabbitMQ обычный. Почему не Kafka или Redis Streams. У вас все влезает в память?

Ответить
Развернуть ветку
Alexander Menshikov

Исторически был опыт работы с RabbitMQ. Кафку использовать тоже вариант. Но как показала практика, RabbitMQ отлично справляется с нагрузкой.
С памятью проблем ни разу не было, мы стараемся держать подключенными достаточно воркеров, чтобы очередь не скапливалась.

Ответить
Развернуть ветку
25 комментариев
Раскрывать всегда