Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

In diesem Artikel wird das Projekt nginx-log-collector, 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. Wie VK Daten aus zehntausenden Servern in ClickHouse eingibt.

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

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 Denis Proskurin.

Erstellung von Datenbanken und Tabellen in Clickhouse

In dieser Datei 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 https://github.com/patsevanton/nginx-log-collector-rpm Wir erstellen ihm ein rpm. Das rpm wird mit Hilfe von Fedora Copr

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-collector

Bearbeiten 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 vhost1

HTTP-Server-Emulator

Als HTTP-Server-Emulator verwenden wir nodejs-stub-server. ab Maxim Ignatenko

Nodejs-stub-server hat kein rpm. Hier https://github.com/patsevanton/nodejs-stub-server Wir erstellen ihm ein rpm. Das rpm wird mit Hilfe von Fedora Copr

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_server

Lasttest

Der Test wird mit Apache Benchmark durchgeführt.

Wir installieren es:

yum install -y httpd-tools

Starten 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; done

Grafana konfigurieren

Auf der offiziellen Grafana-Website finden Sie kein Dashboard.

Deshalb werden wir es manuell erstellen.

Mein gespeichertes Dashboard finden Sie hier.

Sie müssen auch eine Variable "table" mit dem Inhalt erstellen: nginx.access_log.
Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

Singlestat Gesamtanforderungen:

WÄHLEN
 1 als t,
 zähle(*) als c
 VON $table
 WO $timeFilter GRUPPIERE NACH t

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

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

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

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

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

Durchschnittliche Antwortzeit:

WÄHLEN
 1, avg(request_time) VON $table
 WO $timeFilter GRUPPIERE NACH 1

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

Maximale Antwortzeit:

WÄHLEN
 1 als t, max(request_time) als c
 VON $table
 WO $timeFilter GRUPPIERE NACH t

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

Status zählen:

$columns(status, zähle(*) als c) VON $table

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

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 starten

Torte 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

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

Ich werde die Anfragen ohne Screenshots weitergeben:

HTTP User-Agent zählen:

$columns(http_user_agent, zähle(*) c) VON $table

GuteRate/SchlechteRate:

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

Antwortzeit:

$rate(avg(request_time) als request_time) VON $table

Antwortzeit des Upstreams (Antwortzeit des ersten Upstreams):

$rate(avg(arrayElement(upstream_response_time,1)) als upstream_response_time) VON $table

Tabellenstatus zählen für alle vhosts:

$columns(status, zähle(*) als c) VON $table

Gesamter Dashboard Blick

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

Vergleich von avg() und quantile()

avg()
Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse
quantile()
Nginx-Log-Collector-Tool von Avito zum Senden von Nginx-Logs an Clickhouse

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 war das Problem.

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster