Мониторинг HTTP status codes
В чем проблема?
Nginx в своей стандартной комплектации (не Plus) предоставляет мало данных, как я понял. Точнее, наверное, prometheus-nginx-exporter собирает мало метрик. Нужные мне http status codes дефолтный экспортер не собирает, перепробовал многое (заново собирать nginx из исходников ради добавления в него модулей не хотелось) и остановился на другом экспортере, который берет данные из логов доступа (access.log).
Вообще, мне сбор данных из логов кажется тупорылой затеей (если говорить об эффективности и т.д.) но я просто заебался искать подходящее решение - это временное решение, потому что я пока не так сильно шарю.
prometheus-nginxlog-exporter
Repo: https://github.com/martin-helmich/prometheus-nginxlog-exporter
Установка
Есть deb-пакет: https://github.com/martin-helmich/prometheus-nginxlog-exporter/releases
Конфигурация
После установки конфиг /etc/prometheus-nginxlog-exporter.hcl лучше переместить в /etc/prometheus/prometheus-nginxlog-exporter/ (эту папку создать нужно):
mkdir /etc/prometheus/prometheus-nginxlog-exporter/
mv /etc/prometheus-nginxlog-exporter.hcl /etc/prometheus/prometheus-nginxlog-exporter/
Дефолтный конфиг prometheus-nginxlog-exporter.hcl выглядит так:
listen {
port = 9114
}
namespace "nginx" {
source = {
files = [
"/var/log/nginx/access.log"
]
}
format = "$remote_addr - $remote_user [$time_local] \"$request\" $status $body_bytes_sent \"$http_referer\" \"$http_user_agent\" \"$http_x_forwarded_for\""
labels {
app = "default"
}
}
Можно сверху задать порт, в секции files указать нужный лог-файл и ниже указать формат данных, который используется в лог-файле, чтобы экспортер мог нормально парсить оттуда метрики.
Погнали в /etc/nginx/nginx.conf, там нужно подправить пару вещей.
log_format status_only "$status";
access_log /var/log/nginx/access.log;
access_log /var/log/nginx/http_status_codes.log status_only;
error_log /var/log/nginx/error.log;
Указываю нужный мне формат логов и его название произвольное (здесь status_only), чтобы ссылаться на него ниже. Не собираюсь трогать access.log, поэтому укажу новый путь для нужных мне логов; там, по сути, будут только коды (мне пока больше и не нужно).
Нужно исправить и prometheus-nginxlog-exporter.hcl . Конечный конфиг у меня выглядит так:
listen {
port = 9114
}
namespace "nginx" {
source = {
files = [
"/var/log/nginx/http_status_codes.log"
]
}
format = "$status"
labels {
app = "default"
}
}
После изменений нужно подтянуть перезапустить сервисы:
sudo systemctl daemon-reload
sudo systemctl restart prometheus-nginxlog-exporter.service
sudo systemctl status prometheus-nginxlog-exporter.service
sudo systemctl reload nginx.service
sudo systemctl status nginx.service
Может понадобиться указать в prometheus-nginxlog-exporter.service юзера для доступа к access логам. Проверить, у кого есть доступ к логам можно так:
ls -l /var/log/nginx/
Вот prometheus-nginxlog-exporter.service, где указан юзер, от которого будет запускаться экспортер:
sudo vim /etc/systemd/system/multi-user.target.wants/prometheus-nginxlog-exporter.service
[Unit]
Description=NGINX metrics exporter for Prometheus
After=network-online.target
[Service]
User=www-data
ExecStart=/usr/sbin/prometheus-nginxlog-exporter -config-file /etc/prometheus/prometheus-nginxlog-exporter/prometheus-nginxlog-exporter.hcl
Restart=always
ProtectSystem=full
CapabilityBoundingSet=
[Install]
WantedBy=multi-user.target
У меня юзер указан www-data ибо на данный момент логи nginx создаются от этого пользователя, но в целом, лог http_status_codes.log, который нам нужен доступен всем для чтения, поэтому юзера можно и не указывать. Когда как.
Тест
Результат можно увидеть сначала в лог-файле:
sudo tail -f /var/log/nginx/http_status_codes.log
# output
200
200
404
...
# и т.д.
И на самом порту:
curl http://127.0.0.1:9114/metrics
# И там будет среди прочей инфы и комментов нужные нам метрики
nginx_http_response_count_total{app="default",method="",status="200"} 45
nginx_http_response_count_total{app="default",method="",status="404"} 1
# и т.п.
# показывается просто код и его кол-во (nginx_http_response_count_total{status="200"} можно в grafana указать и будет визуал)
PromQL
sum(nginx_http_response_count_total{status=~"2.."})
Этот материал использовался в Module 22