В этой статье мы расскажем, как интегрировать мониторинг Prometheus в существующее приложение. Мониторинг приложения даст вам представление о том, как и когда оно используется. Также вы сможете увидеть и предотвратить потенциальные проблемы.
Ключевые моменты:
- Изучение методов мониторинга приложений и серверов с помощью Prometheus.
- Запуск Prometheus в Docker.
- Мониторинг и применение образца приложения на Golang.
- Развертывание Prometheus с помощью Docker.
- Получение примеров быстрого запуска с PromQL.
Prometheus — ведущая база данных временных рядов и решение для мониторинга.
На снимке сверху — Julius Volz, соучредитель на Docker Berlin Summit.
Ищете примеры кода для быстрого старта? Жмите Star или Fork на Github:
Роль экспортеров
Prometheus — база данных временных рядов с пользовательским интерфейсом и сложным языком запросов (PromQL). Prometheus может очищать метрики, счетчики, датчики и гистограммы через HTTP с использованием простого текста или более эффективного протокола.
Глоссарий:
Конечная точка /metrics, внедряемая в существующее приложение, называется контрольно-измерительным прибором. Когда конечная точка /metrics — отдельный проект, он называется «Экспортер».
NodeExporter
Одним из наиболее широко используемых экспортеров является NodeExporter. Когда NodeExporter запущен на хосте, он предоставляет подробную информацию о нагрузках ввода / вывода, памяти, диска и ЦП. Вы можете запустить NodeExporter в контейнере Docker, но для этого требуется множество дополнительных флагов, которые проект рекомендует запускать на контролируемом хосте.
Встроенный экспортер
Prometheus предоставляет собственный набор показателей. Он интегрирован и обычно настроен на сбор по умолчанию.
Поддерживаемые сообществом экспортеры
Интересные экспортеры, которые были представлены на Docker’s Berlin summit, — Docker Hub и Github Edward Marshall. Эти экспортеры предоставляют метрики с сайтов Docker Hub или Github, периодически запрашивая API, а затем передавая значения.
Эд использовал клиентскую библиотеку Python, чтобы собрать экспортер, но доступны и другие привязки к языку.
- Экспортер Docker Hub, написанный в Python
Один из первых экспортеров Prometheus, который я написал, должен был мониторить статистику биткоинов: сколько долларов я заработал и сколько решений (хэшей) за секунду обрабатывает оборудование.
Биткоин-экспортер написан на Node.js и использует Gauge и показатели Histogram.
- Биткоин- экспортер на Node.js
- Другие экспортеры выделяются в таких документах как MySQL, Mongo, Redis, NATS, Nginx и JenkinsCI.
Построение собственного экспортера
В построении собственного экспортера можно контролировать практически все. Представьте, что вы запустили магазин Shopify (think: webstore-in-a-box) и отслеживаете статус продаж и заказов.
В панель инструментов можно включить параметры:
- Наиболее продаваемый продукт.
- Наиболее продаваемая категория.
- Общее число заказов.
- Время реагирования.
- Общее число отзывов.
- Средний рейтинг по отзывам.
- Количество подписок.
Также можно отслеживать следующие показатели:
- Обработанные транзакции.
- Время отклика платежного шлюза.
- Ошибки HTTP, такие как 403 и 404.
- Географическое расположение клиентов по IP-адресу.
Для начала рассмотрим простой вариант работы Prometheus с Docker, а затем вернемся к написанию инструментария для примера приложения.
Работа Prometheus c Docker
Prometheus написан на Golang и может использоваться как один статически скомпилированный двоичный файл. Проект упаковывает двоичный файл с разумной конфигурацией в контейнер Docker.
Запускаем Prometheus в Docker
Определяем Docker Compose, благодаря которому командные строки будут простыми и повторяемыми:
«`version: “3”
services:
prometheus:
image: quay.io/prometheus/prometheus:latest
ports:
- 9090:9090
Разверните файл стека:
Для развертывания файлов стека требуется режим Swarm, поэтому запустите docker swarm init.
$ docker swarm init
$ docker stack deploy monitoring --compose-file=./docker-compose.yml
Переходите на: http://localhost:9090/ для просмотра пользовательского интерфейса.
На скриншоте выше вы видите количество используемых go_routines
, записанных Prometheus. Чтобы увидеть исходные показатели Prometheus, откройте браузер и перейдите на http://localhost:9090/metrics
Go_routines
– легкая версия потока, используемая в Golang для обеспечения параллелизма.
Возможно, вы не захотите контролировать Prometheus, но тот факт, что батарейки включены, означает, что вы имеете представление о показателях.
Инструментирование приложения
Существуют два подхода к инструментированию, которые подразумевают, что вы открываете конечную точку HTTP/s. По умолчанию конечная точка — /metrics, но может быть настроена в файле prometheus.yml. Prometheus будет использовать эту конечную точку для очистки показателей с регулярными интервалами, например, каждые 5 или 30 секунд.
Нужно ли изменять код приложения?
Вы можете сделать конечную точку /metrics частью кода в существующем приложении. Это означает, что у вас уже есть необходимые секреты и учетные данные для взаимодействия с бизнесом / платежами или уровнями базы данных. Недостатком является то, что вам нужно включить новую библиотеку, конечную точку и зависимость в свой продукт или проект.
Есть ли другой вариант?
Также возможно писать раздельные процессы, которые действуют как оболочка для предоставления информации из вашего приложения или среды. Ed’s Docker Hub — экспортер располагает данными из внешнего API, которые он не контролирует. Такой вариант пригодится, если нельзя получить разрешение на изменение существующего приложения.
Преимущество отдельного процесса заключается в том, что вы можете обновлять то, что контролируете, не переустанавливая свои
приложения.
Имплементация конечной точки:
Есть два формата «изложения». Давайте посмотрим на результат предыдущего примера go_routines
, посетив http://localhost:9090/metrics.
«`# HELP go_goroutines Number of goroutines that currently exist.
TYPE go_goroutines gauge
go_goroutines 92 «`
Использование клиентской библиотеки
Доступно несколько библиотек для экспонирования показателей, большинство из которых могут выводить текст или более эффективный двоичный формат (Protobuf), упомянутый выше.
Привязки к языку Golang, Java, Python и Ruby поддерживаются проектом, но также доступно множество других привязок с открытым исходным кодом. Полный список можно найти здесь:
Стоит ли составлять собственный протокол?
Формат текста настолько прост, что вы можете легко реализовать протокол, следуя форматам изложения Prometheus. Перед тем как составлять протокол, убедитесь, что действительно не сможете воспользоваться проверенными клиентскими библиотеками.
Инструментирование приложения Golang
Давайте создадим простое приложение и применим его к библиотеке Golang Prometheus.
Вариант использования:
Нам было предложено написать веб-сервис для предоставления хэшей SHA-256 по требованию. Для этого нам нужно знать:
- сколько запросов мы получаем для хэшей;
- сколько в среднем времени занимает вычисление каждого хэша;
- сколько ошибок 400 (неудачных запросов) мы получаем.
К счастью, мы можем это узнать, используя метрику гистограммы. Но самым простым способом является счетчик датчика. Счетчик всегда остается неизменным, в то время как датчик может идти вверх или вниз.
Читайте о типах метрик
Полный код, содержащий Dockerfile, доступен на Github: alexellis/hash-browns
Пример файла server.go:
«`func main() {
histogram := prometheus.NewHistogramVec(prometheus.HistogramOpts{
Name: “hash_duration_seconds”,
Help: “Time taken to create hashes”,
}, []string{“code”})
r := mux.NewRouter()
r.Handle("/metrics", prometheusHandler())
r.Handle("/hash", hashHandler(histogram))
prometheus.Register(histogram)
s := &http.Server{
Addr: ":8080",
ReadTimeout: 8 * time.Second,
WriteTimeout: 8 * time.Second,
MaxHeaderBytes: 1 << 20,
Handler: r,
}
log.Fatal(s.ListenAndServe())
}«`
Здесь мы регистрируем маршрут приложения и метрик
.
Время записи — случай вызова histogram.Observe(seconds).
start := time.Now()
// Do something
duration := time.Since(start)
code := 200 // some HTTP Code
histogram.WithLabelValues(fmt.Sprintf("%d", code)).Observe(duration.Seconds())
Вы можете создать хэш следующим образом:
$ curl localhost:8080/hash -d "my_input_value_here"
49b8c4256d603a68ee9bcd95f8e11eed784189bd40c354950014b6d7f7263d6c
Это будет отображаться, если мы curl localhost:8080/metrics
.
# HELP hash_seconds Time taken to create hashes
# TYPE hash_seconds histogram
hash_seconds_bucket{code="200",le="1"} 2
hash_seconds_bucket{code="200",le="2.5"} 2
hash_seconds_bucket{code="200",le="5"} 2
hash_seconds_bucket{code="200",le="10"} 2
hash_seconds_bucket{code="200",le="+Inf"} 2
hash_seconds_sum{code="200"} 9.370800000000002e-05
hash_seconds_count{code="200"} 2
Последний шаг. Отредактируйте файл prometheus.yml
и начните очищать новый код приложения. Затем найдите метрику в раскрывающемся списке и отобразите значения.
Собирая все воедино
Нам нужно отредактировать конфигурацию Prometheus. Вот трюк, чтобы извлечь конфигурацию по умолчанию из официального образа Docker:
$ docker run --entrypoint='' -ti quay.io/prometheus/prometheus:latest /bin/cat /etc/prometheus/prometheus.yml > prometheus.yml
Теперь отредактируйте файл prometheus.yml, созданный в вашем текущем каталоге. В разделе scrape_configs
добавьте следующее:
«` — job_name: ‘hashbrowns’
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['hashbrowns:8080']```
Docker Swarm позволяет сервисам взаимодействовать друг с другом через встроенный DNS, поэтому цель — метка («hashbrowns») из файла компоновки.
Теперь создайте новый файл docker-compose.yml
:
«`version: “3”
services:
prometheus:
image: quay.io/prometheus/prometheus:latest
ports:
- 9090:9090
volumes: - “./prometheus.yml:/etc/prometheus/prometheus.yml”
- hashbrowns:
image: alexellis2/hash-browns
ports: - 8080:8080«`
Разверните файл стека:
$ docker stack deploy tutorial --compose-file=./docker-compose.yml
Примечание. Адресация службы по имени будет функционировать хорошо, пока у вас есть только одна реплика. Если вы решите масштабировать услугу, нужно будет изучить способность Prometheus обнаруживать все реплики отдельно с большей точностью.
Вот как это будет выглядеть в интерфейсе Prometheus:
Теперь мы дадим ответы в формате [PromQL] для показателей, которые хотели собрать выше. Мне потребовалось некоторое время, чтобы привыкнуть к PromQL, но, к счастью, Julius написал очень подробную статью, доступную здесь.
- Вопрос: Сколько запросов мы получаем для хэшей
Следующий оператор PromQL дает скорость увеличения для нашей хэш-функции в течение 1-минутного окна. Это окно может быть меньше, но оно должно охватывать как минимум два образца.
rate(hash_seconds_count[1m])
- Вопрос: Cколько в среднем времени занимает вычисление каждого хэша
Для среднего выполнения за последние 5 минут введите:
rate(hash_seconds_sum[5m]) / rate(hash_seconds_count[5m])
- Вопрос: Покажите, сколько ошибок 400 мы получили за последние 5 минут
rate(hash_seconds_count{code="400"}[5m])