Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Questo articolo discuterà del progetto nginx-log-collector, che leggerà i log nginx e li invierà al cluster Clickhouse. Di solito ElasticSearch viene utilizzato per i log. Clickhouse richiede meno risorse (spazio su disco, RAM, CPU). Clickhouse registra i dati più velocemente. Clickhouse comprime i dati, rendendo i dati su disco ancora più compatti. I vantaggi di Clickhouse sono visibili in 2 slide del report Come VK inserisce i dati in ClickHouse da decine di migliaia di server.

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Per visualizzare le analisi basate sui log, creeremo una dashboard per Grafana.

Chiunque sia interessato, benvenuto su cat.

Installa nginx, grafana nel modo standard.

Installazione di un cluster clickhouse utilizzando ansible-playbook da Denis Proskurin.

Creazione di database e tabelle in Clickhouse

In questo file Vengono descritte le query SQL per la creazione di database e tabelle per nginx-log-collector in Clickhouse.

Effettuiamo ogni richiesta una per una su ciascun server nel cluster Clickhouse.

Nota importante. In questa riga, logs_cluster deve essere sostituito con il nome del cluster dal file clickhouse_remote_servers.xml tra "remote_servers" e "shard".

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

Installazione e configurazione nginx-log-collector-rpm

Nginx-log-collector non ha un numero di giri. Qui https://github.com/patsevanton/nginx-log-collector-rpm creare un numero di giri per questo. rpm verrà compilato utilizzando Fedora Copr

Installa il pacchetto 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

Modifica la configurazione /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/

Configurazione di nginx

Configurazione generale di 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;
}

Un host virtuale:

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

Aggiungi host virtuali al file /etc/hosts:

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

Emulatore del server HTTP

Come emulatore del server HTTP utilizzeremo nodejs-stub-server от Maxim Ignatenko

Nodejs-stub-server non ha un numero di giri. Qui https://github.com/patsevanton/nodejs-stub-server creare un numero di giri per questo. rpm verrà compilato utilizzando Fedora Copr

Installa il pacchetto nodejs-stub-server sull'rpm nginx upstream

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

Prove di stress

Effettuiamo test utilizzando il benchmark Apache.

Installalo:

yum install -y httpd-tools

Iniziamo i test utilizzando il benchmark Apache da 5 server diversi:

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

Impostazione Grafana

Non troverai una dashboard sul sito ufficiale di Grafana.

Pertanto, lo faremo a mano.

Puoi trovare la mia dashboard salvata qui.

È inoltre necessario creare una variabile di tabella con i contenuti nginx.access_log.
Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Richieste totali Singlestat:

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

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Richieste Singlestat non riuscite:

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

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Percentuale di errori 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

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Tempo medio di risposta Singlestat:

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

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Tempo di risposta massimo Singlestat:

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

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Stato del conteggio:

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

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Per visualizzare i dati come una torta, è necessario installare il plugin e riavviare grafana.

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

Stato TOP 5 della torta:

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

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Inoltre fornirò richieste senza screenshot:

Conta http_user_agent:

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

Voto buono/Tasso cattivo:

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

Tempi di risposta:

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

Tempo di risposta upstream (primo tempo di risposta upstream):

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

Stato del conteggio delle tabelle per tutti i vhost:

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

Vista generale del cruscotto

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Confronto tra avg() e quantile()

medio()
Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse
quantile()
Utilità Nginx-log-collector di Avito per l'invio di log nginx a Clickhouse

Conclusione:

Spero che la comunità venga coinvolta nello sviluppo/test e nell'utilizzo di nginx-log-collector.
E quando qualcuno implementa nginx-log-collector, ti dirà quanto ha risparmiato su disco, RAM e CPU.

Canali Telegram:

Millisecondi:

Per chi contano i millisecondi, per favore scrivi o vota qui problema.

Fonte: habr.com

Aggiungi un commento