Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

V tomto článku sa bude načrtávať projekt nginx-log-collector, ktorý bude čítať logy nginx a posielať ich do klastru Clickhouse. Zvyčajne sa na logy používa ElasticSearch. Pre Clickhouse je potrebné menej zdrojov (diskový priestor, RAM, CPU). Clickhouse rýchlejšie zapisuje dáta. Clickhouse komprimuje dáta, čo robí dáta na disku ešte kompaktnejšími. Výhody Clickhouse sú viditeľné v dvoch slaidoch z prezentácie Ako VK vkladá dáta do ClickHouse zo státisícov serverov.

Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Na zobrazenie analytiky logov vytvoríme dashboard pre Grafana.

Kto má záujem, vitajte pod kat.

Inštalujeme nginx, grafana štandardným spôsobom.

Inštalujeme klaster clickhouse pomocou ansible-playbook od Denisa Proskurina.

Vytvorenie db a tabuliek v Clickhouse

V tomto súbore sú opísané SQL dotazy na vytvorenie db a tabuliek pre nginx-log-collector v Clickhouse.

Každý dotaz robíme postupne na každom serveri klastru Clickhouse.

Dôležitá poznámka. V tomto riadku treba nahradiť logs_cluster vaším názvom klastru zo súboru clickhouse_remote_servers.xml medzi "remote_servers" a "shard".

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

Inštalácia a nastavenie nginx-log-collector-rpm

Nginx-log-collector nemá rpm. Tu https://github.com/patsevanton/nginx-log-collector-rpm vytvárame preň rpm. Rpm sa bude skladať pomocou Fedora Copr

Inštalujeme rpm balík 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

Upravujeme konfiguráciu /etc/nginx-log-collector/config.yaml:

  .......
  upload:
    table: nginx.access_log
    dsn: http://ip-adresa-klastra-clickhouse:8123/

- tag: "nginx_error:"
  format: error  # access | error
  buffer_size: 1048576
  upload:
    table: nginx.error_log
    dsn: http://ip-adresa-klastra-clickhouse:8123/

Nastavenie nginx

Celková konfigurácia 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;
}

Virtuálny host jeden:

vhost1.conf:

upstream backend {
    server ip-adresa-servera-s-stub_http_server:8080;
    server ip-adresa-servera-s-stub_http_server:8080;
    server ip-adresa-servera-s-stub_http_server:8080;
    server ip-adresa-servera-s-stub_http_server:8080;
    server ip-adresa-servera-s-stub_http_server:8080;
}

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

Pridávame do súboru /etc/hosts virtuálne hosty:

ip-adresa-servera-s-nginx vhost1

Emulátor HTTP servera

Ako emulátor HTTP servera použijeme nodejs-stub-server od Maxim Ignatenko

Nodejs-stub-server nemá rpm. Tu https://github.com/patsevanton/nodejs-stub-server vytvárame preň rpm. Rpm sa bude skladať pomocou Fedora Copr

Inštalujeme na upstream nginx rpm balík 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

Záťažové testovanie

Testovanie vykonávame pomocou Apache benchmark.

Inštalujeme ho:

yum install -y httpd-tools

Spúšťame testovanie pomocou Apache benchmark z 5 rôznych serverov:

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

Nastavenie Grafana

Na oficiálnej stránke Grafana nenájdete dashboard.

Preto ho budeme robiť ručne.

Môj uložený dashboard nájdete tu.

Taktiež potrebujete vytvoriť premennú table s obsahom nginx.access_log.
Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Singlestat Celkové požiadavky:

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

Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Singlestat Neúspešné požiadavky:

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

Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Singlestat Percento neúspešných požiadaviek:

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 nástroj od Avita na odosielanie logov nginx do Clickhouse

Singlestat Priemerný čas odozvy:

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

Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Singlestat Maximálny čas odozvy:

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

Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Počet stavov:

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

Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Na zobrazenie údajov ako koláč je potrebné nainštalovať plugin a reštartovať grafanu.

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

Koláč TOP 5 stavov:

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 nástroj od Avita na odosielanie logov nginx do Clickhouse

Ďalej budem uvádzať dotazy bez screenshotov:

Počet http_user_agent:

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

Dobrý pomer/Zlý pomer:

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

Časová odozva:

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

Čas odpovede upstream (čas odpovede 1. upstream):

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

Tabuľka počtu stavov pre všetky vhost:

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

Celkový pohľad na dashboard

Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Porovnanie avg() a quantile()

avg()
Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse
quantile()
Nginx-log-collector nástroj od Avita na odosielanie logov nginx do Clickhouse

Výstup:

Dúfam, že sa komunita pripojí k vývoju/testovaniu a používaniu nginx-log-collector.
A niekto, kto implementuje nginx-log-collector, povie, koľko ušetril na disku, RAM a CPU.

Telegram kanály:

Millisekundy:

Kto považuje milisekundy za dôležité, napíšte alebo prosím hlasujte v tomto issue.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster