Calculer des métriques et des histogrammes à partir de flux de journaux
Agrégerez directement à partir des journaux en flux les taux de requêtes, les percentiles et les rapports des N premiers éléments.
Calculer des métriques et des histogrammes à partir de flux de journaux est une leçon DevOps Bootcamp gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage DevOps Bootcamp, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours DevOps Bootcamp comprend 4 leçons au total.
Pourquoi calculer des métriques à partir des journaux bruts ?
Les systèmes de production émettent des milliers de lignes de journal par seconde. Plutôt que d’envoyer les journaux bruts vers des plateformes d’analyse coûteuses, vous pouvez calculer directement dans le shell les taux de requêtes, percentiles et rapports des N premiers éléments — pour un coût presque nul.
- Taux de requêtes : combien de requêtes par seconde ou par minute votre service traite-t-il ?
- Percentiles de latence : quel est le temps de réponse p50/p95/p99 ?
- Rapports des N premiers éléments : quels points d’accès, IP ou codes d’erreur apparaissent le plus souvent ?
Les outils shell tels que awk, sort, uniq et bc forment une puissante chaîne de traitement composable, capable de répondre à ces questions à partir d’un flux de journaux en direct ou d’un fichier historique sans quitter le terminal.
Anatomie d’un journal d’accès courant
La plupart des serveurs web écrivent les journaux au format de journal combiné. Comprendre ses champs constitue le fondement de toute chaîne de traitement de métriques :
127.0.0.1 - frank [10/Oct/2024:13:55:36 -0700] "GET /api/users HTTP/1.1" 200 2326 0.042- Champ 1 : IP du client
- Champ 4 (entre crochets) : horodatage
- Champ 7 (entre guillemets) : méthode HTTP + chemin
- Champ 9 : code d’état
- Champ 10 : octets de la réponse
- Champ 11 : temps de réponse en secondes (champ personnalisé, pas toujours présent)
Utilisez awk pour référencer les champs par leur position ($1, $9, etc.). Les champs entre guillemets comptent comme un seul élément uniquement si vous effectuez le découpage avec précaution — entourez la ligne de journal avec awk -F'"' ou utilisez plusieurs passes.
Compter le taux de requêtes par minute
Pour calculer le nombre de requêtes par minute, extrayez la portion correspondant à la minute de chaque horodatage et comptez les occurrences. Le motif [day/Mon/year:HH:MM vous fournit le compartiment heure-minute.
La chaîne de traitement ci-dessous lit access.log et affiche un tableau de minute → nombre de requêtes :
#!/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 -k2Taux sur fenêtre glissante avec un flux en direct
Pour un suivi en direct, vous avez besoin d’une fenêtre glissante. L’astuce consiste à utiliser tail -f transmis à awk, qui réinitialise son compteur toutes les N secondes à l’aide de l’horloge système (systime()).
Cet exemple affiche une ligne de taux toutes les 10 secondes :
#!/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
}
}'Extraire les valeurs de latence pour calculer les percentiles
Le calcul des percentiles nécessite de trier toutes les valeurs de latence observées. L’approche standard consiste à :
- extraire la colonne de latence dans une liste de nombres simples ;
- trier numériquement ;
- sélectionner la valeur au rang correct à l’aide du nombre de lignes.
Le script ci-dessous extrait le champ 11 (temps de réponse en secondes) et l’enregistre dans un fichier temporaire pour calculer le percentile à l’étape suivante :
#!/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 fileCalculer p50, p95 et p99 avec awk
Une fois les valeurs de latence triées, sélectionner un percentile relève de l’arithmétique : le percentile p se trouve à la ligne ceil(p/100 * N). Un simple awk peut effectuer cette opération en un seul passage après avoir chargé le fichier trié dans un tableau :
#!/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"Créer un rapport des N premiers points d’accès
Un rapport des N premiers éléments répond à la question « quels chemins sont les plus consultés ? » L’idiome classique du shell est le suivant :
awkpour afficher le champ recherché (par exemple, le chemin de l’URL) ;sortpour regrouper les valeurs identiques ;uniq -cpour compter les doublons consécutifs ;sort -rnpour classer par nombre décroissant ;head -n Npour prendre les N premiers éléments.
#!/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 premiers éléments par code d’état : repérer les erreurs en un coup d’œil
Les codes d’état HTTP indiquent l’état de santé de votre service. Regrouper les lignes de journal par code d’état et les compter permet de déterminer si les erreurs sont rares ou généralisées.
Le script ci-dessous produit une répartition dans tous les compartiments 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 -20Histogrammes ASCII avec awk
Un histogramme textuel rend les distributions de latence immédiatement lisibles dans un terminal ou un journal d’intégration continue. L’approche est la suivante :
- regrouper chaque valeur de latence dans un intervalle (par exemple, 0-50 ms, 50-100 ms, …) ;
- compter les observations par intervalle ;
- afficher une barre de caractères
#proportionnelle au nombre maximal.
C’est extrêmement utile pour repérer les distributions bimodales ou les valeurs aberrantes sans outil de création de graphiques.
#!/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"
fiCombiner les métriques : le rapport récapitulatif en une seule commande
Les guides d’exploitation de la production nécessitent souvent une seule commande qui émet toutes les métriques clés en une fois : taux, percentiles de latence, principaux points d’accès et taux d’erreur. Vous pouvez composer tout ce qui a été appris jusqu’ici dans un seul script qu’un humain ou un système d’alerte peut appeler.
#!/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)]
}'Diffuser des métriques via des tubes nommés et tee
Dans les chaînes de traitement d’observabilité, vous devez souvent dupliquer un flux de journaux : écrire les lignes brutes sur le disque et calculer simultanément les métriques. tee associé à un tube nommé (mkfifo) rend cela possible sans mettre en mémoire tampon l’intégralité du flux.
mkfifo /tmp/log_pipe— créer le tube nommétee /tmp/log_pipe | metric_consumer &— créer une branche vers le consommateur de métriques- L’autre branche écrit dans le fichier d’archive
Ce modèle dissocie les écritures sur disque de l’agrégation des métriques et permet à chaque partie de redémarrer indépendamment.
#!/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"Quelle technique awk calcule correctement le centile p95 à partir d’un tableau trié de N valeurs de latence ?
Vous avez chargé N valeurs de latence triées dans un tableau awk v[1..N]. Quelle expression permet de récupérer correctement le centile p95 ?
Récapitulatif de la leçon : métriques et histogrammes à partir de flux de journaux
Dans cette leçon, vous avez créé une chaîne complète de traitement des métriques directement en Bash :
- Débit des requêtes :
awkextrait la tranche de minute des horodatages et compte les occurrences ;tail -f+systime()fournissent un débit en temps réel sur une fenêtre glissante. - Centiles de latence : extraire la colonne de latence, appliquer
sort -n, puis sélectionner la ligne à la positionceil(p/100 * N)avecint(N * p + 0.9999)dans awk. - Rapports des N premiers éléments : la chaîne classique
awk | sort | uniq -c | sort -rn | head -Nfonctionne pour tout champ catégoriel (chemin, IP, code d’état). - Histogrammes ASCII : regrouper les valeurs par intervalles, compter les valeurs de chaque intervalle et ajuster la longueur des barres au nombre maximal de valeurs d’un intervalle pour obtenir une vue immédiate de la distribution.
- Distribution avec des tubes nommés :
mkfifo+teepermettent d’archiver les journaux bruts et d’alimenter simultanément les consommateurs de métriques sans charger le flux en mémoire.
Ces primitives composables éliminent le besoin d’outils externes pendant les incidents et constituent la base de scripts d’observabilité légers qui s’exécutent partout où Bash fonctionne.
Questions Fréquemment Posées
La leçon « Calculer des métriques et des histogrammes à partir de flux de journaux » est-elle gratuite ?
Oui — le texte complet de « Calculer des métriques et des histogrammes à partir de flux de journaux » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours DevOps Bootcamp, passe à CoddyKit PRO. Le cours DevOps Bootcamp comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Calculer des métriques et des histogrammes à partir de flux de journaux » ?
Agrégerez directement à partir des journaux en flux les taux de requêtes, les percentiles et les rapports des N premiers éléments. Tu pratiques DevOps Bootcamp avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer DevOps Bootcamp ?
Aucune expérience préalable n'est requise. DevOps Bootcamp sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Calculer des métriques et des histogrammes à partir de flux de journaux » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon DevOps Bootcamp ?
Oui. Chaque leçon DevOps Bootcamp inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Analyser les journaux web et applicatifs à grande échelle
- Suivre les journaux en temps réel et diffuser des alertes
- Interroger journald avec journalctl dans les scripts
- Calculer des métriques et des histogrammes à partir de flux de journaux