Это лишь часть таблицы инструментов, которые мы рассматривали. Подробнее по ссылке. Мы используем New Relic в каждом из наших 250 PHP-сервисов. С его помощью отслеживаем взаимосвязи между сервисами, их зависимости, смотрим нагруженные транзакции, анализируем полный трейс запроса пользователя. Наши основные функциональные требования: связи, оценка по времени отклика и параметру APDEX (собирательное значение удовлетворенности пользователя). Отказаться от New Relic хотели давно. Главная причина — он стал дорогой. Весной добавилась вторая причина — мы из России. Запереживали, что нас могут отключить. А мы в команде инфраструктуры стараемся все сервисы держать на своей стороне. В августе закончился договор с New Relic, так что заранее стали искать ему замену. И вот, как оно было. Переезд оттягивали долго — задача большая и сложная. После 24 февраля взяли ее в план как целевую. Рассматривали все варианты: закрытые и опенсорс-аналоги New Relic.  Изначально была идея найти дешевую замену в Пакистане или Индии — странах, которые придерживались нейтралитета в отношении России. Примеры таких сервисов: Atatus и Site24x7. Мы отправили им запрос про цены и, получив ответ, ужаснулись. Оказалось в разы больше, чем нам обходился New Relic. Процесс затягивался, потому что на письма с российской почты либо не отвечали, либо выдавали цены выше, чем на официальных сайтах. Начали активнее смотреть опенсорс-аналоги. Практически у всех отсутствует алертинг. Надо накручивать сверху, но с этим можно жить.  В некоторых нет APDEX-метрики. А у нас разработчики к ней привыкли.  Мы решили составить список важных нам характеристик, которые должны быть у инструмента. Я пошел в чат с разработчиками и попросил их назвать все, чем они пользуются в New Relic. Просмотрел ответы, отыскал старые аналогичные треды про возможный переезд, структурировал и выписал основные требования. Собралась первая колонка таблицы — с нужными характеристиками. Их 19.  На всякий случай дублирую ссылку на таблицу. Также мы добавили каждому требованию приоритет: Желательно — если не будет, то мы не расстроимся или разработаем альтернативу. Важно, но не критично — было бы приятно, но можно жить и без. Критично — супер важное требование. Для наличия / отсутствия нужных характеристик у аналогов, выбрали разные цвета:  Зеленый — все в порядке. Желтый — чего-то не хватает. Красный или черный — у инструмента все плохо с характеристикой или мы протестировали его и он нам не подошел. Фиолетовый — нет информации. Если у сервиса критичный для нас параметр окрашивался в красный или черный — мы говорили ему «нет». Хотя были исключения, но об этом позже. Я выписал все аналоги, которые нашел гуглением или которые  рекомендовали. И начал сравнивать. По каждому выставлял: открытый / закрытый софт, облако / сервер, штаб-квартиру и так далее. Указывал стоимость, если цифра была в открытом доступе. Для опенсорс-решений мы старались найти примерный хост, который требуется для обеспечения минимальной жизнеспособности, и сделать десятикратный запас. Например, Apache SkyWalking стоит 200$ за стандартный хост. С запасом x10 — это 2000$. У нас 98% бэкенда на PHP, поэтому была важна метрика поддерживаемых версии PHP. Нужно, чтобы инструмент поддерживал 7.2 — есть ряд старых проектов, хотя основная 7.4 и выше. И, конечно, важна поддержка 8.1.  Еще был важен тип агента PHP, чтобы установить новое расширение и не устраивать переделку кода 500 сервисов. В итоге, выбрали 2 опенсорс-кандидата. Мы остановились на них, несмотря на отсутствие алертов. У Zipkin еще и нет APDEX-метрики. Но это то, с чем решили смириться и прикрутить при необходимости.  Что дальше? Начали тестировать. Первым был Zipkin. Его название понравилось больше :) Развернули сервер и посмотрели, как он выглядит снаружи. По сравнению с New Relic — печально, но терпимо. Для полной проверки решили собрать больше данных и подключить наши сервисы. У Zipkin есть бандлы, поддерживающие Symfony, но понадобилось расширение, которое на уровне PHP перехватывало бы запросы. И мы его нашли — Molten.  Проблема — Molten давно не обновляется и не поддерживает ни PHP 8.1, ни 7.4. Последнее обновление библиотеки — полтора года назад, комментарии на китайском. От идеи двигать Zipkin дальше мы отказались… Попробовали SkyWalking. Он показался более готовым к продакшену. Подняли сервер на тестинге — все более-менее. Зашли в интерфейс — понравилось и даже похож на New Relic. Стали подключаться к сервисам и нашли огромный недостаток — расширение SkyWalking, которое мы использовали, не поддерживало консольные команды! Все консьюмеры и задачи, которые у нас запущены по Cron, никак не отображались. Я не мог понять, как такое возможно. Связался с контрибьютером. Оказалось, из-за архитектуры расширения, CLI плохо контролируется и его поддержка не реализована – пруф. А это для нас критичный момент. Снова вернулись к таблице альтернатив. Бесплатных вариантов не осталось, а из полуопенсорс только Elastic APM. Он требует лицензию. Мы рассчитывали, что она обойдется в 125$, плюс содержание своих серверов. Пообщавшись с Elastic, выяснили, что расклад следующий: Стоимость одной ноды — 6000$ в год. Минимальный контракт — 3 ноды. Elastic насчитали, что нам нужно 5 нод. Получается, Service Map стоил бы нам примерно 18-30 тысяч долларов в год. И, кажется, этот функционал лучше реализовать самим. У Elastic APM есть PHP-расширение. Мы раскатили на тестинге и столкнулись даже с большим количеством проблем, чем в двух предыдущих вариантах:  Нет внятной документации по развертыванию в Kubernetes. Пришлось звать DevOps-команду и разбираться.  При поднятии на тестинге выяснилось, что Elastic APM заблокировал РФ. Например, чтобы внутри Kibana установить расширение для интеграции с Elastic APM, нужно подключиться к серверам Elastic Core, который блокирует любые запросы с нашей стороны. Подумали и для интеграции подняли по инструкциям Elastic Registry, то есть свой сервер с этими же интеграциями.  Невозможно купить лицензию. Вкладка спрятана, опять же по причине блокировки РФ. Нашли внутреннюю апишку и подключили триал. Нам снова не хватало данных. Попробовали с инфровых сервисов, у которых много связей, слать данные на тестинг. Получилось, но столкнулись с недоработками PHP-расширения.  Расширение работает стабильно, поддерживает PHP 7.2-8.1, можно нормально настроить конфигурацию и даже поставить дебаг-режим, чтобы получать сообщения об ошибках.  Но: Внутри пришлось отключить HTTPS. Не поддерживается Symfony HTTP-клиент из-за  отсутствия поддержки curl_multi. Не выстраивается список зависимостей для сервиса, используемые базы можно увидеть только напрямую в транзакции. Несколько запросов к разным базам данным лепятся в одну базу. Он их не умеет различить, сматчить и построить сервисную карту.  Летом New Relic предупредили, что 30 августа переведут нас в режим read-only, поэтому обратного пути не было.  Мы подняли публичную продовую версию Elastic APM внутри под VPN, определились с архитектурой и вырезали лишнее, чтобы сделать ее легковесной. Стали подключать сервисы к Elastic APM, смотреть на данные и сверять с New Relic.  Единственное, что мы не нашли в Elastic APM — апишку, которая позволяет получать оттуда данные. Мы не можем по API запросить зависимые от сервисов сервисы. Поревесинженирили и нашли недокументированную API, которая дает данные для сервисной карты на фронт.  Расширение работало стабильно с PHP 8.0 / PHP 7.2, но не было поддержки RabbitMQ и Symfony Messenger. Для того, чтобы видеть данные по очередям в Elastic APM, мы создали внутренний бандл для Symfony. В нем частично перенесли функционал, который у нас уже был написан для New Relic.  Следующая проблема — в APM отсутствуют данные по запросам к сервисам кешей (Memcached, Redis). Начали смотреть, что с этим делать. Со стороны расширения это была большая доработка. Решили его не править, а позаимствовать внутри нашего бандла функционал, который использует Sentry для получения данных о запросах к кэшу. Еще одна проблема — в Elastic APM не то чтобы отсутствует поддержка Symfony HTTP-клиента, просто он по умолчанию использует асинхронные операции, которые реализованы через curl_multi. А расширение Elastic APM не умеет обрабатывать curl multi. Даже в бэклоге нет задачи на поддержку этого.  Полезли править. Добавили curl multi, а также сохранение результатов по запросу в момент, когда получен первый статус от сервера. Это нам дает хотя бы некоторые данные о том, какой код ответа на запрос и за сколько сервер его приготовил. Внесли доработки и поняли, что если будем делать мерж-реквест в официальный Elastic-репозиторий, то это займет много времени, а уже нужно катить. Поэтому клонировали к себе в GitLab репозиторий Elastic и закомитили правки. Затем еще сложности. Расширение не записывало дополнительные данные по запросу в БД (название базы, адрес и порт, по которому обращение) и не поддерживало Opcache preload. Тоже доделывали.  Едем дальше. Мы все еще используем New Relic и Elastic одновременно и они вроде не конфликтуют. Но если приложение подключается к другому Elastic по HTTP-соединению, то автоматический инструментарий New Relic и Elastic APM добавляют в header заголовок трейса, который по стандартам W3C должен быть один. А у нас получается два. И когда приходит запрос в Elasticsearch, то он выдает ошибки мультизаголовков. Выкатили для таких сервисов отдельный образ с отключенным New Relic и подготовили инструкцию по срочному переходу. У нас постоянно сыпятся ошибки в логи контейнеров о том, что сервер не имеет HTTP-хост ключ. Это происходит из-за того, что есть хелсчеки, которые обращаются на 127.0.0.1. И у них во время запроса не определялся $_SERVER[‘HTTP_HOST’], а Elastic APM думает, что это все равно внешний запрос, пытается найти HTTP_HOST, не находит его. Из-за этого у нас общий фон логов с одной и той же ошибкой возрос по всему Skyeng. Не сильно мешает, но и не очень красиво. В итоге, повысили уровень логирования в расширении до CRITICAL, так-как помимо инфраструктуры, разработчиков это тоже сильно нервировало. Стали проходить не все тесты. Для раннего обнаружения ошибок в образах PHP мы не отключали полностью Elastic APM не на проде. Он работает, но ничего не отправляет. Во время тестов, когда большое количество миграций и прочего, Elastic APM падает по памяти. Ограничились тем, что те, у кого происходят такие проблемы, во время тестов добавляют отдельную энвайронмент-переменную Elastic AMP disabled instrumentations. APM работает, но автоматически ничего не записывает и не тратит память. После того, как раскатилось около 50% сервисов (примерно 100), мы стали не справляться с нагрузкой. По памяти и по CPU Elasticsearch и Kibana тянули нагрузку хорошо, а APM-серверы, которые находятся в кластере на отдельных 10 подах, начали сильно загружаться. Нам пришлось увеличить количество подов, временно убрать им ограничение на память и CPU, а также включить автоматическое масштабирование, потому что поток данных потек большой. Потихоньку подключались следующие сервисы. Мы начали готовиться к переносу алертов из New Relic в Elastic APM… И тут не обошлось без проблем. Мы до сих пор на бесплатной лицензии, а интеграции алертов со Slack и с веб-хуками, которые используются для связи с Opsgenie — на Gold-версии.  Еще Elastic APM не умеет алертить по отдельным транзакциям — только по целому сервису. Например, есть у сервиса отдельный эндпоинт, который отвечает долго. В New Relic можно было для него настроить отдельный порог срабатывания алерта, а в Elastic APM нужно настраивать алерт по среднему уровню по больнице.  В результате, у Elastic APM либо всё время будет алертить медленный эндпоинт (порог настроен по быстрым эндпоинтам) или алертов просто не будет (порог настроен по медленному эндпоинту). У нас же принято, что все алерты настроены на определенные транзакции. Пока с помощью Grafana смогли получить данные из Elasticsearch по APM, вытащить оттуда данные по каждой из транзакций и настроить алерты. Но сложность в том, что Grafana постоянно запрашивает данные. Если сделать так для всех алертов — Elastic будет задыхаться. Решили таким способом выстраивать только критичные алерты. Положительные стороны Elastic APM и его расширения: Что не очень: Есть расширение и оно работает!  Поддерживает PHP 7.2-8.1.  Есть визуализация «из коробки».  Под капотом всё настроено для работы с данными APM. Практически полное отсутствие возможности оптимизировать данные.  Отправлять только транзакции с ошибками или вне среднего времени выполнения нельзя.  Не поддерживается opcache.preload.  Для алертов в Slack и OpsGenie или для ServiceMap требуется Platinum лицензия.  В консьюмерах есть проблемы при работе расширения. Там его пришлось отключать. Мы перевезли 180 сервисов. Остаются задачи по оптимизации хранения и дошлифовке расширения, но основной функционал уже production-ready. Дежурные инфраструктуры используют Elastic APM для расследования инцидентов — пару раз он им в этом сильно помог. С 1 сентября мы остались без New Relic. Хорошо, что к этому моменту была альтернатива, хоть и в состоянии MVP. Возможно, работая над разработкой собственного расширения в связке с Prometheus Grafana, вместо поиска альтернатив, мы бы закончили разработку также. Но теперь наш путь — дорабатывать имеющиеся расширение вместе с ребятам из Elastic.  Вот мы рассказываем про большое количество проблем, телодвижений и доработок — в целом стоил ли переезд того? Да, потому что профит от решения перевешивает, да и остальные аналоги хуже.  Если же вы решили писать своё расширение — PHP Internals Book в помощь.  Site Reliability Engineer