Files
logwatcher/docs/architecture.md
T
maurane fa5987215f docs(docs): 📝 update documentation files
update ruff and pyproject.toml. Sync or reinstall the package
2026-09-17 18:13:57 +02:00

6.8 KiB

Architecture

Vue d'ensemble

Logwatcher est un outil en ligne de commande Python qui analyse des fichiers de logs LAME MDC, identifie les erreurs pertinentes pour le support N2, et génère des rapports texte.

Le traitement suit un pipeline linéaire :

Flux fichiers fichiers de logs

  fichiers de logs
      │
      ▼
  parser.py       lit et parse les fichiers en LogEntry
      │
      ▼
  classifier.py   classe chaque entrée : N2 ou hors N2
      │
      ▼
  reporter.py     génère les trois rapports (all, n2, other)
      │
      ▼
  rapports .log
Flux mail

  boîte Exchange (dossier Logs)
      │
      ▼
  read_mail.py
      │
      ▼
  perser.py
      │
      ▼
  classifier.py
      │
      ▼
  reporter.py
      │
      ▼
  notifier.py

L'envoi du mail précède le déplacement des mails vers Analyzed. Si l'envoi échoue, les mails restent dans Logs et le rapport est régénéré au prochain passage : un rapport peut être envoyé deux fois en cas d'échec après envoi, mais jamais perdu.

Structure du package

src/logwatcher/
├── __init__.py          # expose __version__
├── __main__.py          # point d'entrée : python -m logwatcher
├── cli.py               # interface en ligne de commande (Typer)
├── config.py            # constantes : chemins, formats, source type
├── logging_config.py    # configuration du logging
├── models.py            # LogEntry : structure de données
├── mail_reader.py       # lecture de la boîte mail (EWS)
├── mail_utils.py        # utilitaires boîte mail (dossiers, constantes)
├── notifier.py          # envoi du rapport n2 par mail
├── parser.py            # lecture et parsing des logs
├── classifier.py        # classification N2 / hors N2
└── reporter.py          # génération des rapports texte

Modules

classifier.py — classification

  • N2_PATTERNS : dictionnaire des motifs d'erreurs pertinents pour le N2, fournis par les techniciens.
  • classify_log_entries() : sépare les entrées en deux listes (relevant, irrelevant) et remplit entry.error_name pour les entrées pertinentes.

cli.py — point d'entrée

  • Définit app = typer.Typer() et la commande principale.
  • Valide les arguments (--input-files / --input-dir mutuellement exclusifs).
  • Orchestre le pipeline : parsing → classification → rapports.
  • Gère les erreurs utilisateur (BadParameter, code de sortie 2) et les erreurs d'exécution (code de sortie 1).
  • Expose --version (eager, affiche et quitte).

config.py — constantes

  • Chemins : OUTPUT_PATH, RESULT_PATH, LOGGING_PATH, TEST_PATH, FIXTURE_PATH
  • Date et fuseau : DATETIME_FORMAT, FRENCH_TIMEZONE
  • Types : SourceType (FILE, MAIL)

logging_config.py — logging

  • setup_logging() : configure le logger racine.
  • Handler console (INFO, ou DEBUG si verbose) + handler fichier.
  • Le fichier de log logwatcher.log est horodaté et écrit dans le dossier de sortie.
  • Les loggers verbeux des dépendances (exchangelib) sont ramenés au niveau WARNING, afin de ne pas polluer logwatcher.log.

mail_reader.py — lecture de la boîte mail

Accès à la boîte via EWS (exchangelib), en authentification NTLM.

  • connect_to_mailbox() : lit EMAIL, PASSWORD et EWS_URL dans l'environnement, construit le compte et vérifie la connexion par un aller-retour serveur (accès à account.protocol.version).
  • fetch_log_messages() : retourne les mails du dossier Logs.
  • extract_logs_from_mails() : pour chaque mail, extrait les logs du corps ou de la pièce jointe CR_*, et les normalise en une liste de lignes. Ignore les lignes non conformes et avertit si le corps annonce une pièce jointe introuvable.
  • move_analyzed_mails() : déplace les mails traités vers le dossier Analyzed.

mail_utils.py — utilitaires boîte mail

  • get_or_create_folder(account, folder_name) retourne un dossier du compte, et le crée s'il n'existe pas. Utilisé pour les dossiers Analyzed et Sent.
  • Constantes : LOG_DIR, ANALYZED_FOLDER, SENT_FOLDER, LOG_IN_ATTACHMENT_PATTERN.

notifier.py — envoi du rapport

  • send_n2_report(account, summary, n2_log_file) : construit un message Exchange avec MAIL_TEMPLATE comme corps, attache n2_log_file, et l'envoie aux destinataires de N2_REPORT_RECIPIENTS. Une copie du message envoyé est conservée dans Logs/Sent (copy_to_folder). L'envoi passe par les services Exchange (message.send) : aucun serveur SMTP externe n'est requis.

models.py — LogEntry

Dataclass immuable (par convention) représentant une ligne de log parsée.

Champs principaux :

  • server_ip, mdc_server_name : origine du log
  • store_name : magasin concerné
  • start_time, error_time : horodatages
  • error_message : message d'erreur complet
  • error_name : nom du pattern N2 correspondant (rempli par le classifier)
  • raw_line : ligne brute d'origine
  • ligne : numéro de ligne dans le fichier source

LogEntry est créée uniquement par le parser. Le classifier l'enrichit (remplit error_name). Le modèle lui-même ne contient pas de logique métier.

parser.py — lecture et parsing

  • Patterns réutilisables : SERVER_IP_PATTERN, MDC_SERVER_NAME_PATTERN, DATE_TIME_PATTERN, STORE_NAME_PATTERN, ERROR_MESSAGE_PATTERN.
  • LOG_PATTERN : expression régulière compilée du format d'une ligne LAME MDC.
  • parse_line() : parse une ligne, retourne LogEntry | None.
  • parse_lines() : parse un itérable de lignes, ignore les lignes non conformes.
  • parse_file() : lit un fichier (encodage windows-1252) et délègue à parse_lines().

reporter.py — rapports

  • Templates texte (string.Template) : BASE_TEMPLATE, N2_SUPPORT_TEMPLATE, OTHER_TEMPLATE, ERROR_TEMPLATE.
  • build_reports() : construit les trois rapports (dict n2, other, all).
  • write_log_report() : prend un SourceType (FILE ou MAIL) pour adapter le libellé de l'en-tête ("Fichier(s) lu(s)" ou "Mail(s) lu(s)"). Les fichiers générés s'appellent all.log, n2.log et other.log.
  • _get_period() : calcule les bornes min/max des error_time.

Dépendances

Package Rôle
exchangelib Accès EWS à la boîte mail et envoi des rapports
mypy Typage statique (dev)
pytest Tests (dev)
pytest-cov Couverture (dev)
ruff Linting/formatage (dev)
typer Interface en ligne de commande