In diesem Artikel wird das Projekt , das Nginx-Logs liest und sie an ein Clickhouse-Cluster sendet, behandelt. Üblicherweise werden für Logs ElasticSearch verwendet. Clickhouse benötigt weniger Ressourcen (Speicherplatz, RAM, CPU). Clickhouse schreibt Daten schneller. Clickhouse komprimiert die Daten, wodurch diese auf der Festplatte noch kompakter werden. Die Vorteile von Clickhouse sind auf 2 Folien aus dem Vortrag zu sehen.


Um die Analytik der Logs anzuzeigen, erstellen wir ein Dashboard für Grafana.
Wer interessiert ist, ist herzlich eingeladen, weiterlesen.
Installieren Sie Nginx und Grafana auf die übliche Weise.
Installieren Sie das Clickhouse-Cluster mit dem Ansible-Playbook von .
Erstellung von Datenbanken und Tabellen in Clickhouse
In dieser sind die SQL-Abfragen für die Erstellung von Datenbanken und Tabellen für den nginx-log-collector in Clickhouse beschrieben.
Führen Sie jede Abfrage nacheinander auf jedem Server im Clickhouse-Cluster aus.
Wichtiger Hinweis. In dieser Zeile muss 'logs_cluster' durch Ihren Cluster-Namen aus der Datei clickhouse_remote_servers.xml zwischen "remote_servers" und "shard" ersetzt werden.
ENGINE = Distributed('logs_cluster', 'nginx', 'access_log_shard', rand())Installation und Konfiguration des nginx-log-collector-rpm
Nginx-Log-Collector hat kein RPM. Hier Wir erstellen ihm ein rpm. Das rpm wird mit Hilfe von
Installieren Sie das RPM-Paket 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-collectorBearbeiten Sie die Konfiguration /etc/nginx-log-collector/config.yaml:
.......
upload:
table: nginx.access_log
dsn: http://ip-Adresse-des-Clickhouse-Clusters:8123/
- tag: "nginx_error:"
format: error # access | error
buffer_size: 1048576
upload:
table: nginx.error_log
dsn: http://ip-Adresse-des-Clickhouse-Clusters:8123/Konfiguration von Nginx
Allgemeine Nginx-Konfiguration:
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;
}
Virtueller Host eins:
vhost1.conf:
upstream backend {
server server-ip-address-with-stub_http_server:8080;
server server-ip-address-with-stub_http_server:8080;
server server-ip-address-with-stub_http_server:8080;
server server-ip-address-with-stub_http_server:8080;
server server-ip-address-with-stub_http_server:8080;
}
server {
listen 80;
server_name vhost1;
location / {
proxy_pass http://backend;
}
}Fügen Sie in die Datei /etc/hosts virtuelle Hosts hinzu:
server-ip-address-with-nginx vhost1HTTP-Server-Emulator
Als HTTP-Server-Emulator verwenden wir ab
Nodejs-stub-server hat kein rpm. Hier Wir erstellen ihm ein rpm. Das rpm wird mit Hilfe von
Wir installieren das upstream nginx rpm-Paket 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_serverLasttest
Der Test wird mit Apache Benchmark durchgeführt.
Wir installieren es:
yum install -y httpd-toolsStarten Sie den Test mit Apache Benchmark von 5 verschiedenen Servern:
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; doneGrafana konfigurieren
Auf der offiziellen Grafana-Website finden Sie kein Dashboard.
Deshalb werden wir es manuell erstellen.
Mein gespeichertes Dashboard finden Sie .
Sie müssen auch eine Variable "table" mit dem Inhalt erstellen: nginx.access_log.

Singlestat Gesamtanforderungen:
WÄHLEN
1 als t,
zähle(*) als c
VON $table
WO $timeFilter GRUPPIERE NACH t
Anzahl fehlgeschlagener Einzelstatistiken:
WÄHLEN
1 als t,
zähle(*) als c
VON $table
WO $timeFilter UND status NICHT IN (200, 201, 401) GRUPPIERE NACH t
Anteil der Fehlgeschlagenen Statistiken:
WÄHLEN
1 als t, (summe(status = 500 oder status = 499)/summe(status = 200 oder status = 201 oder status = 401))*100 VON $table
WO $timeFilter GRUPPIERE NACH t
Durchschnittliche Antwortzeit:
WÄHLEN
1, avg(request_time) VON $table
WO $timeFilter GRUPPIERE NACH 1
Maximale Antwortzeit:
WÄHLEN
1 als t, max(request_time) als c
VON $table
WO $timeFilter GRUPPIERE NACH t
Status zählen:
$columns(status, zähle(*) als c) VON $table
Um Daten als Torte anzuzeigen, muss das Plugin installiert und Grafana neu gestartet werden.
grafana-cli plugins install grafana-piechart-panel
service grafana-server neu startenTorte TOP 5 Status:
WÄHLEN
1, /* gefälschter Zeitstempelwert */
status,
sum(status) AS Reqs
VON $table
WO $timeFilter
GRUPPIERE NACH status
ORDER BY Reqs desc
LIMIT 5
Ich werde die Anfragen ohne Screenshots weitergeben:
HTTP User-Agent zählen:
$columns(http_user_agent, zähle(*) c) VON $tableGuteRate/SchlechteRate:
$rate(countIf(status = 200) AS good, countIf(status != 200) AS bad) VON $tableAntwortzeit:
$rate(avg(request_time) als request_time) VON $tableAntwortzeit des Upstreams (Antwortzeit des ersten Upstreams):
$rate(avg(arrayElement(upstream_response_time,1)) als upstream_response_time) VON $tableTabellenstatus zählen für alle vhosts:
$columns(status, zähle(*) als c) VON $tableGesamter Dashboard Blick



Vergleich von avg() und quantile()
avg()

quantile()

Fazit:
Ich hoffe, die Community beteiligt sich an der Entwicklung/Testung und Nutzung des nginx-log-collectors.
Und wenn jemand den nginx-log-collector implementiert, wird er erzählen, wie viel Speicher, RAM und CPU gespart wurden.
Telegram-Kanäle:
Millisekunden:
Wenn Millisekunden für Sie wichtig sind, schreiben Sie bitte oder stimmen Sie in diesem .
Quelle: habr.com
