Cet article portera sur le projet , 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


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 .
Création de bd et de tables dans Clickhouse
Dans ce 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 nous lui créons un rpm. Le rpm sera construit avec
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-collectorNous 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 à partir de
Nodejs-stub-server n'a pas de rpm. Ici nous lui créons un rpm. Le rpm sera construit avec
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_serverTest de charge
Nous effectuons des tests avec Apache benchmark.
Nous l'installons :
yum install -y httpd-toolsDé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; doneConfiguration 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é .
Vous devez également créer une variable table avec le contenu nginx.access_log.

Total des demandes Singlestat :
SELECT
1 as t,
count(*) as c
FROM $table
WHERE $timeFilter GROUP BY t
É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
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
Temps de réponse moyen Singlestat :
SELECT
1, avg(request_time) FROM $table
WHERE $timeFilter GROUP BY 1
Temps de réponse maximum Singlestat :
SELECT
1 as t, max(request_time) as c
FROM $table
WHERE $timeFilter GROUP BY t
Compter le statut :
$columns(status, count(*) as c) from $table
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 restartStatut 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
Je vais donner des requêtes sans captures d'écran :
Compter http_user_agent :
$columns(http_user_agent, count(*) c) FROM $tableTaux Bon/Taux Mauvais :
$rate(countIf(status = 200) AS good, countIf(status != 200) AS bad) FROM $tableTemporisation de la réponse :
$rate(avg(request_time) as request_time) FROM $tableTemps de réponse en amont (première réponse en amont) :
$rate(avg(arrayElement(upstream_response_time,1)) as upstream_response_time) FROM $tableCompter le statut pour tous les vhosts :
$columns(status, count(*) as c) from $tableVue d'ensemble du tableau de bord



Comparaison avg() et quantile()
avg()

quantile()

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 .
Source : habr.com
