Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Tatalakayin ng artikulong ito ang proyekto nginx-log-collector, na magbabasa ng mga log ng nginx at ipapadala ang mga ito sa cluster ng Clickhouse. Karaniwan ang ElasticSearch ay ginagamit para sa mga log. Ang Clickhouse ay nangangailangan ng mas kaunting mapagkukunan (disk space, RAM, CPU). Ang Clickhouse ay nagtatala ng data nang mas mabilis. Kino-compress ng Clickhouse ang data, na ginagawang mas compact ang data sa disk. Ang mga bentahe ng Clickhouse ay makikita sa 2 slide mula sa ulat Paano ipinapasok ng VK ang data sa ClickHouse mula sa libu-libong mga server.

Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Upang tingnan ang analytics batay sa mga log, gagawa kami ng dashboard para sa Grafana.

Sinumang interesado, maligayang pagdating sa pusa.

I-install ang nginx, grafana sa karaniwang paraan.

Pag-install ng clickhouse cluster gamit ang ansible-playbook mula sa Denis Proskurin.

Paglikha ng mga database at talahanayan sa Clickhouse

Sa ganitong file Ang mga query sa SQL para sa paglikha ng mga database at mga talahanayan para sa nginx-log-collector sa Clickhouse ay inilarawan.

Ginagawa namin ang bawat kahilingan nang paisa-isa sa bawat server sa cluster ng Clickhouse.

Mahalagang paalaala. Sa linyang ito, kailangang palitan ang logs_cluster ng iyong cluster name mula sa clickhouse_remote_servers.xml file sa pagitan ng "remote_servers" at "shard".

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

Pag-install at pag-configure ng nginx-log-collector-rpm

Ang Nginx-log-collector ay walang rpm. Dito https://github.com/patsevanton/nginx-log-collector-rpm lumikha ng rpm para dito. rpm ay bubuuin gamit ang Fedora Copr

I-install ang rpm package 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

I-edit ang config /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/

Pagse-set up ng nginx

Pangkalahatang nginx config:

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;
}

Isang virtual host:

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;
    }
}

Magdagdag ng mga virtual host sa /etc/hosts file:

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

HTTP server emulator

Bilang isang HTTP server emulator ang gagamitin namin nodejs-stub-server mula sa Maxim Ignatenko

Walang rpm ang Nodejs-stub-server. Dito https://github.com/patsevanton/nodejs-stub-server lumikha ng rpm para dito. rpm ay bubuuin gamit ang Fedora Copr

I-install ang nodejs-stub-server package sa upstream nginx rpm

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

Pagsusuri ng Stress

Nagsasagawa kami ng pagsubok gamit ang benchmark ng Apache.

I-install ito:

yum install -y httpd-tools

Sinimulan namin ang pagsubok gamit ang Apache benchmark mula sa 5 magkakaibang server:

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

Pag-set up ng Grafana

Hindi ka makakahanap ng dashboard sa opisyal na website ng Grafana.

Samakatuwid, gagawin namin ito sa pamamagitan ng kamay.

Mahahanap mo ang aking naka-save na dashboard dito.

Kailangan mo ring lumikha ng isang variable ng talahanayan na may mga nilalaman nginx.access_log.
Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Singlestat Kabuuang Kahilingan:

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

Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Mga Nabigong Kahilingan sa Singlestat:

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

Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Porsyento ng Nabigong Singlestat:

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 utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Singlestat Avg na Oras ng Pagtugon:

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

Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Singlestat Max na Oras ng Pagtugon:

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

Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Katayuan ng Bilang:

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

Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Upang makapag-output ng data tulad ng isang pie, kailangan mong i-install ang plugin at i-restart ang grafana.

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

Katayuan ng Pie TOP 5:

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 utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Dagdag pa, magbibigay ako ng mga kahilingan nang walang mga screenshot:

Bilangin ang 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

Timing ng Tugon:

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

Upstream na oras ng pagtugon (1st upstream na oras ng pagtugon):

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

Katayuan ng Bilang ng Talahanayan para sa lahat ng vhost:

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

Pangkalahatang view ng dashboard

Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Paghahambing ng avg() at quantile()

avg()
Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse
dami()
Nginx-log-collector utility mula sa Avito para sa pagpapadala ng nginx logs sa Clickhouse

Konklusyon:

Umaasa ako na ang komunidad ay makibahagi sa pagbuo/pagsubok at paggamit ng nginx-log-collector.
At kapag may nagpatupad ng nginx-log-collector, sasabihin nila sa iyo kung magkano ang na-save nila sa disk, RAM, at CPU.

Mga channel sa Telegram:

Millisecond:

Kung kanino mahalaga ang millisecond, mangyaring sumulat o bumoto dito problema.

Pinagmulan: www.habr.com

Magdagdag ng komento