Este artigo abordará o projeto , que irá ler os logs do nginx e enviá-los para um cluster Clickhouse. Normalmente, para logs, utiliza-se o ElasticSearch. O Clickhouse requer menos recursos (espaço em disco, RAM, CPU). O Clickhouse grava dados mais rapidamente. O Clickhouse comprime os dados, tornando-os ainda mais compactos no disco. As vantagens do Clickhouse são evidentes em 2 slides da apresentação


Para visualizar a análise dos logs, criaremos um dashboard para o Grafana.
Quem tiver interesse, sinta-se à vontade para continuar.
Instalamos o nginx e o grafana da maneira padrão.
Instalamos o cluster Clickhouse usando o ansible-playbook de .
Criação de banco de dados e tabelas no Clickhouse
Neste estão descritas as consultas SQL para criar o banco de dados e tabelas para o nginx-log-collector no Clickhouse.
Executamos cada consulta sequencialmente em cada servidor do cluster Clickhouse.
Importante observar: nesta linha, logs_cluster deve ser substituído pelo nome do seu cluster do arquivo clickhouse_remote_servers.xml entre "remote_servers" e "shard".
ENGINE = Distributed('logs_cluster', 'nginx', 'access_log_shard', rand())Instalação e configuração do nginx-log-collector-rpm
Nginx-log-collector não possui rpm. Aqui Criamos o rpm para ele. O rpm será construído com o auxílio de
Instalamos o pacote 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-collectorEditamos o config /etc/nginx-log-collector/config.yaml:
.......
upload:
table: nginx.access_log
dsn: http://ip-endereço-do-cluster-clickhouse:8123/
- tag: "nginx_error:"
format: error # access | error
buffer_size: 1048576
upload:
table: nginx.error_log
dsn: http://ip-endereço-do-cluster-clickhouse:8123/Configuração do nginx
Configuração geral do nginx:
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;
}
Um host virtual:
vhost1.conf:
upstream backend {
server ip-endereço-do-servidor-com-stub_http_server:8080;
server ip-endereço-do-servidor-com-stub_http_server:8080;
server ip-endereço-do-servidor-com-stub_http_server:8080;
server ip-endereço-do-servidor-com-stub_http_server:8080;
server ip-endereço-do-servidor-com-stub_http_server:8080;
}
server {
listen 80;
server_name vhost1;
location \/ {
proxy_pass http:\/\/backend;
}
}Adicionando hosts virtuais ao arquivo \/etc\/hosts:
ip-endereço-do-servidor-com-nginx vhost1Emulador de servidor HTTP
Usaremos como emulador de servidor HTTP de
Nodejs-stub-server não possui rpm. Aqui Criamos o rpm para ele. O rpm será construído com o auxílio de
Instalando o pacote rpm nodejs-stub-server no 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_serverTestes de carga
Os testes são realizados com a ajuda do Apache benchmark.
Instalando-o:
yum install -y httpd-toolsIniciando o teste com Apache benchmark em 5 servidores diferentes:
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; doneConfiguração do Grafana
No site oficial do Grafana, você não encontrará um painel.
Portanto, faremos isso manualmente.
Meu painel salvo pode ser encontrado .
Você também precisa criar uma variável table com o conteúdo nginx.access_log.

Singlestat Total Requests:
SELECIONE
1 como t,
contagem(*) como c
DE $table
ONDE $timeFilter AGRUPAR POR t
Solicitações com Falha de Singlestat:
SELECIONE
1 como t,
contagem(*) como c
DE $table
ONDE $timeFilter E status NÃO IN (200, 201, 401) AGRUPAR POR t
Percentual de Falhas de Singlestat:
SELECIONE
1 como t, (soma(status = 500 ou status = 499) / soma(status = 200 ou status = 201 ou status = 401)) * 100 DE $table
ONDE $timeFilter AGRUPAR POR t
Tempo Médio de Resposta de Singlestat:
SELECIONE
1, média(tempo_de_resposta) DE $table
ONDE $timeFilter AGRUPAR POR 1
Tempo Máximo de Resposta de Singlestat:
SELECIONE
1 como t, max(tempo_de_resposta) como c
DE $table
ONDE $timeFilter AGRUPAR POR t
Contagem de Status:
$columns(status, contagem(*) como c) DE $table
Para exibir dados como gráfico de pizza, é necessário instalar o plugin e reiniciar o grafana.
grafana-cli plugins install grafana-piechart-panel
serviço grafana-server restartTop 5 Status de Pizza:
SELECIONE
1,
status,
soma(status) COMO Reqs
DE $table
ONDE $timeFilter
AGRUPAR POR status
ORDER BY Reqs desc
LIMIT 5
A partir daqui, apresentarei as consultas sem capturas de tela:
Contagem de http_user_agent:
$columns(http_user_agent, contagem(*) c) DE $tableTaxa Boa/Taxa Ruim:
$rate(contagemSe(status = 200) COMO boa, contagemSe(status != 200) COMO ruim) DE $tableTempo de Resposta:
$rate(média(tempo_de_resposta) como tempo_de_resposta) DE $tableTempo de resposta do upstream (tempo de resposta do primeiro upstream):
$rate(média(elemento_array(tempo_de_resposta_upstream, 1)) como tempo_de_resposta_upstream) DE $tableContagem de Status da Tabela para todos os vhosts:
$columns(status, contagem(*) como c) DE $tableVisão geral do painel



Comparação entre avg() e quantile()
avg()

quantile()

Conclusão:
Espero que a comunidade se junte ao desenvolvimento/teste e uso do nginx-log-collector.
E quem implementar o nginx-log-collector vai contar quanto economizou de disco, RAM, CPU.
Canais do Telegram:
Milissegundos:
Para quem se importa com milissegundos, por favor, escreva ou vote neste .
Fonte: habr.com
