„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Šiame straipsnyje bus aptariamas projektas nginx-log-collector, kuri nuskaitys nginx žurnalus ir išsiųs juos į Clickhouse klasterį. Paprastai žurnalams naudojama ElasticSearch. Clickhouse reikalauja mažiau resursų (vietas diske, RAM, procesoriaus). „Clickhouse“ duomenis įrašo greičiau. Clickhouse suspaudžia duomenis, todėl diske esantys duomenys tampa dar kompaktiškesni. Clickhouse pranašumai matomi 2 ataskaitos skaidrėse Kaip VK įterpia duomenis į ClickHouse iš dešimčių tūkstančių serverių.

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Norėdami peržiūrėti analizę pagal žurnalus, sukurkime „Grafana“ prietaisų skydelį.

Kam rūpi, sveiki atvykę po katinu.

Įdiekite nginx, grafana standartiniu būdu.

Įdiekite clickhouse klasterį su ansible-playbook iš Denisas Proskurinas.

Duomenų bazės ir lentelių kūrimas „Clickhouse“.

Tai failą Aprašytos SQL užklausos, skirtos kurti duomenų bazes ir lenteles nginx-log-collector programoje Clickhouse.

Kiekvieną užklausą paeiliui pateikiame kiekviename Clickhouse klasterio serveryje.

Svarbi pastaba. Šioje eilutėje logs_cluster turėtų būti pakeistas klasterio pavadinimu iš failo clickhouse_remote_servers.xml tarp „remote_servers“ ir „shard“.

ENGINE = Distributed('logs_cluster', 'nginx', 'access_log_shard', rand())

Įdiegti ir konfigūruoti nginx-log-collector-rpm

Nginx-log-collector neturi apsisukimų per minutę. Čia https://github.com/patsevanton/nginx-log-collector-rpm sukurti jam apsukų skaičių. rpm bus pastatytas naudojant Fedora Copr

Įdiekite 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

Redaguoti konfigūraciją /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/

Nginx nustatymas

Bendra nginx konfigūracija:

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

Vienas virtualus pagrindinis kompiuteris:

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

Pridėkite virtualius pagrindinius kompiuterius prie /etc/hosts failo:

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

HTTP serverio emuliatorius

Mes naudosime kaip HTTP serverio emuliatorių nodejs-stub-server nuo Maksimas Ignatenko

nodejs-stub-server neturi rpm. Čia https://github.com/patsevanton/nodejs-stub-server sukurti jam apsukų skaičių. rpm bus pastatytas naudojant Fedora Copr

Įdiekite „nodejs-stub-server“ paketą prieš nginx rpm

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

Testavimas nepalankiausiomis sąlygomis

Testavimas atliekamas naudojant Apache etaloną.

Įdiekite jį:

yum install -y httpd-tools

Pradedame testuoti naudodami „Apache“ etaloną iš 5 skirtingų serverių:

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“ nustatymas

Oficialioje „Grafana“ svetainėje prietaisų skydelio nerasite.

Todėl tai darysime rankomis.

Galite rasti mano išsaugotą prietaisų skydelį čia.

Taip pat turite sukurti lentelės kintamąjį su turiniu nginx.access_log.
„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Iš viso „Singlestat“ užklausų:

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

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Nepavykusios „Singlestat“ užklausos:

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

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Singlestat nesėkmių procentas:

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

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Singlestat vidutinis atsako laikas:

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

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Singlestat maksimalus atsako laikas:

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

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Skaičiavimo būsena:

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

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Norėdami išvesti duomenis kaip pyragą, turite įdiegti papildinį ir iš naujo įkelti grafana.

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

Pyrago TOP 5 būsena:

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

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Toliau pateiksiu užklausas be ekrano kopijų:

Skaičiuoti http_user_agent:

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

GoodRate/BadRate:

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

atsakymo laikas:

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

Atsakymo laikas prieš srovę (1-ojo prieš srovę atsako laikas):

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

Visų „vhost“ lentelių skaičiaus būsena:

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

Bendras prietaisų skydelio vaizdas

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Avg() ir kvantilio() palyginimas

vid.()
„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“
kvantilis ()
„Nginx-log-collector“ programa iš „Avito“, skirta „nginx“ žurnalams siųsti į „Clickhouse“

Išvada:

Tikimės, kad bendruomenė įsitrauks į nginx-log-collector kūrimą / testavimą ir naudojimą.
Ir kai kas nors įdiegs nginx-log-collector, jis pasakys, kiek sutaupė disko, RAM, procesoriaus.

Telegramos kanalai:

Milisekundės:

Kam rūpi milisekundės, rašykite arba balsuokite, prašau emisija.

Šaltinis: www.habr.com

Добавить комментарий