Prometheus – open-source система мониторинга, изначально разработанная в SoundCloud в 2012, публичный релиз состоялся в 2015.
Сам Prometheus написан большей частью на Go, компоненты связываются по HTTP.
Для визуализации имеет собственные графики, но может работать с системами типа Grafana (о ней позже, тоже будем применять).
Данные хранит локально, в собственной TSDB базе, индексы хранятся в LevelDB. Подробнее – тут>>>.
Метрики представляют собой time series данные – каждая состоит из имени метрики, временной метки и пары «ключ — значение». Больше деталей – тут>>>.
Компоненты
- сам сервер Prometheus
- клиентские библиотеки
- push gateway для работы с кратковременными процессами (когда сервис работает слишком мало времени, что бы Prometheus имел возможность выполнять к нему запросы для получения метрик)
- exporters для сбора метрик из сторонних сервисом (и таких экспортёров – миллион, и имя им легион)
- alertmanager – менеджер уведомлений (умеет Slack, почту и т.д.)
В целом архитектура самого Prometheus выглядит примерно так:
Больше – в документации.
Пробный запуск
Самый просто способ увидеть Prometheus в действии – запустить Docker контейнер.
Выполняем docker run -p 9090:9090 prom/prometheus
:
docker run -p 9090:9090 prom/prometheus
time="2017-09-18T09:02:34Z" level=info msg="Starting prometheus (version=1.7.1, branch=master, revision=3afb3fffa3a29c3de865e1172fb740442e9d0133)" source="main.go:88"
time="2017-09-18T09:02:34Z" level=info msg="Build context (go=go1.8.3,
[email protected], date=20170612-11:44:05)" source="main.go:89"
time="2017-09-18T09:02:34Z" level=info msg="Host details (Linux 4.12.12-1-ARCH #1 SMP PREEMPT Sun Sep 10 09:41:14 CEST 2017 x86_64 b446e48e4889 (none))" source="main.go:90"
time="2017-09-18T09:02:34Z" level=info msg="Loading configuration file /etc/prometheus/prometheus.yml" source="main.go:252"
time="2017-09-18T09:02:34Z" level=info msg="Loading series map and head chunks..." source="storage.go:428"
time="2017-09-18T09:02:34Z" level=info msg="0 series loaded." source="storage.go:439"
time="2017-09-18T09:02:34Z" level=info msg="Starting target manager..." source="targetmanager.go:63"
time="2017-09-18T09:02:34Z" level=info msg="Listening on :9090" source="web.go:259"
...
И открываем дашборд на localhost:9090:

Пример графика метрики времени выполнения проверок:

Другие примеры запуска – в документации тут>>>.
Сначала запустим Prometheus локально, в будущем – будем разворачивать и обновлять с помощью Ansbile, например – William-Yeh/ansible-prometheus (ну – по крайней мере так планируется на данный момент).
Запуск Prometheus
Запуск Docker контейнера – это хорошо, но посмотреть на Prometheus “изнутри” – нужно.
Загружаем архив со страницы загрузок:
sudo mkdir /opt/prometheus
sudo chown setevoy:setevoy /opt/prometheus
cd /opt/prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.0.0-beta.4/prometheus-2.0.0-beta.4.linux-amd64.tar.gz
tar xfp prometheus-2.0.0-beta.4.linux-amd64.tar.gz
cd prometheus-2.0.0-beta.4.linux-amd64
Содержимое каталога:
ls -l
total 77048
drwxrwxr-x 2 setevoy setevoy 4096 Sep 14 14:21 console_libraries
drwxrwxr-x 2 setevoy setevoy 4096 Sep 14 14:21 consoles
-rw-rw-r-- 1 setevoy setevoy 11357 Sep 14 14:21 LICENSE
-rw-rw-r-- 1 setevoy setevoy 2793 Sep 14 14:21 NOTICE
-rwxr-xr-x 1 setevoy setevoy 65725853 Sep 14 14:24 prometheus
-rw-rw-r-- 1 setevoy setevoy 995 Sep 14 14:21 prometheus.yml
-rwxr-xr-x 1 setevoy setevoy 13138183 Sep 14 14:24 promtool
prometheus
– исполняемый файл сервера
prometheus.yml
– файл настроек, полная документация тут>>>
Есть и Prometheus CLI – но пока не пользовался им.
Файл настроек по умолчанию умеет мониторить сам Prometheus.
Помощь – стандартно, через --help
:
./prometheus --help
usage: prometheus [<flags>]
The Prometheus monitoring server
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
--version Show application version.
...
Например – там есть параметр для указания директории для данных:
...
--storage.tsdb.path="data/"
Base path for metrics storage.
...
Запускаем, посмотрим:
./prometheus --config.file=prometheus.yml
INFO[0000] Starting prometheus (version=2.0.0-beta.4, branch=HEAD, revision=1b80f631a88a01473c1356d50da12eb49b462050) source="main.go:210"
INFO[0000] Build context (go=go1.8.3,
[email protected], date=20170914-11:22:50) source="main.go:211"
INFO[0000] Host details (Linux 4.12.12-1-ARCH #1 SMP PREEMPT Sun Sep 10 09:41:14 CEST 2017 x86_64 setevoy-arch-work (none)) source="main.go:212"
INFO[0000] Starting tsdb source="main.go:224"
INFO[0000] tsdb started source="main.go:230"
INFO[0000] Loading configuration file prometheus.yml source="main.go:363"
INFO[0000] Server is ready to receive requests. source="main.go:340"
INFO[0000] Listening on 0.0.0.0:9090 source="web.go:359"
INFO[0000] Starting target manager... source="targetmanager.go:67"
Появился каталог с данными:
ls -l data/
total 8
-rw------- 1 setevoy setevoy 6 Sep 18 13:27 lock
drwxr-xr-x 2 setevoy setevoy 4096 Sep 18 13:27 wal
Просмотреть метрики по умолчанию можно открыв http://localhost:9090/metrics:
curl -s http://localhost:9090/metrics | head
HELP go_gc_duration_seconds A summary of the GC invocation durations.
TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 2.8536e-05
go_gc_duration_seconds{quantile="0.25"} 4.0398e-05
go_gc_duration_seconds{quantile="0.5"} 6.5249e-05
go_gc_duration_seconds{quantile="0.75"} 9.6245e-05
go_gc_duration_seconds{quantile="1"} 0.006219725
go_gc_duration_seconds_sum 0.010451709
go_gc_duration_seconds_count 19
HELP go_goroutines Number of goroutines that currently exist.
Примеры
Добавление targets
Не будем отходить далеко от Getting started – продолжим с добавления локальных таргетов для мониторинга.
Клонируем тестовые клиенты:
git clone https://github.com/prometheus/client_golang.git
cd client_golang/examples/random
go get -d
go build
Запускаем три клиента:
./random -listen-address=:8081 &
./random -listen-address=:8082 &
./random -listen-address=:8083 &
Каждый начинает отдавать набор метрик:
curl -s localhost:8081/metrics | head
HELP go_gc_duration_seconds A summary of the GC invocation durations.
TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0
go_gc_duration_seconds{quantile="0.25"} 0
go_gc_duration_seconds{quantile="0.5"} 0
go_gc_duration_seconds{quantile="0.75"} 0
go_gc_duration_seconds{quantile="1"} 0
go_gc_duration_seconds_sum 0
go_gc_duration_seconds_count 0
HELP go_goroutines Number of goroutines that currently exist.
Теперь – добавим их в Prometheus.
Редактируем prometheus.yml
, добавляем новые таргеты:
...
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
- job_name: 'example-random'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
static_configs:
- targets: ['localhost:8080', 'localhost:8081']
labels:
group: 'production'
- targets: ['localhost:8082']
labels:
group: 'canary'
Перезапускам Prometheus, проверяем:

Отлично!
Одна нода Down, т.к. конфиг копировал из документации, а ноды у себя запускал на портах 8081-8083. ОК, работает, идём дальше.
Фильтры и запросы Promeheus
Отфильтруем запросы в графиках.
Если перейти в графики и выбрать, например, go_gc_duration_seconds_count
– будут отображены метрики от всех таргетов:
Используем язык запросов Prometheus.
Обновляем выражение в строке консоли. В примере файла настроек выше мы добавили три таргета в две группы – два таргета в production, один – в canaris.
Сделаем выборку по production, форматируем запрос:
go_gc_duration_seconds_count{group="production",job="example-random"}
Жмём Execute:

ОК, работает. Очень удобно.
Еднственный момент – в группе production добавлено два таргета, а в графике выводится только один – потому что второй в Down.
Запускаем ещё один random таргет, проверяем снова:
./random -listen-address=:8080 &
Обновляем страницу:

Замечательно.
Exporters
Теперь для примера – добавим Node exporter, что бы промониторить ресурсы локального сервера (вообще-то – рабочего ноутбука, на котором сейчас запущен Prometheus).
Качаем со страницы загрузок:
mkdir -p exporters/node_exporter
cd exporters/node_exporter/ && wget https://github.com/prometheus/node_exporter/releases/download/v0.14.0/node_exporter-0.14.0.linux-amd64.tar.gz
tar xfp node_exporter-0.14.0.linux-amd64.tar.gz
ls -l node_exporter-0.14.0.linux-amd64
total 12824
-rw-rw-r-- 1 setevoy setevoy 11357 Mar 21 14:11 LICENSE
-rwxr-xr-x 1 setevoy setevoy 13115134 Mar 21 14:13 node_exporter
-rw-rw-r-- 1 setevoy setevoy 463 Mar 21 14:11 NOTICE
Список коллекторов (т.е. метрик, которые будет отдавать експортёр) есть в README.
Запускаем:
./node_exporter-0.14.0.linux-amd64/node_exporter
INFO[0000] Starting node_exporter (version=0.14.0, branch=master, revision=840ba5dcc71a084a3bc63cb6063003c1f94435a6) source="node_exporter.go:140"
INFO[0000] Build context (go=go1.7.5,
[email protected], date=20170321-12:12:54) source="node_exporter.go:141"
INFO[0000] No directory specified, see --collector.textfile.directory source="textfile.go:57"
INFO[0000] Enabled collectors: source="node_exporter.go:160"
INFO[0000] - diskstats source="node_exporter.go:162"
INFO[0000] - time source="node_exporter.go:162"
INFO[0000] - wifi source="node_exporter.go:162"
INFO[0000] - conntrack source="node_exporter.go:162"
INFO[0000] - edac source="node_exporter.go:162"
INFO[0000] - filesystem source="node_exporter.go:162"
INFO[0000] - infiniband source="node_exporter.go:162"
INFO[0000] - netdev source="node_exporter.go:162"
INFO[0000] - stat source="node_exporter.go:162"
INFO[0000] - entropy source="node_exporter.go:162"
INFO[0000] - hwmon source="node_exporter.go:162"
INFO[0000] - sockstat source="node_exporter.go:162"
INFO[0000] - textfile source="node_exporter.go:162"
INFO[0000] - uname source="node_exporter.go:162"
INFO[0000] - zfs source="node_exporter.go:162"
INFO[0000] - filefd source="node_exporter.go:162"
INFO[0000] - loadavg source="node_exporter.go:162"
INFO[0000] - mdadm source="node_exporter.go:162"
INFO[0000] - meminfo source="node_exporter.go:162"
INFO[0000] - netstat source="node_exporter.go:162"
INFO[0000] - vmstat source="node_exporter.go:162"
INFO[0000] Listening on :9100 source="node_exporter.go:186"
Собственно – повторяем те же дейсвия.
Проверим доступные метрики:
./node_exporter-0.14.0.linux-amd64/node_exporter
INFO[0000] Starting node_exporter (version=0.14.0, branch=master, revision=840ba5dcc71a084a3bc63cb6063003c1f94435a6) source="node_exporter.go:140"
INFO[0000] Build context (go=go1.7.5,
[email protected], date=20170321-12:12:54) source="node_exporter.go:141"
INFO[0000] No directory specified, see --collector.textfile.directory source="textfile.go:57"
INFO[0000] Enabled collectors: source="node_exporter.go:160"
INFO[0000] - diskstats source="node_exporter.go:162"
INFO[0000] - time source="node_exporter.go:162"
INFO[0000] - wifi source="node_exporter.go:162"
INFO[0000] - conntrack source="node_exporter.go:162"
INFO[0000] - edac source="node_exporter.go:162"
INFO[0000] - filesystem source="node_exporter.go:162"
INFO[0000] - infiniband source="node_exporter.go:162"
INFO[0000] - netdev source="node_exporter.go:162"
INFO[0000] - stat source="node_exporter.go:162"
INFO[0000] - entropy source="node_exporter.go:162"
INFO[0000] - hwmon source="node_exporter.go:162"
INFO[0000] - sockstat source="node_exporter.go:162"
INFO[0000] - textfile source="node_exporter.go:162"
INFO[0000] - uname source="node_exporter.go:162"
INFO[0000] - zfs source="node_exporter.go:162"
INFO[0000] - filefd source="node_exporter.go:162"
INFO[0000] - loadavg source="node_exporter.go:162"
INFO[0000] - mdadm source="node_exporter.go:162"
INFO[0000] - meminfo source="node_exporter.go:162"
INFO[0000] - netstat source="node_exporter.go:162"
INFO[0000] - vmstat source="node_exporter.go:162"
INFO[0000] Listening on :9100 source="node_exporter.go:186"
Отдаёт – все замечательно.
Редактируем prometheus.yml
, добавляем новый таргет:
...
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
- job_name: 'example-random'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
static_configs:
- targets: ['localhost:8080', 'localhost:8081']
labels:
group: 'production'
- targets: ['localhost:8082']
labels:
group: 'canary'
- job_name: "node_local"
scrape_interval: "5s"
static_configs:
- targets: ['localhost:9100']
labels:
group: 'local'
Запускаем, проверяем таргеты:

Графики:

Всё работает.
Итоги
Prometheus потрогал первый раз. Весьма понравился как возможностями, так и удобством настройки и запуска.
Всё легко запускается в Docker, все настройки в файлах – отлично.
Далее – добавлю к нему Grafana, посмотрю на мониторинг уже Docker контейнеров, отдельных приложений (типа NodeJS) и начнём внедрять.
Ссылки по теме
Сайт проекта
Checking if SSH is responding with Prometheus
How To Use Prometheus to Monitor Your Ubuntu 14.04 Server
How to Use Prometheus to Monitor Your CentOS 7 Server
Prometheus Monitoring With Grafana
Initial experiences with the Prometheus monitoring system
Мониторинг сервисов с Prometheus
Prometheus — практическое использование
Мониторинг докер-хостов, контейнеров и контейнерных служб
Monitoring with Prometheus, Grafana & Docker Part 1