Adloun

Python (école d'ingénieur) · Chapitre 7 · Exercice

Analyseur de logs

Fichiers, exceptions et modules

Énoncé

Écrire un script qui analyse un fichier de log serveur au format Common Log Format et produit un rapport. Un log typique contient des lignes comme :

192.168.1.1 - - [10/Dec/2023:10:15:32] "GET /index.html" 200 1024
192.168.1.2 - - [10/Dec/2023:10:15:35] "POST /api" 404 512
192.168.1.1 - - [10/Dec/2023:10:15:40] "GET /about" 200 2048

Le script doit :

  • Compter le nombre total de requêtes.
  • Compter les requêtes par code HTTP.
  • Identifier les IP les plus actives.
  • Sauvegarder un rapport final dans un fichier texte.

Corrigé

import re
from collections import defaultdict

def analyser_logs(nom_fichier_log, rapport_sortie="rapport.txt"):
    """Analyse un fichier de log au format Apache/Common Log Format."""
    total_requetes = 0
    codes_http = defaultdict(int)
    ip_requetes = defaultdict(int)
    
    # Expression régulière pour parser une ligne de log
    pattern = re.compile(r'^(\d+\.\d+\.\d+\.\d+) - - \[(.*?)\] "(.*?)" (\d{3}) (\d+|-)$')
    
    try:
        with open(nom_fichier_log, 'r', encoding='utf-8') as f:
            for ligne in f:
                match = pattern.search(ligne.strip())
                if match:
                    ip, date, requete, code, taille = match.groups()
                    total_requetes += 1
                    codes_http[code] += 1
                    ip_requetes[ip] += 1
    except FileNotFoundError:
        print(f"Erreur : Fichier {nom_fichier_log} introuvable.")
        return
        
    # Tri des IP par nombre de requêtes (décroissant)
    ip_triees = sorted(ip_requetes.items(), key=lambda x: x[1], reverse=True)
    
    # Génération du rapport
    with open(rapport_sortie, 'w', encoding='utf-8') as f:
        f.write("=" * 50 + "\n")
        f.write("RAPPORT D'ANALYSE DE LOGS\n")
        f.write("=" * 50 + "\n\n")
        f.write(f"Total des requêtes : {total_requetes}\n\n")
        
        f.write("Codes HTTP :\n")
        for code, count in sorted(codes_http.items()):
            f.write(f"  {code} : {count}\n")
            
        f.write("\nIP les plus actives (top 10) :\n")
        for ip, count in ip_triees[:10]:
            f.write(f"  {ip} : {count} requêtes\n")
            
    print(f"Rapport généré dans {rapport_sortie}")

# Création d'un fichier de log de test
def creer_log_test():
    logs = [
        '192.168.1.1 - - [10/Dec/2023:10:15:32] "GET /index.html" 200 1024\n',
        '192.168.1.2 - - [10/Dec/2023:10:15:35] "POST /api" 404 512\n',
        '192.168.1.1 - - [10/Dec/2023:10:15:40] "GET /about" 200 2048\n',
        '192.168.1.3 - - [10/Dec/2023:10:15:45] "GET /index.html" 200 1024\n',
        '192.168.1.1 - - [10/Dec/2023:10:15:50] "GET /index.html" 200 1024\n',
        '192.168.1.2 - - [10/Dec/2023:10:15:55] "GET /contact" 404 256\n',
    ]
    with open("test.log", "w", encoding="utf-8") as f:
        f.writelines(logs)

# Test
creer_log_test()
analyser_logs("test.log")

100 % gratuit

La suite du chapitre est sur Adloun

Exercice suivant et tuteur

Sans compte : le cours et le premier QCM. Exercices et tuteur : inscription gratuite en 30 secondes, sans carte bancaire.

Le cours du chapitre · Tous les exercices du chapitre

Exercice suivant et tuteur →