Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Cet article portera sur le projet nginx-log-collector, qui lira les journaux nginx et les enverra vers un cluster Clickhouse. En général, ElasticSearch est utilisé pour les journaux. Clickhouse nécessite moins de ressources (espace disque, RAM, CPU). Clickhouse enregistre les données plus rapidement. Clickhouse compresse les données, rendant ainsi les données sur disque encore plus compactes. Les avantages de Clickhouse sont visibles sur 2 diapositives de la présentation Comment VK insère des données dans ClickHouse depuis des dizaines de milliers de serveurs.

Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Pour visualiser l'analyse des journaux, nous créerons un tableau de bord pour Grafana.

Pour ceux que cela intéresse, bienvenue sous le kat.

Nous installons nginx et grafana de manière standard.

Nous installons un cluster clickhouse via ansible-playbook de Denis Proskourine.

Création de bd et de tables dans Clickhouse

Dans ce fichier sont décrits les requêtes SQL pour créer la bd et les tables pour nginx-log-collector dans Clickhouse.

Chaque requête est exécutée successivement sur chaque serveur du cluster Clickhouse.

Remarque importante. Dans cette ligne, logs_cluster doit être remplacé par le nom de votre cluster dans le fichier clickhouse_remote_servers.xml entre "remote_servers" et "shard".

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

Installation et configuration de nginx-log-collector-rpm

Nginx-log-collector n'a pas de rpm. Ici https://github.com/patsevanton/nginx-log-collector-rpm nous lui créons un rpm. Le rpm sera construit avec Fedora Copr

Installation du paquet 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

Nous modifions la configuration /etc/nginx-log-collector/config.yaml :

  .......
  upload:
    table: nginx.access_log
    dsn: http://adresse-ip-du-cluster-clickhouse:8123/

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

Configuration de nginx

Configuration générale de nginx :

utilisateur  nginx;
processus_travail  automatique;

#error_log  /var/log/nginx/error.log avertir;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  principal  '$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  principal;

    proxy_ignore_client_abort on;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
}

Hôte virtuel unique :

vhost1.conf :

upstream backend {
    serveur ip-adresse-serveur-stub_http_server:8080;
    serveur ip-adresse-serveur-stub_http_server:8080;
    serveur ip-adresse-serveur-stub_http_server:8080;
    serveur ip-adresse-serveur-stub_http_server:8080;
    serveur ip-adresse-serveur-stub_http_server:8080;
}

serveur {
    écoute   80;
    server_name vhost1;
    location / {
        proxy_pass http://backend;
    }
}

Ajout des hôtes virtuels dans le fichier /etc/hosts :

ip-adresse-serveur-nginx vhost1

Émulateur de serveur HTTP

Nous allons utiliser comme émulateur de serveur HTTP nodejs-stub-server à partir de Maxim Ignatenko

Nodejs-stub-server n'a pas de rpm. Ici https://github.com/patsevanton/nodejs-stub-server nous lui créons un rpm. Le rpm sera construit avec Fedora Copr

Installation du paquet rpm nodejs-stub-server sur upstream nginx

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

Test de charge

Nous effectuons des tests avec Apache benchmark.

Nous l'installons :

yum install -y httpd-tools

Démarrons les tests avec Apache benchmark depuis 5 serveurs différents :

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

Configuration de Grafana

Vous ne trouverez pas de tableau de bord sur le site officiel de Grafana.

Nous allons donc le créer manuellement.

Vous pouvez trouver votre tableau de bord enregistré ici.

Vous devez également créer une variable table avec le contenu nginx.access_log.
Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Total des demandes Singlestat :

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

Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Échecs des demandes 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 est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Pourcentage d'échecs 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 est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Temps de réponse moyen Singlestat :

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

Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Temps de réponse maximum Singlestat :

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

Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Compter le statut :

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

Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Pour afficher les données sous forme de graphique circulaire, vous devez installer le plugin et redémarrer grafana.

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

Statut des 5 principaux en circulaire :

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

Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Je vais donner des requêtes sans captures d'écran :

Compter http_user_agent :

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

Taux Bon/Taux Mauvais :

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

Temporisation de la réponse :

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

Temps de réponse en amont (première réponse en amont) :

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

Compter le statut pour tous les vhosts :

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

Vue d'ensemble du tableau de bord

Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Comparaison avg() et quantile()

avg()
Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse
quantile()
Nginx-log-collector est un outil d'Avito pour envoyer des journaux nginx vers Clickhouse

Conclusion :

J'espère que la communauté se joindra au développement/test et à l'utilisation de nginx-log-collector.
Et quelqu'un lorsque nginx-log-collector sera mis en œuvre racontera combien d'espace disque, de RAM, de CPU a été économisé.

Canaux Telegram :

Millisecondes :

Ceux qui se soucient des millisecondes, écrivez ou votez s'il vous plaît dans cette issue.

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster