В статье показано как настроить мониторинг веб-приложения на Rust. Приложение выставляет наружу Prometheus метрики, которые визуализируются с помощью Grafana. Мониторинг осуществляется для проекта mongodb-redis demo, детально рассмотренного здесь. В итоге получена следующая архитектура:  Система мониторинга включает: Для запуска всех этих инструментов вы можете воспользоваться следующим: Docker Compose файл Отдача метрик имплементируется с помощью крейта prometheus. Существует четыре типа Prometheus метрик: счётчик (counter), датчик/измеритель/шкала (gauge), гистограмма (histogram), сводка (summary). Использование первых трёх из них будет описано в статье (в настоящее время крейт не поддерживает сводки). Метрики могут быть созданы и зарегистрированы следующим образом: Создание и регистрация метрик В примере кода выше метрики добавляются в реестр по умолчанию. Также возможно зарегистрировать их в кастомном реестре (пример). Если требуется посчитать все входящие HTTP запросы, то возможно использовать тип IntCounter. Но более полезно видеть не только общее число запросов, но также некоторые дополнительные измерения, такие как path и HTTP метод. Это можно сделать с помощью IntCounterVec; метрика HTTP_REQUESTS_TOTAL этого типа используется в кастомном Actix middleware таким образом: Использование метрики HTTP_REQUESTS_TOTAL После того, как вы сделаете несколько запросов к API, появится что-то похожее на: Выходные данные метрики HTTP_REQUESTS_TOTAL Каждая выборка метрики содержит лейблы (атрибуты метрики) method и path, что позволяет Prometheus серверу различать выборки. Как показано в фрагменте выше, запросы к GET /metrics (эндпоинт, с которого Prometheus сервер собирает метрики приложения) также учитываются. Датчик отличается от счётчика тем, что его значение может уменьшаться. Пример датчика показывает сколько клиентов в настоящий момент подключены с помощью SSE. Используется следующим образом: Использование метрики HTTP_CONNECTED_SSE_CLIENTS При переходе на http://localhost:9000 в браузере будет установлено SSE соединение, что инкрементирует значение метрики. После этого выходные данные станут такими: Выходные данные метрики HTTP_CONNECTED_SSE_CLIENTS Для имплементации датчика числа SSE клиентов потребовался рефакторинг кода приложения и реализация broadcaster'а. Он сохраняет всех подключённых (с помощью функции sse) клиентов в вектор и периодически их пингует (с помощью функции remove_stale_clients), чтобы убедиться, что соединение по-прежнему активно, в противном случае удаляет отсоединённых клиентов из вектора. Broadcaster позволяет открывать всего лишь одно Redis Pub/Sub соединение; сообщения из него отправляются (broadcasted) всем клиентам. В этом гайде гистограмма используется для сбора данных о времени ответа. Как и в случае со счётчиком запросов, трекинг осуществляется в Actix middleware; это реализует следущий код: Трекинг времени ответа Полагаю, этот способ не очень точный (вопрос в том, насколько измеренное время ответа меньше реального), но тем не менее данные наблюдений будут полезны в качестве примера гистограммы и для её дальнейшей визуализации в Grafana. Гистограмма принимает результаты наблюдений и подсчитывает их количество в конфигурируемых bucket'ах (есть bucket'ы по умолчанию, но скорее всего вам потребуется определить кастомные bucket'ы, подходящие к вашему use case); чтобы их сконфигурировать, было бы неплохо знать примерное рспределение значений определённой метрики. В этом приложении время ответа невелико, поэтому используется следующая конфигурация: Bucket'ы для метрики времени ответа Выходные данные будут выглядеть примерно так (показана только часть данных): Выходные данные метрики HTTP_RESPONSE_TIME_SECONDS Данные показывают число наблюдений, попавших в определённые bucket'ы. Также предоставляются данные по общему числу и сумме наблюдений. process фича позволяет экспортировать метрики процесса, такие как использование процессора или памяти. Для этого нужно указать фичу в Cargo.toml. После этого вы получите что-то вроде: Выходные данные метрик процесса Обратите внимание, что крейт prometheus поддерживает экспорт метрик процесса в приложениях, запущенных на Linux (например, в таком Docker контейнере). Actix сконфигурирован так, чтобы обрабатывать запрос к GET /metrics с помощью следующего хэндлера: Хэндлер для метрик Теперь, после успешного конфигурирования приложения, вы можете получить все ранее описанные метрики выполнив запрос GET http://localhost:9000/metrics. Этот эндпоинт используется Prometheus сервером для получения метрик приложения. Метрики отдаются в простом текстовом формате. Prometheus собирает метрики используя следующий конфиг: Конфиг Prometheus для сбора метрик В конфиге определены две job'ы. Первая собирает ранее описанные метрики приложения, вторая — метрики использования ресурсов и производительности запущенных контейнеров (это будет подробно рассмотрено в разделе, описывающем использование cAdvisor). scrape_interval указывает как часто забирать данные с target. Параметр metrics_path не указан, поэтому Prometheus ожидает, что метрики будут доступны на target'ах по пути /metrics. Для использования встроенного Prometheus expression browser перейдите на http://localhost:9090/graph и попробуйте запросить любую из ранее описанных метрик, например, http_requests_total. Используйте вкладку "Graph" для визуализации данных. PromQL позволяет делать более сложные запросы; рассмотрим пару примеров. вернуть все временные ряды для метрики http_requests_total и заданной job'ы: http_requests_total{job="mongodb_redis_web_app"} Лейблы job и instance автоматически добавляются к собираемым Prometheus сервером временным рядам. вернуть с помощью функции rate число запросов в секунду на основании измерений в последние 5 минут: rate(http_requests_total[5m]) Вы можете найти больше примеров здесь. В этом проекте Grafana сконфигурирована с помощью следующих параметров: источники данных (откуда Grafana будет запрашивать данные) Конфиг источников данных для Grafana провайдер дашбордов (откуда Grafana загрузит дашборды) Конфиг дашбордов для Grafana После запуска проекта с помощью файла Docker Compose вы можете перейти на http://localhost:3000/, войти с помощью admin/admin и найти дашборд webapp_metrics. Некоторое время спустя он будет выглядеть примерно так:  Дашборд показывает состояние приложения под простым нагрузочным тестом. (Если вы запустите какой-нибудь нагрузочный тест, то для большей наглядности графиков (особенно гистограммы) вам нужно будет отключить ограничение MAX_REQUESTS_PER_MINUTE, например, путём резкого увеличения этого числа.) Для визуализации данных в дашборде используются PromQL запросы, включающие ранее показанные метрики, например: rate(http_response_time_seconds_sum[5m]) / rate(http_response_time_seconds_count[5m]) Показать среднее время ответа за последние 5 минут sum(increase(http_response_time_seconds_bucket{path="/planets"}[30s])) by (le) Используется для визуализации распределения времени ответа в форме тепловой карты. Тепловая карта похожа на гистограмму, но во времени; каждый интервал времени представляет собой отдельную гистограмму: rate(process_cpu_seconds_total{job="mongodb_redis_web_app"}[1m]), sum(rate(container_cpu_usage_seconds_total{name='mongodb-redis'}[1m])) by (name) Показывает использование процессора за последние 5 минут. Запрашиваемые данные приходят из двух источников и показывают использование ресурса процессом и контейнером соответственно. Два графика почти одинаковы. (sum используется поскольку container_cpu_usage_seconds_total предоставляет информацию по использованию каждого ядра.) Примечание: График "Memory usage" показывает память, используемую: По неизвестной мне причине график показывает, что процесс потребляет намного больше памяти, чем весь контейнер. Я создал issue по данному вопросу. Напишите, если что-то не так в этом сравнении или знаете, как это объясняется. В дополнение к системным метрикам процесса (было показано ранее) также могут быть экспортированы системные метрики Docker контейнера приложения. Это можно сделать с помощью cAdvisor. Веб-интерфейс cAdvisor доступен по http://localhost:8080/. Все запущенные Docker контейнеры показаны на http://localhost:8080/docker/:  Вы можете получить информацию по использованию ресурсов любым контейнером:  Метрики собираются Prometheus сервером с http://localhost:8080/metrics. Метрики, экспортируемые cAdvisor'ом, перечислены здесь. Системные метрики серверов могут быть экспортированы с помощью Node exporter или Windows exporter. В этом проекте следующая часть конфига Prometheus отвечает за уведомления: Конфиг Prometheus для уведомлений В разделе alerting определён инстанс AlertManager, с которым взаимодействет Prometheus сервер. Правила оповещений позволяют определить условия на основе PromQL выражений: Пример правила оповещения в rules.yml Указанное правило, что число SSE клиентов больше 0, — это не то, что вы обычно настраиваете в приложении. Оно используется в качестве примера только потому, что позволяет легко его нарушить с помощью всего лишь одного запроса. Если правило нарушено, Prometheus сервер отправит оповещение на инстанс AlertManager, который предоставляет множество фич, таких как дедупликация оповещений, группировка, отключение и роутинг уведомлений конечного пользователя. Здесь мы рассмотрим только роутинг: уведомление будлет перенаправлено на email. AlertManager сконфигурирован так: Конфиг AlertManager В этом проекте AlertManager сконфигурирован с помощью Gmail аккаунта. Чтобы сгенерировать app password, вы можете использовать этот гайд. Чтобы правило оповещения SseClients сработало, вам нужно перейти на http://localhost:9000 в браузере. Это увеличит значение метрики http_connected_sse_clients на 1. Вы можете видеть изменения статуса оповещения SseClients на http://localhost:9090/alerts. После срабатывания оповещение перейдёт в статус Pending. По прошествии интервала for, определённого в rules.yml (в нашем случае это 1 минута), оповещение перейдёт в статус Firing.  Это приведёт к тому, что Prometheus сервер отправит оповещение в AlertManager, который определит что с ним делать. В нашем случае будет отправлен email:  Для third-party тулов, таких как MongoDB, Redis и многих других, есть возможность настроить мониторинг с помощью Prometheus exporters. docker compose up --build В этой статье было показано как настроить отдачу метрик веб-приложения на Rust, их сбор Prometheus'ом и визуализацию данных с помощью Grafana. Также было показано как начать работу с cAdvisor для сбора метрик контейнеров и с нотификациями с помощью AlertManager. Не стесняйтесь написать мне, если нашли какие-либо ошибки в статье или исходном коде. Спасибо за внимание!