0Pricing
DevOps Bootcamp · Aula

Cálculo de métricas e histogramas a partir de fluxos de registros

Agregue taxas de solicitações, percentis e relatórios dos N primeiros itens diretamente de dados de registros transmitidos.

Cálculo de métricas e histogramas a partir de fluxos de registros é uma aula grátis de DevOps Bootcamp no CoddyKit. Esta é a aula 4 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 DevOps Bootcamp, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de DevOps Bootcamp inclui 4 aulas no total.

Por que calcular métricas a partir de registros brutos?

Sistemas de produção emitem milhares de linhas de registro por segundo. Em vez de enviar registros brutos para plataformas de análise caras, você pode calcular taxas de requisições, percentis e relatórios dos principais itens diretamente no shell — com custo praticamente nulo.

  • Taxa de requisições: quantas requisições por segundo/minuto seu serviço processa?
  • Percentis de latência: qual é o tempo de resposta p50/p95/p99?
  • Relatórios dos principais itens: quais endpoints, IPs ou códigos de erro aparecem com mais frequência?

Ferramentas do shell como awk, sort, uniq e bc formam um pipeline poderoso e combinável, capaz de responder a essas perguntas a partir de um fluxo de registros ao vivo ou de um arquivo histórico, sem sair do terminal.

Anatomia de um registro de acesso comum

A maioria dos servidores web grava registros no Formato de Registro Combinado. Entender seus campos é a base de todo pipeline de métricas:

127.0.0.1 - frank [10/Oct/2024:13:55:36 -0700] "GET /api/users HTTP/1.1" 200 2326 0.042
  • Campo 1: IP do cliente
  • Campo 4 (entre colchetes): marca de data e hora
  • Campo 7 (entre aspas): método HTTP + caminho
  • Campo 9: código de status
  • Campo 10: bytes da resposta
  • Campo 11: tempo de resposta em segundos (campo personalizado, nem sempre presente)

Use awk para referenciar campos por posição ($1, $9 etc.). Campos entre aspas contam como um único token somente quando você faz a divisão com cuidado — envolva a linha de registro em awk -F'"' ou use várias passagens.

Contando a taxa de requisições por minuto

Para calcular requisições por minuto, extraia a parte correspondente ao minuto de cada marca de data e hora e conte as ocorrências. O padrão [day/Mon/year:HH:MM fornece o intervalo de hora e minuto.

O pipeline abaixo lê access.log e imprime uma tabela de minuto → contagem de requisições:

#!/usr/bin/env bash
# Requests per minute from an nginx/apache access log
# Usage: bash req_per_min.sh access.log

LOG="${1:-access.log}"

awk '{
    # Extract [day/Mon/year:HH:MM from field 4
    match($0, /\[([^:]+:[0-9]+:[0-9]+)/, arr)
    minute = arr[1]
    if (minute != "") count[minute]++
} END {
    for (m in count) print count[m], m
}' "$LOG" | sort -k2

Taxa em janela deslizante com um fluxo ao vivo

Para um acompanhamento ao vivo, você precisa de uma janela deslizante. O truque é usar tail -f encaminhado para awk, que reinicia o contador a cada N segundos usando o relógio do sistema (systime()).

Este exemplo imprime uma linha de taxa a cada 10 segundos:

#!/usr/bin/env bash
# Live request rate — prints lines/10s from a tailed log
# Usage: bash live_rate.sh /var/log/nginx/access.log

LOG="${1:-/var/log/nginx/access.log}"
WINDOW=10

tail -f "$LOG" | awk -v win="$WINDOW" '
BEGIN { start = systime(); count = 0 }
{
    count++
    now = systime()
    if (now - start >= win) {
        printf "[%s] %d req/%ds (%.1f req/s)\n",
               strftime("%H:%M:%S", now), count, win, count/win
        count = 0
        start = now
    }
}'

Extraindo valores de latência para calcular percentis

O cálculo de percentis exige ordenar todos os valores de latência observados. A abordagem padrão é:

  1. Extraia a coluna de latência para uma lista simples de números.
  2. Ordene numericamente.
  3. Escolha o valor na posição correta usando a contagem de linhas.

O script abaixo extrai o campo 11 (tempo de resposta em segundos) e o salva em um arquivo temporário para o cálculo de percentis na próxima etapa:

#!/usr/bin/env bash
# Extract latency column from access log (field 11)
# Assumes last field on each line is response time in seconds

LOG="${1:-access.log}"
TMP=$(mktemp /tmp/latency_XXXXXX.txt)

awk '{ if ($NF ~ /^[0-9]+\.?[0-9]*$/) print $NF }' "$LOG" \
    | sort -n > "$TMP"

echo "Extracted $(wc -l < "$TMP") latency samples -> $TMP"
echo "$TMP"   # callers can read this file

Calculando p50, p95 e p99 com awk

Depois que os valores de latência são ordenados, escolher um percentil é uma operação aritmética: o percentil p fica na linha ceil(p/100 * N). O awk puro pode fazer isso em uma única passagem depois de carregar o arquivo ordenado em uma matriz:

#!/usr/bin/env bash
# Compute p50 / p95 / p99 from a sorted latency file
# Usage: bash percentiles.sh latency_sorted.txt

# Demo: generate 1000 random latencies if no file given
if [[ $# -eq 0 ]]; then
    SORTED=$(mktemp)
    for i in $(seq 1 1000); do
        awk 'BEGIN { srand(); printf "%.4f\n", 0.001 + rand()*0.999 }'
    done | sort -n > "$SORTED"
else
    SORTED="$1"
fi

awk '
{ values[NR] = $1 }
END {
    n = NR
    if (n == 0) { print "No data"; exit }
    p50  = values[int(n * 0.50 + 0.9999)]
    p95  = values[int(n * 0.95 + 0.9999)]
    p99  = values[int(n * 0.99 + 0.9999)]
    printf "p50  = %.4fs\np95  = %.4fs\np99  = %.4fs\nN    = %d\n",
           p50, p95, p99, n
}' "$SORTED"

Criando um relatório dos principais N endpoints

Um relatório dos principais N itens responde à pergunta "quais caminhos são mais acessados?" O idioma clássico do shell é:

  • awk para imprimir o campo de interesse (por exemplo, o caminho da URL)
  • sort para agrupar valores idênticos
  • uniq -c para contar duplicatas consecutivas
  • sort -rn para classificar pela contagem em ordem decrescente
  • head -n N para obter os N primeiros
#!/usr/bin/env bash
# Top-10 most requested URL paths from access log
# Usage: bash top_endpoints.sh access.log [N]

LOG="${1:-access.log}"
N="${2:-10}"

echo "=== Top $N endpoints ==="
awk -F'"' '{ print $2 }' "$LOG" \
    | awk '{ print $2 }' \
    | sort \
    | uniq -c \
    | sort -rn \
    | head -n "$N" \
    | awk '{ printf "%6d  %s\n", $1, $2 }'

Principais N por código de status: identificando erros rapidamente

Os códigos de status HTTP informam a saúde do seu serviço. Agrupar as linhas de registro por código de status e contá-las revela se os erros são raros ou sistêmicos.

O script abaixo gera uma decomposição abrangendo todos os grupos 2xx/3xx/4xx/5xx:

#!/usr/bin/env bash
# Status code frequency breakdown
# Usage: bash status_breakdown.sh access.log

LOG="${1:-access.log}"

echo "=== HTTP Status Code Distribution ==="
awk '{ print $9 }' "$LOG" \
    | grep -E '^[0-9]{3}$' \
    | sort \
    | uniq -c \
    | sort -rn \
    | awk '{ printf "%6d  %s\n", $1, $2 }'

echo
echo "=== 5xx Error Spike Check ==="
awk '$9 ~ /^5/ { print $9, $7 }' "$LOG" \
    | sort | uniq -c | sort -rn | head -20

Histogramas ASCII com awk

Um histograma de texto torna as distribuições de latência imediatamente legíveis em um terminal ou registro de CI. A abordagem é:

  1. Agrupe cada valor de latência em uma faixa (por exemplo, 0–50 ms, 50–100 ms, …).
  2. Conte as observações por faixa.
  3. Imprima uma barra de caracteres # dimensionada para a contagem máxima.

Isso é extremamente útil para identificar distribuições bimodais ou valores discrepantes sem uma ferramenta de gráficos.

#!/usr/bin/env bash
# ASCII latency histogram from a list of latency values in seconds
# Demo: generates synthetic data if no input file is provided

if [[ $# -eq 0 ]]; then
    # Generate 500 synthetic latencies (ms converted to s)
    python3 -c "
import random, math
for _ in range(500):
    # bimodal: fast cluster ~50ms, slow cluster ~300ms
    if random.random() < 0.75:
        v = max(1, random.gauss(50, 15))
    else:
        v = max(1, random.gauss(300, 80))
    print(f'{v/1000:.4f}')
" | sort -n | awk '
{ values[NR] = $1 * 1000 }  # convert to ms
END {
    buckets = 10; maxVal = 500
    step = maxVal / buckets
    for (i = 0; i < buckets; i++) hist[i] = 0
    for (i = 1; i <= NR; i++) {
        b = int(values[i] / step)
        if (b >= buckets) b = buckets - 1
        hist[b]++
    }
    maxCount = 0
    for (i = 0; i < buckets; i++) if (hist[i] > maxCount) maxCount = hist[i]
    print "Latency (ms)   Count   Distribution"
    print "---------------------------------------"
    for (i = 0; i < buckets; i++) {
        lo = i * step; hi = lo + step
        barLen = int(hist[i] / maxCount * 40)
        bar = ""
        for (j = 0; j < barLen; j++) bar = bar "#"
        printf "%4d-%4dms  %5d  %s\n", lo, hi, hist[i], bar
    }
}'
else
    echo "Usage: pipe a sorted latency file (in seconds) to this pattern"
fi

Combinando métricas: o relatório resumido em uma única execução

Guias operacionais de produção geralmente precisam de um único comando que emita todas as métricas principais de uma vez: taxa, percentis de latência, principais endpoints e taxa de erros. Você pode combinar tudo o que aprendeu até agora em um script que uma pessoa ou um sistema de alertas possa chamar.

#!/usr/bin/env bash
# One-shot log summary report
# Usage: bash log_summary.sh access.log

LOG="${1:-access.log}"
[[ -f "$LOG" ]] || { echo "File not found: $LOG"; exit 1; }

TOTAL=$(wc -l < "$LOG")
ERRORS=$(awk '$9 ~ /^[45]/' "$LOG" | wc -l)
ERR_RATE=$(awk "BEGIN { printf \"%.1f\", ($ERRORS / ($TOTAL || 1)) * 100 }")

echo "====================================="
echo " Log Summary: $LOG"
echo "====================================="
printf " Total requests : %d\n" "$TOTAL"
printf " 4xx/5xx errors : %d (%.1f%%)\n" "$ERRORS" "$ERR_RATE"

echo
echo "--- Top 5 Endpoints ---"
awk -F'"' '{ print $2 }' "$LOG" | awk '{ print $2 }' \
    | sort | uniq -c | sort -rn | head -5 \
    | awk '{ printf "  %6d  %s\n", $1, $2 }'

echo
echo "--- Latency Percentiles ---"
awk '{ if ($NF ~ /^[0-9]+\.?[0-9]*$/) print $NF * 1000 }' "$LOG" \
    | sort -n \
    | awk '
{ v[NR]=$1 }
END {
  if (NR==0) { print "  No latency data"; exit }
  printf "  p50 = %.1fms\n", v[int(NR*0.50+0.9999)]
  printf "  p95 = %.1fms\n", v[int(NR*0.95+0.9999)]
  printf "  p99 = %.1fms\n", v[int(NR*0.99+0.9999)]
}'

Transmitindo métricas por pipes nomeados e tee

Em pipelines de observabilidade, muitas vezes é necessário ramificar um fluxo de registros: gravar as linhas brutas no disco e, simultaneamente, calcular métricas. O tee com um pipe nomeado (mkfifo) torna isso possível sem armazenar todo o fluxo na memória.

  • mkfifo /tmp/log_pipe — cria o pipe nomeado
  • tee /tmp/log_pipe | metric_consumer & — ramifica uma parte para o consumidor de métricas
  • A outra parte grava no arquivo de armazenamento

Esse padrão mantém as gravações em disco e a agregação de métricas desacopladas e permite que qualquer um dos lados seja reiniciado de forma independente.

#!/usr/bin/env bash
# Fan-out: write to archive AND count errors in real time
# Run: bash fanout_pipeline.sh /var/log/nginx/access.log

LOG="${1:-/var/log/nginx/access.log}"
ARCHIVE="/tmp/access_archive.log"
PIPE="/tmp/log_metrics_pipe"

# Clean up on exit
trap 'rm -f "$PIPE"' EXIT

mkfifo "$PIPE"

# Branch 1: count 5xx errors per minute from the pipe
awk '$9 ~ /^5/ {
    match($0, /\[([^:]+:[0-9]+:[0-9]+)/, arr)
    errors[arr[1]]++
} END {
    for (m in errors) printf "5xx errors at %s: %d\n", m, errors[m]
}' "$PIPE" &

# Branch 2: archive to disk + feed Branch 1 via pipe
tail -f "$LOG" | tee "$PIPE" >> "$ARCHIVE"

Qual técnica de awk calcula corretamente o percentil p95 a partir de uma matriz ordenada com N valores de latência?

Você carregou N valores de latência ordenados em uma matriz de awk v[1..N]. Qual expressão recupera corretamente o percentil p95?

Recapitulação da lição: métricas e histogramas a partir de fluxos de registros

Nesta lição, você criou um pipeline completo de métricas diretamente no Bash:

  • Taxa de requisições: awk extrai o intervalo de minutos dos carimbos de data e hora e conta as ocorrências; tail -f + systime() fornece uma taxa ao vivo em uma janela deslizante.
  • Percentis de latência: extraia a coluna de latência, use sort -n e selecione a linha na posição ceil(p/100 * N) com int(N * p + 0.9999) no awk.
  • Relatórios dos N primeiros: o pipeline clássico awk | sort | uniq -c | sort -rn | head -N funciona para qualquer campo categórico (caminho, IP, código de status).
  • Histogramas ASCII: agrupe os valores, conte por intervalo e ajuste o comprimento da barra à contagem máxima de um intervalo para obter visualizações da distribuição de relance.
  • Distribuição com canais nomeados: mkfifo + tee permite arquivar registros brutos e alimentar consumidores de métricas simultaneamente, sem carregar o fluxo na memória.

Esses elementos básicos combináveis eliminam a necessidade de ferramentas externas durante incidentes e formam a base de scripts leves de observabilidade que são executados em qualquer ambiente onde o Bash esteja disponível.

Perguntas Frequentes

A aula “Cálculo de métricas e histogramas a partir de fluxos de registros” é grátis?

Sim — o texto completo de “Cálculo de métricas e histogramas a partir de fluxos de registros” é 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 DevOps Bootcamp, atualize para CoddyKit PRO. O curso de DevOps Bootcamp inclui 4 aulas no total.

O que vou aprender em “Cálculo de métricas e histogramas a partir de fluxos de registros”?

Agregue taxas de solicitações, percentis e relatórios dos N primeiros itens diretamente de dados de registros transmitidos. Você pratica DevOps Bootcamp 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 DevOps Bootcamp?

Nenhuma experiência prévia é necessária. DevOps Bootcamp 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 4 de 4.

Quanto tempo leva a aula “Cálculo de métricas e histogramas a partir de fluxos de registros”?

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 DevOps Bootcamp?

Sim. Cada aula de DevOps Bootcamp 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

  1. Análise de registros da Web e de aplicações em grande escala
  2. Acompanhamento de registros em tempo real e alertas por transmissão
  3. Consulta ao journald com journalctl em scripts
  4. Cálculo de métricas e histogramas a partir de fluxos de registros
← Voltar para DevOps Bootcamp