Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

В тази статия ще разгледаме проект nginx-log-collector, който ще чете логовете на nginx и ще ги изпраща в клъстера Clickhouse. Обикновено за логове се използва ElasticSearch. Clickhouse изисква по-малко ресурси (дисково пространство, RAM, CPU). Clickhouse записва данните по-бързо. Clickhouse компресира данните, което прави информацията на диска още по-компактна. Предимствата на Clickhouse са видими в 2 слайда от доклада Как VK вмъква данни в ClickHouse от десетки хиляди сървъри.

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

За да прегледаме аналитиката по логовете, ще създадем табло за Grafana.

На интересуващите се, добре дошли под кат.

Инсталираме nginx и grafana по стандартен начин.

Инсталираме клъстера Clickhouse с помощта на ansible-playbook от Денис Проскурин.

Създаване на база данни и таблици в Clickhouse

В този файл са описани SQL запитвания за създаване на база данни и таблици за nginx-log-collector в Clickhouse.

Всеки запитване правим по реда на всеки сървър в клъстера Clickhouse.

Важно забележка. В този ред logs_cluster трябва да бъде заменен с името на вашия клъстер от файла clickhouse_remote_servers.xml между "remote_servers" и "shard".

ENGINE = Distributed('logs_cluster', 'nginx', 'access_log_shard', rand())

Инсталиране и настройка на nginx-log-collector-rpm

Nginx-log-collector няма rpm. Тук https://github.com/patsevanton/nginx-log-collector-rpm създаваме му rpm. RPM ще се компилира с помощта на Fedora Copr

Инсталираме rpm пакета nginx-log-collector-rpm

yum -y install yum-plugin-copr
yum copr enable antonpatsev/nginx-log-collector-rpm
yum -y install nginx-log-collector
systemctl start nginx-log-collector

Коригирайте конфигурацията в /etc/nginx-log-collector/config.yaml:

  .......
  upload:
    table: nginx.access_log
    dsn: http://ip-адрес-кластера-clickhouse:8123/

- tag: "nginx_error:"
  format: error  # access | error
  buffer_size: 1048576
  upload:
    table: nginx.error_log
    dsn: http://ip-адрес-кластера-clickhouse:8123/

Настройка на nginx

Общата конфигурация на nginx:

user  nginx;
worker_processes  auto;

#error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    log_format avito_json escape=json
                     '{'
                     '"event_datetime": "$time_iso8601", '
                     '"server_name": "$server_name", '
                     '"remote_addr": "$remote_addr", '
                     '"remote_user": "$remote_user", '
                     '"http_x_real_ip": "$http_x_real_ip", '
                     '"status": "$status", '
                     '"scheme": "$scheme", '
                     '"request_method": "$request_method", '
                     '"request_uri": "$request_uri", '
                     '"server_protocol": "$server_protocol", '
                     '"body_bytes_sent": $body_bytes_sent, '
                     '"http_referer": "$http_referer", '
                     '"http_user_agent": "$http_user_agent", '
                     '"request_bytes": "$request_length", '
                     '"request_time": "$request_time", '
                     '"upstream_addr": "$upstream_addr", '
                     '"upstream_response_time": "$upstream_response_time", '
                     '"hostname": "$hostname", '
                     '"host": "$host"'
                     '}';

    access_log     syslog_server=unix:/var/run/nginx_log.sock,nohostname,tag=nginx avito_json; #ClickHouse
    error_log      syslog_server=unix:/var/run/nginx_log.sock,nohostname,tag=nginx_error; #ClickHouse

    #access_log  /var/log/nginx/access.log  main;

    proxy_ignore_client_abort on;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
}

Единственен виртуален хост:

vhost1.conf:

upstream backend {
    server ip-адрес-сервера-с-stub_http_server:8080;
    server ip-адрес-сервера-с-stub_http_server:8080;
    server ip-адрес-сервера-с-stub_http_server:8080;
    server ip-адрес-сервера-с-stub_http_server:8080;
    server ip-адрес-сервера-с-stub_http_server:8080;
}

server {
    listen   80;
    server_name vhost1;
    location / {
        proxy_pass http://backend;
    }
}

Добавяме виртуалните хостове в файла /etc/hosts:

ip-адрес-сервера-с-nginx vhost1

Емулятор на HTTP сървър

Като емулатор на HTTP сървър ще използваме nodejs-stub-server от Максим Игнатенко

Nodejs-stub-server не предлага rpm. Тук https://github.com/patsevanton/nodejs-stub-server създаваме му rpm. RPM ще се компилира с помощта на Fedora Copr

Инсталираме rpm пакета nodejs-stub-server на upstream nginx

yum -y install yum-plugin-copr
yum copr enable antonpatsev/nodejs-stub-server
yum -y install stub_http_server
systemctl start stub_http_server

Тест за натоварване

Тестът се провежда с помощта на Apache benchmark.

Инсталираме го:

yum install -y httpd-tools

Започваме тестване с Apache benchmark от 5 различни сървъра:

while true; do ab -H "User-Agent: 1server" -c 10 -n 10 -t 10 http://vhost1/; sleep 1; done
while true; do ab -H "User-Agent: 2server" -c 10 -n 10 -t 10 http://vhost1/; sleep 1; done
while true; do ab -H "User-Agent: 3server" -c 10 -n 10 -t 10 http://vhost1/; sleep 1; done
while true; do ab -H "User-Agent: 4server" -c 10 -n 10 -t 10 http://vhost1/; sleep 1; done
while true; do ab -H "User-Agent: 5server" -c 10 -n 10 -t 10 http://vhost1/; sleep 1; done

Настройка на Grafana

На официалния сайт на Grafana не можете да намерите дашборда.

Затова ще го направим ръчно.

Моят запазен дашборд можете да намерите тук.

Също така трябва да създадете променлива table с съдържанието nginx.access_log.
Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Singlestat Общо заявки:

SELECT
 1 as t,
 count(*) as c
 FROM $table
 WHERE $timeFilter GROUP BY t

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Показатели за една стойност: Неправилни заявки:

SELECT
 1 as t,
 count(*) as c
 FROM $table
 WHERE $timeFilter AND status NOT IN (200, 201, 401) GROUP BY t

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Процент на неуспех:

SELECT
 1 as t, (sum(status = 500 or status = 499) / sum(status = 200 or status = 201 or status = 401)) * 100 FROM $table
 WHERE $timeFilter GROUP BY t

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Средно време за отговор:

SELECT
 1, avg(request_time) FROM $table
 WHERE $timeFilter GROUP BY 1

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Максимално време за отговор:

SELECT
 1 as t, max(request_time) as c
 FROM $table
 WHERE $timeFilter GROUP BY t

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Брой статуса:

$columns(status, count(*) as c) from $table

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

За да покажете данни като пай, трябва да инсталирате плъгин и да рестартирате grafana.

grafana-cli plugins install grafana-piechart-panel
service grafana-server restart

Пай ТОП 5 статус:

SELECT
    1, 
    status,
    sum(status) AS Reqs
FROM $table
WHERE $timeFilter
GROUP BY status
ORDER BY Reqs desc
LIMIT 5

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Сега ще предоставя заявки без екранни снимки:

Брой http_user_agent:

$columns(http_user_agent, count(*) c) FROM $table

Добра ставка/Лоша ставка:

$rate(countIf(status = 200) AS good, countIf(status != 200) AS bad) FROM $table

Време за отговор:

$rate(avg(request_time) as request_time) FROM $table

Време за отговор от upstream (време за отговор от първия upstream):

$rate(avg(arrayElement(upstream_response_time,1)) as upstream_response_time) FROM $table

Таблица Брой статуси за всички vhost:

$columns(status, count(*) as c) from $table

Общ изглед на таблото

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Сравнение на avg() и quantile()

avg()
Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse
quantile()
Nginx-log-collector утилита от Авито за изпращане на nginx логове в Clickhouse

Изход:

Надявам се общността да се включи в разработката/тестовете и използването на nginx-log-collector.
И някой, който внедри nginx-log-collector, ще сподели колко пространство спести на диска, RAM, CPU.

Telegram канали:

Милисекунди:

Който е важен за милисекундите, напишете или гласувайте, моля, в това проблем.

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster