Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Cet article discutera du projet nginx-log-collecteur, qui lira les journaux nginx et les enverra au cluster Clickhouse. Habituellement, 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, ce qui rend les données sur disque encore plus compactes. Les avantages de Clickhouse sont visibles dans 2 slides du rapport Comment VK insère les données dans ClickHouse à partir de dizaines de milliers de serveurs.

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Pour afficher les analyses basées sur les journaux, nous allons créer un tableau de bord pour Grafana.

Toute personne intéressée, bienvenue sur Cat.

Installez nginx, grafana de la manière standard.

Installation d'un cluster Clickhouse à l'aide d'ansible-playbook à partir de Denis Proskurine.

Création de bases de données et de tables dans Clickhouse

Dans ce dossier Les requêtes SQL pour créer des bases de données et des tables pour nginx-log-collector dans Clickhouse sont décrites.

Nous effectuons chaque requête une par une sur chaque serveur du cluster Clickhouse.

Note importante. Dans cette ligne, logs_cluster doit être remplacé par le nom de votre cluster provenant du 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 créez un RPM pour cela. rpm sera compilé en utilisant Copr Fedora

Installez le package 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

Modifiez la configuration /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/

Configuration de nginx

Configuration générale de 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 hôte virtuel :

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

Ajoutez des hôtes virtuels au fichier /etc/hosts :

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

Émulateur de serveur HTTP

En tant qu'émulateur de serveur HTTP, nous utiliserons serveur nodejs-stub à partir de Maxime Ignatenko

Nodejs-stub-server n'a pas de RPM. Ici https://github.com/patsevanton/nodejs-stub-server créez un RPM pour cela. rpm sera compilé en utilisant Copr Fedora

Installer le package nodejs-stub-server sur le rpm nginx en amont

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

Tests de résistance

Nous effectuons des tests à l'aide du benchmark Apache.

Installez-le:

yum install -y httpd-tools

Nous commençons les tests en utilisant le benchmark Apache à partir de 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 le ferons donc à la main.

Vous pouvez trouver mon tableau de bord enregistré ici.

Vous devez également créer une variable de table avec le contenu nginx.access_log.
Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Requêtes totales Singlestat :

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

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Requêtes singlestat ayant échoué :

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

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Pourcentage d'échec du 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

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Temps de réponse moyen d'un seul statistique :

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

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Temps de réponse maximum Singlestat :

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

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Statut du compte :

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

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Pour afficher des données comme un gâteau, vous devez installer le plugin et redémarrer grafana.

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

Statut du TOP 5 de la tarte :

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

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

De plus, je donnerai des demandes sans captures d'écran :

Comptez http_user_agent :

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

Bon taux/mauvais taux :

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

Délai de réponse :

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

Temps de réponse amont (1er temps de réponse amont) :

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

Statut du nombre de tables pour tous les hôtes virtuels :

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

Vue générale du tableau de bord

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Comparaison de avg() et quantile()

moy()
Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse
quantile()
Utilitaire Nginx-log-collector d'Avito pour envoyer des journaux nginx à Clickhouse

Conclusion:

J'espère que la communauté s'impliquera dans le développement/test et l'utilisation de nginx-log-collector.
Et lorsque quelqu'un implémentera nginx-log-collector, il vous dira combien il a économisé sur le disque, la RAM et le CPU.

Chaînes de télégramme :

Millisecondes :

Pour qui les millisecondes comptent, veuillez écrire ou voter ici aide.

Source: habr.com

Ajouter un commentaire