In diesem Artikel wird das Projekt behandelt, das die nginx-Logs liest und sie an einen Clickhouse-Cluster sendet. Üblicherweise werden für Logs ElasticSearch verwendet. Clickhouse benötigt weniger Ressourcen (Speicherplatz, RAM, CPU). Clickhouse schreibt Daten schneller. Clickhouse komprimiert Daten, was den Speicherplatz auf der Festplatte noch effizienter macht. Die Vorteile von Clickhouse sind in 2 Folien der Präsentation sichtbar.


Um Analysen zu den Logs anzuzeigen, erstellen wir ein Dashboard für Grafana.
Wer interessiert ist, ist unter dem Schnitt willkommen.
Wir installieren nginx und grafana auf die übliche Weise.
Wir installieren den Clickhouse-Cluster mit dem Ansible-Playbook von .
Erstellung der DB und Tabellen in Clickhouse
In dieser sind die SQL-Abfragen zur Erstellung der DB und Tabellen für den nginx-log-collector in Clickhouse beschrieben.
Jede Abfrage führen wir nacheinander auf jedem Server des Clickhouse-Clusters aus.
Wichtiger Hinweis: In dieser Zeile muss logs_cluster durch den Namen Ihres Clusters 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 erstellen wir ein rpm. Das rpm wird mit Hilfe von
Wir installieren 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-collectorWir bearbeiten 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 ip-adresse-des-servers-mit-stub_http_server:8080;
server ip-adresse-des-servers-mit-stub_http_server:8080;
server ip-adresse-des-servers-mit-stub_http_server:8080;
server ip-adresse-des-servers-mit-stub_http_server:8080;
server ip-adresse-des-servers-mit-stub_http_server:8080;
}
server {
listen 80;
server_name vhost1;
location / {
proxy_pass http://backend;
}
}Fügen Sie virtuelle Hosts in die Datei /etc/hosts ein:
ip-adresse-des-servers-mit-nginx vhost1HTTP-Server-Emulator
Als HTTP-Server-Emulator verwenden wir ab
Nodejs-stub-server hat kein rpm. Hier erstellen wir ein rpm. Das rpm wird mit Hilfe von
Installieren Sie das rpm-Paket nodejs-stub-server auf dem 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_serverLasttest
Wir führen den Test mit Apache Benchmark durch.
Wir installieren es:
yum install -y httpd-toolsWir starten 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 einrichten
Auf der offiziellen Website von Grafana finden Sie kein Dashboard.
Deshalb werden wir es manuell machen.
Ihr gespeichertes Dashboard finden Sie .
Sie müssen auch eine Variable table mit dem Inhalt erstellen nginx.access_log.

Singlestat Gesamtanforderungen:
SELECT
1 as t,
count(*) as c
FROM $table
WHERE $timeFilter GROUP BY t
Singlestat Fehlgeschlagene Anforderungen:
SELECT
1 as t,
count(*) as c
FROM $table
WHERE $timeFilter AND status NOT IN (200, 201, 401) GROUP BY t
Singlestat Fehlerrate:
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
Singlestat Durchschnittliche Reaktionszeit:
SELECT
1, avg(request_time) FROM $table
WHERE $timeFilter GROUP BY 1
Singlestat Maximale Reaktionszeit:
SELECT
1 as t, max(request_time) as c
FROM $table
WHERE $timeFilter GROUP BY t
Zählstatus:
$columns(status, count(*) as c) from $table
Um die Daten als Tortendiagramm anzuzeigen, müssen Sie ein Plugin installieren und Grafana neu starten.
grafana-cli plugins install grafana-piechart-panel
service grafana-server restartTorte TOP 5 Status:
SELECT
1,
/* gefälschter Zeitstempelwert */
status,
sum(status) AS Reqs
FROM $table
WHERE $timeFilter
GROUP BY status
ORDER BY Reqs desc
LIMIT 5
Ich werde die Abfragen weiter ohne Screenshots bereitstellen:
Zähl http_user_agent:
$columns(http_user_agent, count(*) c) FROM $tableGoodRate/BadRate:
$rate(countIf(status = 200) AS good, countIf(status != 200) AS bad) FROM $tableReaktionszeiten:
$rate(avg(request_time) as request_time) FROM $tableUpstream-Antwortzeit (Antwortzeit des ersten Upstreams):
$rate(avg(arrayElement(upstream_response_time,1)) as upstream_response_time) FROM $tableTabelle Zählstatus für alle vhosts:
$columns(status, count(*) as c) from $tableGesamtansicht des Dashboards



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

quantile()

Ausgabe:
Ich hoffe, die Community wird sich an der Entwicklung, dem Testen und der Nutzung des nginx-log-collectors beteiligen.
Und jemand, der den nginx-log-collector implementiert, wird sagen, wie viel Speicherplatz, RAM und CPU gespart wurde.
Telegram-Kanäle:
Millisekunden:
Wer Millisekunden wichtig ist, schreibt bitte oder stimmt in diesem .
Quelle: habr.com
