Cálculo de métricas e histogramas a partir de flujos de registros
Agregue tasas de solicitudes, percentiles e informes de los valores principales directamente desde datos de registros en streaming.
Cálculo de métricas e histogramas a partir de flujos de registros es una lección gratuita de Linux Command Line & Bash Scripting Mastery en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Linux Command Line & Bash Scripting Mastery, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Linux Command Line & Bash Scripting Mastery incluye 4 lecciones en total.
¿Por qué calcular métricas a partir de registros sin procesar?
Los sistemas en producción generan miles de líneas de registro por segundo. En lugar de enviar registros sin procesar a costosas plataformas de análisis, puede calcular directamente en el shell las tasas de solicitudes, los percentiles y los informes de los N principales, con un coste prácticamente nulo.
- Tasa de solicitudes: ¿cuántas solicitudes por segundo o minuto gestiona su servicio?
- Percentiles de latencia: ¿cuál es el tiempo de respuesta p50/p95/p99?
- Informes de los N principales: ¿qué endpoints, direcciones IP o códigos de error aparecen con mayor frecuencia?
Las herramientas del shell como awk, sort, uniq y bc forman una canalización potente y componible que puede responder a estas preguntas a partir de un flujo de registros en directo o de un archivo histórico sin salir del terminal.
Anatomía de un registro de acceso habitual
La mayoría de los servidores web escriben los registros en Combined Log Format. Comprender sus campos es la base de cualquier canalización 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 del cliente
- Campo 4 (entre corchetes): marca de tiempo
- Campo 7 (entre comillas): método HTTP + ruta
- Campo 9: código de estado
- Campo 10: bytes de respuesta
- Campo 11: tiempo de respuesta en segundos (campo personalizado, no siempre presente)
Use awk para hacer referencia a los campos por posición ($1, $9, etc.). Los campos entre comillas cuentan como un único token solo si se dividen con cuidado; incluya la línea de registro en awk -F'"' o utilice varias pasadas.
Contar la tasa de solicitudes por minuto
Para calcular las solicitudes por minuto, extraiga la parte correspondiente al minuto de cada marca de tiempo y cuente las apariciones. El patrón [day/Mon/year:HH:MM le proporciona el intervalo de hora y minuto.
La siguiente canalización lee access.log e imprime una tabla de minuto → cantidad de solicitudes:
#!/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 -k2Tasa en una ventana deslizante con un flujo en directo
Para seguir un flujo en directo, necesita una ventana deslizante. El truco consiste en canalizar tail -f a awk y hacer que restablezca su contador cada N segundos usando el reloj del sistema (systime()).
Este ejemplo imprime una línea de tasa 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
}
}'Extraer valores de latencia para calcular percentiles
Los percentiles requieren ordenar todos los valores de latencia observados. El enfoque estándar es:
- Extraer la columna de latencia en una lista de números sin formato.
- Ordenarla numéricamente.
- Elegir el valor que ocupa el rango correcto mediante el recuento de líneas.
El siguiente script extrae el campo 11 (tiempo de respuesta en segundos) y lo guarda en un archivo temporal para calcular los percentiles en el paso siguiente:
#!/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 fileCalcular p50, p95 y p99 con awk
Una vez ordenados los valores de latencia, elegir un percentil es una operación aritmética: el percentil p se encuentra en la fila ceil(p/100 * N). Con awk puro puede hacerlo en una sola pasada después de cargar el archivo ordenado en un array:
#!/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"Crear un informe de los N endpoints principales
Un informe de los N principales responde a la pregunta «¿qué rutas reciben más solicitudes?». El modismo clásico del shell es:
awkpara imprimir el campo de interés (por ejemplo, la ruta de la URL)sortpara agrupar los valores idénticosuniq -cpara contar los duplicados consecutivossort -rnpara ordenar por cantidad descendentehead -n Npara obtener los N primeros
#!/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 }'N principales por código de estado: detectar errores de un vistazo
Los códigos de estado HTTP indican el estado de salud de su servicio. Agrupar las líneas de registro por código de estado y contarlas revela si los errores son poco frecuentes o sistémicos.
El siguiente script genera un desglose de todos los 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 -20Histogramas ASCII con awk
Un histograma de texto permite leer al instante las distribuciones de latencia en un terminal o registro de CI. El procedimiento es:
- Agrupar cada valor de latencia en un intervalo (por ejemplo, 0-50 ms, 50-100 ms, …).
- Contar las observaciones de cada intervalo.
- Imprimir una barra de caracteres
#cuya escala se base en el recuento máximo.
Esto resulta muy útil para detectar distribuciones bimodales o valores atípicos sin utilizar una herramienta 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"
fiCombinar métricas: el informe resumido de una sola ejecución
Los manuales operativos de producción suelen necesitar un único comando que emita todas las métricas clave a la vez: tasa, percentiles de latencia, endpoints principales y tasa de errores. Puede combinar en un solo script todo lo aprendido hasta ahora, para que lo invoque una persona o un sistema de alertas.
#!/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)]
}'Transmitir métricas mediante tuberías con nombre y tee
En las canalizaciones de observabilidad, a menudo necesita distribuir un flujo de registros: escribir las líneas sin procesar en el disco y, al mismo tiempo, calcular métricas. tee con una tubería con nombre (mkfifo) lo hace posible sin almacenar todo el flujo en la memoria.
mkfifo /tmp/log_pipe— crea la tubería con nombretee /tmp/log_pipe | metric_consumer &— bifurca una rama hacia el consumidor de métricas- La otra rama escribe en el archivo de archivo histórico
Este patrón mantiene desacopladas las escrituras en disco y la agregación de métricas, y permite reiniciar cada lado de forma independiente.
#!/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"¿Qué técnica de awk calcula correctamente el percentil p95 a partir de un array ordenado con N valores de latencia?
Ha cargado N valores de latencia ordenados en un array de awk v[1..N]. ¿Qué expresión recupera correctamente el percentil p95?
Resumen de la lección: métricas e histogramas a partir de flujos de registros
En esta lección ha creado un pipeline completo de métricas directamente en Bash:
- Tasa de solicitudes:
awkextrae el intervalo de minutos de las marcas de tiempo y cuenta las apariciones;tail -f+systime()proporciona una tasa de ventana deslizante en tiempo real. - Percentiles de latencia: extraiga la columna de latencia, use
sort -ny, después, seleccione la fila enceil(p/100 * N)conint(N * p + 0.9999)en awk. - Informes de los N primeros: el pipeline clásico
awk | sort | uniq -c | sort -rn | head -Nfunciona con cualquier campo categórico (ruta, IP, código de estado). - Histogramas ASCII: agrupe los valores, cuente cada intervalo y escale la longitud de la barra según el recuento máximo de un intervalo para obtener una vista de la distribución de un vistazo.
- Distribución mediante named pipes:
mkfifo+teepermite archivar los registros sin procesar y alimentar simultáneamente a los consumidores de métricas sin cargar el flujo en memoria.
Estas primitivas componibles eliminan la necesidad de herramientas externas durante los incidentes y constituyen la base de scripts ligeros de observabilidad que se ejecutan allí donde se ejecute Bash.
Preguntas frecuentes
¿La lección «Cálculo de métricas e histogramas a partir de flujos de registros» es gratis?
Sí — el texto completo de «Cálculo de métricas e histogramas a partir de flujos de registros» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Linux Command Line & Bash Scripting Mastery, actualiza a CoddyKit PRO. El curso de Linux Command Line & Bash Scripting Mastery incluye 4 lecciones en total.
¿Qué aprenderé en «Cálculo de métricas e histogramas a partir de flujos de registros»?
Agregue tasas de solicitudes, percentiles e informes de los valores principales directamente desde datos de registros en streaming. Practicas Linux Command Line & Bash Scripting Mastery con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Linux Command Line & Bash Scripting Mastery?
No se requiere experiencia previa. Linux Command Line & Bash Scripting Mastery en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Cálculo de métricas e histogramas a partir de flujos de registros»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Linux Command Line & Bash Scripting Mastery?
Sí. Cada lección de Linux Command Line & Bash Scripting Mastery incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Análisis de registros web y de aplicaciones a gran escala
- Seguimiento de registros en tiempo real y alertas en streaming
- Consulta de journald con journalctl en scripts
- Cálculo de métricas e histogramas a partir de flujos de registros