0Pricing
Linux Command Line & Bash Scripting Mastery · Leçon

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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Linux Command Line & Bash Scripting Mastery 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 -k2

Taux 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 à :

  1. extraire la colonne de latence dans une liste de nombres simples ;
  2. trier numériquement ;
  3. 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 file

Calculer 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 :

  • awk pour afficher le champ recherché (par exemple, le chemin de l’URL) ;
  • sort pour regrouper les valeurs identiques ;
  • uniq -c pour compter les doublons consécutifs ;
  • sort -rn pour classer par nombre décroissant ;
  • head -n N pour 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&nbsp;: 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 -20

Histogrammes 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 :

  1. regrouper chaque valeur de latence dans un intervalle (par exemple, 0-50 ms, 50-100 ms, …) ;
  2. compter les observations par intervalle ;
  3. 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"
fi

Combiner les métriques&nbsp;: 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 : awk extrait 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 position ceil(p/100 * N) avec int(N * p + 0.9999) dans awk.
  • Rapports des N premiers éléments : la chaîne classique awk | sort | uniq -c | sort -rn | head -N fonctionne 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 + tee permettent 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 Linux Command Line & Bash Scripting Mastery, passe à CoddyKit PRO. Le cours Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery ?

Aucune expérience préalable n'est requise. Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery ?

Oui. Chaque leçon Linux Command Line & Bash Scripting Mastery 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

  1. Analyser les journaux web et applicatifs à grande échelle
  2. Suivre les journaux en temps réel et diffuser des alertes
  3. Interroger journald avec journalctl dans les scripts
  4. Calculer des métriques et des histogrammes à partir de flux de journaux
← Retour à Linux Command Line & Bash Scripting Mastery