Análise de registros da Web e de aplicações em grande escala
Extraia códigos de status, latências e campos de clientes de registros de acesso usando grep, cut e awk.
Análise de registros da Web e de aplicações em grande escala é uma aula grátis de Linux Command Line & Bash Scripting Mastery no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Linux Command Line & Bash Scripting Mastery, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Linux Command Line & Bash Scripting Mastery inclui 4 aulas no total.
O que é um registro de acesso à web?
Todo servidor HTTP — Apache, Nginx, Caddy — grava uma linha em um registro de acesso para cada solicitação. Entender a estrutura dessas linhas é a base de todo trabalho de análise de registros.
Uma linha típica do Formato de Registro Combinado (CLF) tem esta aparência:
- IP do cliente — quem fez a solicitação
- Carimbo de data e hora — quando isso aconteceu
- Linha da solicitação — método, caminho e protocolo
- Código de status — resposta HTTP (200, 404, 500…)
- Bytes enviados — tamanho do corpo da resposta
- Referenciador — página de origem
- Agente do usuário — texto que identifica o navegador ou bot
Exemplo de linha de /var/log/nginx/access.log:
192.168.1.10 - alice [11/Jun/2026:14:32:01 +0000] "GET /api/orders HTTP/1.1" 200 1482 "-" "curl/7.88.1"
Em grande escala, esses arquivos chegam a milhões de linhas por dia. O objetivo desta lição é extrair, filtrar e agregar campos deles com eficiência usando ferramentas padrão do BASH.
Amostrando um registro ativo com tail e grep
Antes de escrever qualquer cadeia de processamento, examine o registro para entender seu formato. tail permite acompanhar um fluxo ativo; grep o restringe imediatamente às linhas relevantes.
Padrões comuns:
tail -n 1000 access.log— últimas 1000 linhastail -f access.log— acompanhar em tempo realtail -f access.log | grep '" 5'— apenas erros 5xx à medida que chegam
A principal ideia é que grep compara com a linha inteira, portanto é importante fixar corretamente o padrão. Comparar ' 500 ' (com espaços) evita que você corresponda acidentalmente a um caminho de URL que contenha a sequência 500.
#!/usr/bin/env bash
# Watch only HTTP 5xx errors arriving in real time
tail -f /var/log/nginx/access.log \
| grep --line-buffered '" 5[0-9][0-9] 'Extraindo o código de status com cut
cut divide cada linha usando um delimitador e exibe os campos selecionados. No Formato de Registro Combinado, o código de status fica no campo 9 quando a divisão é feita nos espaços — mas as aspas ao redor da linha da solicitação fazem com que seja mais seguro contar a partir de uma referência conhecida.
Um truque confiável: como a linha da solicitação está sempre entre aspas, o código de status é sempre o primeiro item depois das aspas de fechamento do campo da solicitação. Usar cut -d'"' -f3 isola tudo depois das aspas da solicitação; em seguida, um segundo cut -d' ' -f2 seleciona o código de status.
Esse uso do cut em duas etapas é um padrão clássico para registros CLF — rápido e sem dependências externas.
#!/usr/bin/env bash
# Print only the HTTP status code from each log line
# Input format: ... "GET /path HTTP/1.1" 200 1482 ...
cut -d'"' -f3 /var/log/nginx/access.log \
| cut -d' ' -f2 \
| sort \
| uniq -c \
| sort -rnContando códigos de status com awk
awk é mais poderoso que cut porque pode acumular estado entre as linhas. O padrão idiomático para contar ocorrências é usar uma matriz associativa indexada pelo valor que você deseja analisar.
No CLF, o campo $9 (indexado a partir de 1 e delimitado por espaços) contém o código de status. awk processa cada linha, incrementa um contador e depois exibe um resumo ordenado no bloco END.
Por que preferir awk a cut | sort | uniq -c? Porque awk faz isso em uma única passagem, sem ordenar primeiro o arquivo inteiro — algo essencial quando o registro tem centenas de gigabytes.
#!/usr/bin/env bash
# Count HTTP status codes in a single awk pass
awk '{ count[$9]++ }
END {
for (status in count)
printf "%6d %s\n", count[status], status
}' /var/log/nginx/access.log \
| sort -rnFiltrando erros e extraindo IPs de clientes
Uma das tarefas operacionais mais comuns é descobrir quais IPs de clientes estão gerando mais erros. Isso combina filtragem (apenas linhas de erro) com extração de campos (o IP no campo 1).
A estratégia da cadeia de processamento:
- Use
awkpara filtrar pelo intervalo do código de status e extrair o IP em uma única etapa — evite uma passagem separada comgrep - Encadeie com
sort | uniq -c | sort -rn | headpara obter rapidamente uma visão dos N primeiros
Esse padrão é rápido o suficiente para ser executado em um arquivo de registro de 10 GB em um único servidor, sem carregar o arquivo na memória.
#!/usr/bin/env bash
# Top 10 IPs generating HTTP 4xx or 5xx errors
awk '$9 ~ /^[45][0-9][0-9]$/ { print $1 }' \
/var/log/nginx/access.log \
| sort \
| uniq -c \
| sort -rn \
| head -10Analisando a latência das respostas nos registros da aplicação
Servidores de aplicações (Rails, Gunicorn, Express com morgan etc.) costumam registrar a duração das solicitações. O Nginx pode ser configurado para emitir $request_time como um campo adicional no fim de cada linha.
Exemplo de formato de registro personalizado do Nginx em nginx.conf:
log_format timed '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" rt=$request_time';
Quando a latência estiver no registro, você poderá usar awk para calcular a média, o máximo e aproximações de percentis em milhões de solicitações, sem carregar os dados em um banco de dados.
#!/usr/bin/env bash
# Compute average and max request_time from Nginx timed log
# Assumes last field is rt=<seconds> e.g. rt=0.042
awk '{
# Extract numeric value after rt=
n = split($NF, a, "=")
if (n == 2 && a[1] == "rt") {
t = a[2] + 0
sum += t
count++
if (t > max) max = t
}
}
END {
if (count > 0)
printf "Requests: %d Avg: %.4fs Max: %.4fs\n", count, sum/count, max
}' /var/log/nginx/timed_access.logCriando um histograma de latência com awk
Uma única média oculta a latência da cauda. Um histograma revela a distribuição — mostra se a maioria das solicitações é rápida e algumas são muito lentas (cauda longa) ou se a distribuição é uniforme.
O truque é agrupar cada valor em um intervalo arredondado usando aritmética inteira dentro do awk. Multiplicar por 1000 (convertendo segundos em milissegundos) e depois usar a divisão inteira produz limites de intervalo bem definidos.
Isso produz um histograma textual que você pode ler diretamente em um terminal, o que costuma ser mais rápido do que enviar dados ao Grafana para uma investigação rápida.
#!/usr/bin/env bash
# Latency histogram (50ms buckets) from Nginx timed log
awk '{
n = split($NF, a, "=")
if (n == 2 && a[1] == "rt") {
ms = int(a[2] * 1000) # convert to ms
bucket = int(ms / 50) * 50 # round down to 50ms boundary
hist[bucket]++
}
}
END {
for (b in hist)
printf "%6dms %d\n", b, hist[b]
}' /var/log/nginx/timed_access.log \
| sort -nExtraindo o agente do usuário e detectando bots
O campo do agente do usuário (campo 6 ao dividir em ") identifica os clientes. Rastreadores, coletores e bots mal-intencionados costumam poluir suas métricas e inflar as contagens de erros. Filtrá-los resulta em uma visão mais clara do tráfego de usuários reais.
Assinaturas comuns de bots: bot, crawler, spider, curl, python-requests, Googlebot, Bingbot.
Use grep -iv (inversão sem distinção entre maiúsculas e minúsculas) para excluir bots conhecidos ou use awk para dividir em " e comparar diretamente o campo UA.
#!/usr/bin/env bash
# Count top 15 User-Agent strings, excluding known bots
awk -F'"' '{ print $6 }' /var/log/nginx/access.log \
| grep -iv -e 'bot' -e 'crawler' -e 'spider' -e 'curl' \
-e 'python' -e 'wget' -e 'Go-http-client' \
| sort \
| uniq -c \
| sort -rn \
| head -15Agregando tráfego por endpoint
Saber quais endpoints recebem mais tráfego — e geram mais erros — ajuda a priorizar a otimização e o planejamento de capacidade. O caminho da solicitação fica dentro do campo entre aspas.
Divida em ", use o campo 2 (a linha da solicitação) e depois remova o método e o protocolo para isolar o caminho. Para APIs com parâmetros no caminho, como /users/12345, talvez você também queira normalizar os IDs para /users/:id usando sed ou um padrão mais complexo de awk.
#!/usr/bin/env bash
# Top 20 requested endpoints (method + path, no query string)
awk -F'"' '{ print $2 }' /var/log/nginx/access.log \
| awk '{ print $1, $2 }' \
| sed 's|/[0-9][0-9]*\b|/:id|g' \
| sort \
| uniq -c \
| sort -rn \
| head -20Correlacionando erros com endpoints usando awk
A análise de passagem única mais poderosa combina vários campos ao mesmo tempo: endpoint, código de status e, opcionalmente, latência. Matrizes associativas de awk indexadas por valores compostos tornam isso simples e rápido.
O padrão abaixo conta erros 5xx por endpoint em uma única passagem — sem arquivos temporários e sem ordenações intermediárias até o final. Essa é a abordagem usada em scripts de observabilidade de produção quando você precisa de respostas em menos de um minuto sobre um registro grande.
#!/usr/bin/env bash
# Count 5xx errors per endpoint path in a single pass
awk -F'"' '{
# $2 = request line e.g. "GET /api/orders HTTP/1.1"
# $0 in original space-split: $9 = status
split($0, fields, " ")
status = fields[9]
if (status ~ /^5/) {
split($2, req, " ")
path = req[2]
# Normalise numeric IDs
gsub(/\/[0-9]+/, "/:id", path)
errors[path]++
}
}
END {
for (p in errors)
printf "%6d %s\n", errors[p], p
}' /var/log/nginx/access.log \
| sort -rn \
| head -20Processando registros rotacionados e compactados
Na maioria dos servidores, os registros são rotacionados diariamente. Os arquivos mais antigos são compactados com gzip como access.log.1.gz, access.log.2.gz etc. As ferramentas padrão não conseguem lê-los diretamente, mas duas abordagens funcionam bem:
zcat— descompacta para a saída padrão e envia para sua cadeia de processamentozgrep— executa grep diretamente dentro dos arquivos gzip, sem extraí-los
Para analisar uma semana inteira de registros que inclua arquivos descompactados e compactados, use a substituição de processo ou concatene com zcat. O trecho abaixo processa os últimos 7 arquivos rotacionados e o registro ativo atual em uma única invocação de awk — não são necessários arquivos temporários.
#!/usr/bin/env bash
# Aggregate status codes across a week of rotated logs
# Handles both plain and gzip-compressed rotation files
LOG_DIR="/var/log/nginx"
{
cat "${LOG_DIR}/access.log" 2>/dev/null
zcat "${LOG_DIR}/access.log".*.gz 2>/dev/null
} | awk '
{ count[$9]++ }
END {
for (s in count)
printf "%6d %s\n", count[s], s
}' | sort -rnQual campo do awk contém o código de status HTTP no Formato de Registro Combinado?
Você está escrevendo uma linha única de awk para filtrar apenas respostas HTTP 4xx de um registro de acesso padrão do Nginx no Combined Log Format (delimitado por espaços, com a linha de requisição entre aspas). Qual número de campo identifica corretamente o código de status HTTP?
Resumo da lição: pipelines de análise de registros
Nesta lição, você construiu um conjunto completo de ferramentas para analisar registros da Web e de aplicações em grande escala usando apenas utilitários padrão do BASH.
Principais técnicas abordadas:
- Estrutura em primeiro lugar — o Combined Log Format tem uma disposição previsível dos campos; conhecê-la permite dividi-lo de forma confiável com
cut -d'"'ou referências a campos doawk. - Extração do código de status —
awk '{ count[$9]++ }'conta todos os códigos em uma única passagem; filtre com$9 ~ /^5/para encontrar erros do servidor. - Análise de latência — analise o campo personalizado
rt=comawkpara calcular médias, valores máximos e intervalos de histogramas sem nenhuma ferramenta externa. - Análise de clientes e robôs — divida em
"com-F'"'para acessar o campo User-Agent; use um pipeline comgrep -ivpara excluir robôs antes de agregar os dados. - Normalização de endpoints — use
gsub(/\/[0-9]+/, "/:id")dentro doawkpara agrupar caminhos parametrizados antes da contagem. - Registros rotacionados — combine
catezcatem um subshell para enviar todos os arquivos de rotação em uma única passagem pelo pipeline.
Esses padrões podem ser combinados: você pode encadear filtragem, extração, normalização e agregação em um único pipeline que processa centenas de milhões de linhas em hardware comum. Domine essas primitivas e raramente precisará de um serviço dedicado de agregação de registros para investigar incidentes pontuais.
Perguntas Frequentes
A aula “Análise de registros da Web e de aplicações em grande escala” é grátis?
Sim — o texto completo de “Análise de registros da Web e de aplicações em grande escala” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Linux Command Line & Bash Scripting Mastery, atualize para CoddyKit PRO. O curso de Linux Command Line & Bash Scripting Mastery inclui 4 aulas no total.
O que vou aprender em “Análise de registros da Web e de aplicações em grande escala”?
Extraia códigos de status, latências e campos de clientes de registros de acesso usando grep, cut e awk. Você pratica Linux Command Line & Bash Scripting Mastery com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Linux Command Line & Bash Scripting Mastery?
Nenhuma experiência prévia é necessária. Linux Command Line & Bash Scripting Mastery no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Análise de registros da Web e de aplicações em grande escala”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Linux Command Line & Bash Scripting Mastery?
Sim. Cada aula de Linux Command Line & Bash Scripting Mastery inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Análise de registros da Web e de aplicações em grande escala
- Acompanhamento de registros em tempo real e alertas por transmissão
- Consulta ao journald com journalctl em scripts
- Cálculo de métricas e histogramas a partir de fluxos de registros