Ответ
Prometheus — это система мониторинга и алертинга, работающая по pull-модели. Это означает, что сервер Prometheus сам периодически опрашивает (scrape) HTTP-эндпоинты (/metrics) целевых сервисов для сбора метрик.
Ключевые компоненты и принципы:
-
Многомерная модель данных: Метрики хранятся в виде временных рядов (time series), где каждая точка данных идентифицируется именем метрики и набором пар ключ-значение, называемых метками (labels). Это позволяет гибко фильтровать и агрегировать данные. Пример:
http_requests_total{method="POST", path="/api/users"} -
Pull-модель сбора метрик: Prometheus активно собирает данные с настроенных
targets. Это упрощает развертывание и отладку, так как состояние мониторинга можно проверить, просто открыв эндпоинт/metricsв браузере. -
PromQL: Мощный и гибкий язык запросов, специально созданный для работы с многомерными данными временных рядов. Он позволяет выполнять сложные вычисления и агрегации на лету.
-
Хранилище (TSDB): Данные хранятся локально на диске в высокоэффективной базе данных временных рядов (Time Series Database), оптимизированной для быстрой записи и чтения.
-
Компоненты экосистемы:
- Exporters: Сторонние утилиты, которые преобразуют метрики из существующих систем (например, баз данных, очередей сообщений, оборудования) в формат Prometheus.
- Alertmanager: Отдельный компонент для управления алертами. Он обрабатывает правила, заданные в Prometheus, и отвечает за дедупликацию, группировку и отправку уведомлений в различные системы (Slack, PagerDuty, Email).
Пример инструментации приложения на Python:
from prometheus_client import start_http_server, Counter
import time
import random
# Создаем метрику типа Counter. Она может только увеличиваться.
# 'method' и 'endpoint' - это метки (labels).
REQUESTS = Counter('http_requests_total', 'Total HTTP Requests', ['method', 'endpoint'])
if __name__ == '__main__':
# Запускаем HTTP-сервер на порту 8000 для предоставления метрик
start_http_server(8000)
print("Prometheus metrics available on http://localhost:8000/metrics")
# Эмуляция работы приложения
endpoints = ['/api/v1/users', '/api/v1/items']
methods = ['GET', 'POST']
while True:
method = random.choice(methods)
endpoint = random.choice(endpoints)
# Увеличиваем счетчик для конкретной комбинации меток
REQUESTS.labels(method=method, endpoint=endpoint).inc()
time.sleep(1)