Nginx-log-collector ўтыліта ад Авіта для адпраўкі логаў nginx у Clickhouse

У гэтым артыкуле будзе разглядацца праект nginx-log-collector, які будзе чытаць логі nginx, адпраўляць іх у кластар Clickhouse. Звычайна для логаў выкарыстоўваюць ElasticSearch. Для Clickhouse патрабуецца менш рэсурсаў (дыскавая прастора, АЗП, ЦПУ). 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" and "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 ад Maxim Ignatenko

Nodejs-stub-server не мае rpm. Тут https://github.com/patsevanton/nodejs-stub-server ствараем яму rpm. Збірацца rpm будзе з дапамогай Fedora Copr

Усталеўваны на upstream nginx rpm пакет nodejs-stub-server

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 Total Requests:

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

Nginx-log-collector ўтыліта ад Авіта для адпраўкі логаў nginx у Clickhouse

Singlestat Failed Requests:

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

Singlestat Failing Percent:

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

Singlestat Avg Response Time:

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

Nginx-log-collector ўтыліта ад Авіта для адпраўкі логаў nginx у Clickhouse

Singlestat Max Response Time:

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

Nginx-log-collector ўтыліта ад Авіта для адпраўкі логаў nginx у Clickhouse

Count Status:

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

Nginx-log-collector ўтыліта ад Авіта для адпраўкі логаў nginx у Clickhouse

Для вываду дадзеных як пірог, трэба ўсталяваць убудова і перазагрузіць grafana.

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

Pie TOP 5 Status:

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

Nginx-log-collector ўтыліта ад Авіта для адпраўкі логаў nginx у Clickhouse

Далей буду прыводзіць запыты без скрыншотаў:

Count http_user_agent:

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

GoodRate/BadRate:

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

Response Timing:

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

Upstream response time (час адказу 1-га upstream):

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

Table Count Status для ўсіх hostаў:

$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 раскажа колькі зэканоміў дыска, АЗП, ЦПУ.

Telegram каналы:

Мілісекунды:

Каму важныя мілісекунды, напішыце ці прагаласуйце, калі ласка, у гэтым пытанне.

Крыніца: habr.com

Дадаць каментар