- PVSM.RU - https://www.pvsm.ru -

Мониторинг веб-приложения на Rust с использованием Prometheus и Grafana

В статье показано как настроить мониторинг веб-приложения на Rust. Приложение выставляет наружу Prometheus метрики, которые визуализируются с помощью Grafana. Мониторинг осуществляется для проекта mongodb-redis demo [1], детально рассмотренного здесь [2]. В итоге получена следующая архитектура:

architecture

Система мониторинга включает:

  • Prometheus [3] — платформа для мониторинга, которая агрегирует метрики в режиме реального времени и сохраняет их в базу данных временных рядов (time series database [4]).
  • Grafana [5] — платформа для анализа и визуализации метрик
  • AlertManager [6] — приложение, которое обрабатывает уведомления (alerts), отправляемые Prometheus сервером (например, когда в вашем приложении что-то идёт не так), и оповещает пользователя с помощью электронной почты, Slack, Telegram и т. д.
  • cAdvisor [7] — платформа для пользователей, использующих контейнеризацию, которая предоставляет данные по использованию ресурсов и параметрам производительности запущенных контейнеров. (На самом деле cAdvisor собирает данные со всех Docker контейнеров на схеме)

Для запуска всех этих инструментов вы можете воспользоваться следующим:

Docker Compose файл [8]

version: '3.8'
services:

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    restart: always
    ports:
      - '9090:9090'
    volumes:
      - ./monitoring/prometheus:/etc/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--web.external-url=http://localhost:9090'

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    restart: always
    ports:
      - '3000:3000'
    volumes:
      - ./monitoring/grafana/data:/var/lib/grafana
      - ./monitoring/grafana/provisioning:/etc/grafana/provisioning
    environment:
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: admin

  alertmanager:
    image: prom/alertmanager:latest
    container_name: alertmanager
    ports:
      - '9093:9093'
    volumes:
      - ./monitoring/alertmanager:/etc/alertmanager
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
      - '--web.external-url=http://localhost:9093'

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: cadvisor
    restart: always
    ports:
      - '8080:8080'
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro

Отдача Prometheus метрик Rust приложением

Отдача метрик имплементируется с помощью крейта [9] prometheus.

Существует четыре типа [10] Prometheus метрик: счётчик (counter), датчик/измеритель/шкала (gauge), гистограмма (histogram), сводка (summary). Использование первых трёх из них будет описано в статье (в настоящее время крейт не поддерживает [11] сводки).

Создание метрик

Метрики могут быть созданы и зарегистрированы следующим образом:

Создание и регистрация метрик [12]

lazy_static! {
    pub static ref HTTP_REQUESTS_TOTAL: IntCounterVec = register_int_counter_vec!(
        opts!("http_requests_total", "HTTP requests total"),
        &["method", "path"]
    )
    .expect("Can't create a metric");
    pub static ref HTTP_CONNECTED_SSE_CLIENTS: IntGauge =
        register_int_gauge!(opts!("http_connected_sse_clients", "Connected SSE clients"))
            .expect("Can't create a metric");
    pub static ref HTTP_RESPONSE_TIME_SECONDS: HistogramVec = register_histogram_vec!(
        "http_response_time_seconds",
        "HTTP response times",
        &["method", "path"],
        HTTP_RESPONSE_TIME_CUSTOM_BUCKETS.to_vec()
    )
    .expect("Can't create a metric");
}

В примере кода выше метрики добавляются в реестр по умолчанию. Также возможно зарегистрировать их в кастомном реестре (пример [13]).

Счётчик

Если требуется посчитать все входящие HTTP запросы, то возможно использовать тип IntCounter [14]. Но более полезно видеть не только общее число запросов, но также некоторые дополнительные измерения, такие как path и HTTP метод. Это можно сделать с помощью IntCounterVec [15]; метрика HTTP_REQUESTS_TOTAL этого типа используется в кастомном Actix middleware таким образом:

Использование [16] метрики HTTP_REQUESTS_TOTAL

let request_path = req.path();
let is_registered_resource = req.resource_map().has_resource(request_path);
// this check prevents possible DoS attacks that can be done by flooding the application
// using requests to different unregistered paths. That can cause high memory consumption
// of the application and Prometheus server and also overflow Prometheus's TSDB
if is_registered_resource {
    let request_method = req.method().to_string();
    metrics::HTTP_REQUESTS_TOTAL
        .with_label_values(&[&request_method, request_path])
        .inc();
}

После того, как вы сделаете несколько запросов к API, появится что-то похожее на:

Выходные данные метрики HTTP_REQUESTS_TOTAL

# HELP http_requests_total HTTP requests total
# TYPE http_requests_total counter
http_requests_total{method="GET",path="/"} 1
http_requests_total{method="GET",path="/events"} 1
http_requests_total{method="GET",path="/metrics"} 22
http_requests_total{method="GET",path="/planets"} 20634

Каждая выборка метрики содержит лейблы (атрибуты метрики) method и path, что позволяет Prometheus серверу различать выборки.

Как показано в фрагменте выше, запросы к GET /metrics (эндпоинт, с которого Prometheus сервер собирает метрики приложения) также учитываются.

Датчик

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

Использование [17] метрики HTTP_CONNECTED_SSE_CLIENTS

crate::metrics::HTTP_CONNECTED_SSE_CLIENTS.inc();

crate::metrics::HTTP_CONNECTED_SSE_CLIENTS.set(broadcaster_mutex.clients.len() as i64)

При переходе на http://localhost:9000 в браузере будет установлено SSE соединение, что инкрементирует значение метрики. После этого выходные данные станут такими:

Выходные данные метрики HTTP_CONNECTED_SSE_CLIENTS

# HELP http_connected_sse_clients Connected SSE clients
# TYPE http_connected_sse_clients gauge
http_connected_sse_clients 1

Broadcaster

Для имплементации датчика числа SSE клиентов потребовался рефакторинг кода приложения и реализация [17] broadcaster'а. Он сохраняет всех подключённых (с помощью функции [18] sse) клиентов в вектор и периодически их пингует (с помощью функции [17] remove_stale_clients), чтобы убедиться, что соединение по-прежнему активно, в противном случае удаляет отсоединённых клиентов из вектора. Broadcaster позволяет открывать всего лишь одно Redis Pub/Sub соединение [19]; сообщения из него отправляются (broadcasted) всем клиентам.

Гистограмма

В этом гайде гистограмма [20] используется для сбора данных о времени ответа. Как и в случае со счётчиком запросов, трекинг осуществляется в Actix middleware; это реализует следущий код:

Трекинг времени ответа [16]

...

histogram_timer = Some(
    metrics::HTTP_RESPONSE_TIME_SECONDS
        .with_label_values(&[&request_method, request_path])
        .start_timer(),
);

...

if let Some(histogram_timer) = histogram_timer {
    histogram_timer.observe_duration();
};

Полагаю, этот способ не очень точный (вопрос в том, насколько измеренное время ответа меньше реального), но тем не менее данные наблюдений будут полезны в качестве примера гистограммы и для её дальнейшей визуализации в Grafana.

Гистограмма принимает результаты наблюдений и подсчитывает их количество в конфигурируемых bucket'ах (есть bucket'ы по умолчанию, но скорее всего вам потребуется определить кастомные bucket'ы, подходящие к вашему use case); чтобы их сконфигурировать, было бы неплохо знать примерное рспределение значений определённой метрики. В этом приложении время ответа невелико, поэтому используется следующая конфигурация:

Bucket'ы для метрики времени ответа [12]

const HTTP_RESPONSE_TIME_CUSTOM_BUCKETS: &[f64; 14] = &[
    0.0005, 0.0008, 0.00085, 0.0009, 0.00095, 0.001, 0.00105, 0.0011, 0.00115, 0.0012, 0.0015,
    0.002, 0.003, 1.0,
];

Выходные данные будут выглядеть примерно так (показана только часть данных):

Выходные данные метрики HTTP_RESPONSE_TIME_SECONDS

# HELP http_response_time_seconds HTTP response times
# TYPE http_response_time_seconds histogram
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.0005"} 0
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.0008"} 6
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.00085"} 1307
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.0009"} 10848
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.00095"} 22334
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.001"} 31698
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.00105"} 38973
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.0011"} 44619
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.00115"} 48707
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.0012"} 51495
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.0015"} 57066
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.002"} 59542
http_response_time_seconds_bucket{method="GET",path="/planets",le="0.003"} 60532
http_response_time_seconds_bucket{method="GET",path="/planets",le="1"} 60901
http_response_time_seconds_bucket{method="GET",path="/planets",le="+Inf"} 60901
http_response_time_seconds_sum{method="GET",path="/planets"} 66.43133770000004
http_response_time_seconds_count{method="GET",path="/planets"} 60901

Данные показывают число наблюдений, попавших в определённые bucket'ы. Также предоставляются данные по общему числу и сумме наблюдений.

Системные метрики

process фича позволяет экспортировать метрики процесса [21], такие как использование процессора или памяти. Для этого нужно указать фичу в Cargo.toml. После этого вы получите что-то вроде:

Выходные данные метрик процесса

# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 134.49
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1048576
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 37
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 15601664
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1636309802.38
# HELP process_threads Number of OS threads in the process.
# TYPE process_threads gauge
process_threads 6
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 439435264

Обратите внимание, что крейт prometheus поддерживает экспорт метрик процесса в приложениях, запущенных на Linux (например, в таком [22] Docker контейнере).

Эндпоинт для отдачи метрик

Actix сконфигурирован так, чтобы обрабатывать запрос к GET /metrics с помощью следующего хэндлера:

Хэндлер для метрик [18]

pub async fn metrics() -> Result<HttpResponse, CustomError> {
    let encoder = TextEncoder::new();
    let mut buffer = vec![];
    encoder
        .encode(&prometheus::gather(), &mut buffer)
        .expect("Failed to encode metrics");

    let response = String::from_utf8(buffer.clone()).expect("Failed to convert bytes to string");
    buffer.clear();

    Ok(HttpResponse::Ok()
        .insert_header(header::ContentType(mime::TEXT_PLAIN))
        .body(response))
}

Теперь, после успешного конфигуриования приложения, вы можете получить все ранее описанные метрики выполнив запрос GET http://localhost:9000/metrics. Этот эндпоинт используется Prometheus сервером для получения метрик приложения.

Метрики отдаются в простом текстовом формате [23].

Настройка Prometheus для сбора метрик

Prometheus собирает метрики используя следующий конфиг:

Конфиг [24] Prometheus для сбора метрик

scrape_configs:

  - job_name: mongodb_redis_web_app
    scrape_interval: 5s
    static_configs:
      - targets: ['host.docker.internal:9000']

  - job_name: cadvisor
    scrape_interval: 5s
    static_configs:
      - targets: ['cadvisor:8080']

В конфиге определены две job'ы. Первая собирает ранее описанные метрики приложения, вторая — метрики использования ресурсов и производительности запущенных контейнеров (это будет подробно рассмотрено в разделе, описывающем использование cAdvisor). scrape_interval указывает как часто забирать данные с target. Параметр metrics_path не указан, поэтому Prometheus ожидает, что метрики будут доступны на target'ах по пути /metrics.

Expression browser и графический интерфейс

Для использования встроенного Prometheus expression browser перейдите на http://localhost:9090/graph и попробуйте запросить любую из ранее описанных метрик, например, http_requests_total. Используйте вкладку "Graph" для визуализации данных.

PromQL [25] позволяет делать более сложные запросы; рассмотрим пару примеров.

  • вернуть все временные ряды для метрики http_requests_total и заданной job'ы:

    http_requests_total{job="mongodb_redis_web_app"}

    Лейблы job и instance автоматически добавляются [26] к собираемым Prometheus сервером временным рядам.

  • вернуть с помощью функции rate [27] число запросов в секунду на основании измерений в последние 5 минут:

    rate(http_requests_total[5m])

Вы можете найти больше примеров здесь [28].

Настройка Grafana для визуализации метрик

В этом проекте Grafana сконфигурирована с помощью следующих параметров:

  • источники данных (откуда Grafana будет запрашивать данные)

    Конфиг источников данных [29] для Grafana

    apiVersion: 1
    
    datasources:
      - name: Prometheus
        type: prometheus
        access: proxy
        url: prometheus:9090
        isDefault: true

  • провайдер дашбордов (откуда Grafana загрузит дашборды)

    Конфиг дашбордов [30] для Grafana

    apiVersion: 1
    
    providers:
      - name: 'default'
        folder: 'default'
        type: file
        allowUiUpdates: true
        updateIntervalSeconds: 30
        options:
          path: /etc/grafana/provisioning/dashboards
          foldersFromFilesStructure: true

После запуска проекта с помощью файла Docker Compose [8] вы можете перейти на http://localhost:3000/, войти с помощью admin/admin и найти дашборд webapp_metrics. Некоторое время спустя он будет выглядеть примерно так:

grafana

Дашборд показывает состояние приложения под простым нагрузочным тестом. (Если вы запустите какой-нибудь нагрузочный тест, то для большей наглядности графиков (особенно гистограммы) вам нужно будет отключить ограничение [31] MAX_REQUESTS_PER_MINUTE, например, путём резкого увеличения этого числа.)

Для визуализации данных в дашборде [32] используются 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)

    Используется для визуализации распределения времени ответа в форме тепловой карты [33]. Тепловая карта похожа на гистограмму, но во времени; каждый интервал времени представляет собой отдельную гистограмму:

  • 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" показывает память, используемую:

  • процессом (process_resident_memory_bytes{job="mongodb_redis_web_app"} / 1024 / 1024)
  • контейнером (container_memory_usage_bytes{name="mongodb-redis"} / 1024 / 1024)

По неизвестной мне причине график показывает, что процесс потребляет намного больше памяти, чем весь контейнер. Я создал issue [34] по данному вопросу. Напишите, если что-то не так в этом сравнении или знаете, как это объясняется.

Мониторинг метрик контейнера приложения с помощью cAdvisor

В дополнение к системным метрикам процесса (было показано ранее) также могут быть экспортированы системные метрики Docker контейнера приложения. Это можно сделать с помощью cAdvisor.

Веб-интерфейс cAdvisor доступен по http://localhost:8080/. Все запущенные Docker контейнеры показаны на http://localhost:8080/docker/:

cadvisor docker containers

Вы можете получить информацию по использованию ресурсов любым контейнером:

cadvisor container info

Метрики собираются Prometheus сервером с http://localhost:8080/metrics.

Метрики, экспортируемые cAdvisor'ом, перечислены здесь [35].

Системные метрики серверов могут быть экспортированы с помощью Node exporter [36] или Windows exporter [37].

Настройка уведомлений с помощью правил и AlertManager

В этом проекте следующая часть конфига Prometheus отвечает за уведомления:

Конфиг [24] Prometheus для уведомлений

rule_files:
  - 'rules.yml'

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']

В разделе alerting определён инстанс AlertManager, с которым взаимодействет Prometheus сервер.

Правила оповещений [38] позволяют определить условия на основе PromQL выражений:

Пример [39] правила оповещения в rules.yml

groups:
- name: default
  rules:
  - alert: SseClients
    expr:  http_connected_sse_clients > 0
    for: 1m
    labels:
      severity: high
    annotations:
      summary: Too many SSE clients

  • alert – название оповещения
  • expr – определение правила в виде Prometheus выражения
  • for – как долго правило должно быть нарушено перед отправкой оповещения. В нашем случае если число SSE клиентов будет больше 0 в течение 1 минуты, то будет отправлено оповещение
  • labels – дополнительная информация, которая может быть добавлена к оповещению, например, уровень серьёзности проблемы
  • annotations – дополнительные сведения, которые могут быть добавлены к оповещению

Указанное правило, что число SSE клиентов больше 0, — это не то, что вы обычно настраиваете в приложении. Оно используется в качестве примера только потому, что позволяет легко его нарушить с помощью всего лишь одного запроса.

Если правило нарушено, Prometheus сервер отправит оповещение на инстанс AlertManager, который предоставляет множество фич, таких как дедупликация оповещений, группировка, отключение и роутинг уведомлений конечного пользователя. Здесь мы рассмотрим только роутинг: уведомление будлет перенаправлено на email.

AlertManager сконфигурирован так:

Конфиг AlertManager [40]

route:
  receiver: gmail

receivers:
- name: gmail
  email_configs:
  - to: recipient@gmail.com
    from: email_id@gmail.com
    smarthost: smtp.gmail.com:587
    auth_username: email_id@gmail.com
    auth_identity: email_id@gmail.com
    auth_password: password

В этом проекте AlertManager сконфигурирован с помощью Gmail аккаунта. Чтобы сгенерировать app password, вы можете использовать этот гайд [41].

Чтобы правило оповещения SseClients сработало, вам нужно перейти на http://localhost:9000 в браузере. Это увеличит значение метрики http_connected_sse_clients на 1. Вы можете видеть изменения статуса оповещения SseClients на http://localhost:9090/alerts. После срабатывания оповещение перейдёт в статус Pending. По прошествии интервала for, определённого в rules.yml (в нашем случае это 1 минута), оповещение перейдёт в статус Firing.

prometheus alert

Это приведёт к тому, что Prometheus сервер отправит оповещение в AlertManager, который определит что с ним делать. В нашем случае будет отправлен email:

gmail alert

Мониторинг third-party систем с помощью Prometheus exporters

Для third-party тулов, таких как MongoDB, Redis и многих других, есть возможность настроить мониторинг с помощью Prometheus exporters [42].

Запуск

docker compose up --build

Заключение

В этой статье было показано как настроить отдачу метрик веб-приложения на Rust, их сбор Prometheus'ом и визуализацию данных с помощью Grafana. Также было показано как начать работу с cAdvisor для сбора метрик контейнеров и с нотификациями с помощью AlertManager. Не стесняйтесь написать мне, если нашли какие-либо ошибки в статье или исходном коде. Спасибо за внимание!

Полезные ссылки

Автор: Roman Kudryashov

Источник [47]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/vizualizatsiya-danny-h/371243

Ссылки в тексте:

[1] mongodb-redis demo: https://github.com/rkudryashov/exploring-rust-ecosystem/tree/master/mongodb-redis

[2] здесь: https://romankudryashov.com/blog/2021/06/mongodb-redis-rust/

[3] Prometheus: https://prometheus.io/

[4] time series database: https://en.wikipedia.org/wiki/Time_series_database

[5] Grafana: https://grafana.com/

[6] AlertManager: https://prometheus.io/docs/alerting/latest/alertmanager/

[7] cAdvisor: https://github.com/google/cadvisor

[8] Docker Compose файл: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/docker-compose.override.yml

[9] крейта: https://github.com/tikv/rust-prometheus

[10] четыре типа: https://prometheus.io/docs/concepts/metric_types/

[11] не поддерживает: https://github.com/tikv/rust-prometheus/issues/5

[12] Создание и регистрация метрик: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/src/metrics.rs

[13] пример: https://github.com/tikv/rust-prometheus/blob/master/examples/example_custom_registry.rs

[14] IntCounter: https://docs.rs/prometheus/latest/prometheus/type.IntCounter.html

[15] IntCounterVec: https://docs.rs/prometheus/latest/prometheus/type.IntCounterVec.html

[16] Использование: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/src/main.rs

[17] Использование: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/src/broadcaster.rs

[18] функции: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/src/handlers.rs

[19] соединение: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/src/redis.rs

[20] гистограмма: https://prometheus.io/docs/practices/histograms/

[21] метрики процесса: https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics

[22] таком: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/Dockerfile

[23] формате: https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md

[24] Конфиг: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/monitoring/prometheus/prometheus.yml

[25] PromQL: https://prometheus.io/docs/prometheus/latest/querying/basics/

[26] автоматически добавляются: https://prometheus.io/docs/concepts/jobs_instances/

[27] rate: https://prometheus.io/docs/prometheus/latest/querying/functions/#rate

[28] здесь: https://prometheus.io/docs/prometheus/latest/querying/examples/

[29] Конфиг источников данных: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/monitoring/grafana/provisioning/datasources/datasources.yml

[30] Конфиг дашбордов: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/monitoring/grafana/provisioning/dashboards/providers.yml

[31] ограничение: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/src/services.rs

[32] дашборде: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/monitoring/grafana/provisioning/dashboards/webapp_metrics.json

[33] тепловой карты: https://grafana.com/docs/grafana/latest/basics/intro-histograms/

[34] issue: https://github.com/tikv/rust-prometheus/issues/424

[35] здесь: https://github.com/google/cadvisor/blob/master/docs/storage/prometheus.md

[36] Node exporter: https://github.com/prometheus/node_exporter

[37] Windows exporter: https://github.com/prometheus-community/windows_exporter

[38] Правила оповещений: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/

[39] Пример: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/monitoring/prometheus/rules.yml

[40] Конфиг AlertManager: https://github.com/rkudryashov/exploring-rust-ecosystem/blob/master/mongodb-redis/monitoring/alertmanager/alertmanager.yml

[41] этот гайд: https://support.google.com/accounts/answer/185833?hl=en

[42] exporters: https://prometheus.io/docs/instrumenting/exporters/

[43] Introduction to Prometheus: https://prometheus.io/docs/introduction/overview/

[44] Prometheus’s naming convention: https://prometheus.io/docs/practices/naming/

[45] How to visualize Prometheus histograms in Grafana: https://grafana.com/blog/2020/06/23/how-to-visualize-prometheus-histograms-in-grafana/

[46] Setup of an alerting system for Spring Boot application: https://tomgregory.com/monitoring-a-spring-boot-application-part-3-rules-and-alerting/

[47] Источник: https://habr.com/ru/post/645231/?utm_source=habrahabr&utm_medium=rss&utm_campaign=645231