Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Acest articol va discuta despre proiect nginx-log-collector, care va citi jurnalele nginx, le trimite către clusterul Clickhouse. De obicei, ElasticSearch este folosit pentru jurnalele. Clickhouse necesită mai puține resurse (spațiu pe disc, RAM, CPU). Clickhouse scrie datele mai rapid. Clickhouse comprimă datele, ceea ce face ca datele de pe disc să fie și mai compacte. Beneficiile Clickhouse pot fi văzute în 2 slide-uri din raport Cum inserează VK date în ClickHouse de la zeci de mii de servere.

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Pentru a vizualiza analizele după jurnale, să creăm un tablou de bord pentru Grafana.

Cui îi pasă, bine ai venit sub pisica.

Instalați nginx, grafana în modul standard.

Instalați clusterul clickhouse cu ansible-playbook de la Denis Proskurin.

Crearea unei baze de date și a tabelelor în Clickhouse

În acest fişier Sunt descrise interogări SQL pentru crearea de baze de date și tabele pentru nginx-log-collector în Clickhouse.

Facem fiecare cerere pe rând pe fiecare server al cluster-ului Clickhouse.

Notă importantă. În această linie, logs_cluster ar trebui să fie înlocuit cu numele dvs. de cluster din fișierul clickhouse_remote_servers.xml între „remote_servers” și „shard”.

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

Instalarea și configurarea nginx-log-collector-rpm

Nginx-log-collector nu are un rpm. Aici https://github.com/patsevanton/nginx-log-collector-rpm creați rpm pentru el. rpm va fi construit folosind Fedora Copr

Instalați pachetul 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

Editați configurația /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/

Configurarea nginx

Configurație generală 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;
}

Gazdă virtuală una:

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

Adăugați gazde virtuale în fișierul /etc/hosts:

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

Emulator de server HTTP

Vom folosi ca emulator de server HTTP nodejs-stub-server din Maxim Ignatenko

nodejs-stub-server nu are rpm. Aici https://github.com/patsevanton/nodejs-stub-server creați rpm pentru el. rpm va fi construit folosind Fedora Copr

Instalați pachetul nodejs-stub-server pe rpm nginx în amonte

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

Testare stresanta

Testarea este efectuată folosind benchmark Apache.

Instalează-l:

yum install -y httpd-tools

Începem să testăm folosind benchmark Apache de pe 5 servere diferite:

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

Înființarea Grafana

Nu veți găsi un tablou de bord pe site-ul oficial Grafana.

Prin urmare, o vom face manual.

Puteți găsi tabloul de bord salvat aici.

De asemenea, trebuie să creați o variabilă de tabel cu conținutul nginx.access_log.
Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Număr total de solicitări:

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

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Solicitări eșuate Singlestat:

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

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Procent de eșec de stat unic:

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

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Timp mediu de răspuns la un singur stat:

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

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Timp maxim de răspuns singlestat:

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

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Stare numărare:

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

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Pentru a scoate date ca o plăcintă, trebuie să instalați pluginul și să reîncărcați grafana.

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

Piesa TOP 5 Stare:

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

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

În continuare, voi da cereri fără capturi de ecran:

Număr 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

timpul de răspuns:

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

Timp de răspuns în amonte (timpul de răspuns al primului în amonte):

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

Starea numărului tabelului pentru toate vhost-urile:

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

Vedere generală a tabloului de bord

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Compararea avg() și quantile()

medie()
Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse
cuantilă()
Utilitar Nginx-log-collector de la Avito pentru trimiterea jurnalelor nginx către Clickhouse

Concluzie:

Sperăm că comunitatea se va implica în dezvoltarea/testarea și utilizarea nginx-log-collector.
Și când cineva implementează nginx-log-collector, vă va spune cât de mult a economisit disc, RAM, CPU.

Canale Telegram:

Milisecunde:

Cui îi pasă de milisecunde, scrie sau votează, te rog, în asta problema.

Sursa: www.habr.com

Adauga un comentariu