Blog

Analyse de logs SMTP en live : comment repérer une défaillance de délivrabilité avant qu’elle ne vous coûte des ventes

 

 

Tout avait l’air normal. La campagne email était partie, aucun retour d’erreur, les outils marketing affichaient un taux d’ouverture correct.

Et pourtant : les ventes chutaient. Le tunnel s’était vidé.

La vraie raison ? Une défaillance silencieuse dans la livraison d’une partie des emails. Invisible sur Mailchimp, absente des dashboards. Mais parfaitement visible… dans les logs SMTP.

 

Pourquoi les logs SMTP sont votre meilleur outil d’alerte

Un email ne meurt pas toujours bruyamment. Parfois, il se contente de ne jamais arriver.

Les logs SMTP, ce sont vos boîtes noires : chaque tentative, chaque rebond, chaque refus est enregistré. Encore faut-il les lire, les comprendre, et les exploiter en temps réel.

 

Comment lire un log SMTP (et ce qu’il vous raconte)

Voici un exemple brut de log Postfix :

 

status=sent (250 2.0.0 OK 168ms)

status=deferred (421 4.7.0 Try again later)

status=bounced (550 5.1.1 User unknown)

 

status=sent → Le message est accepté, mais attention au temps de réponse.

status=deferred → Le serveur distant a temporairement rejeté l’envoi.

status=bounced → L’adresse est invalide ou le domaine a refusé l’envoi.

 

Chaque code SMTP raconte une histoire. Et certaines sont urgentes à lire.

 

Trois cas réels rencontrés en live

⚠️ Cas #1 : Greylisting silencieux

status=deferred (451 Temporary local problem)

Impact : les mails transactionnels ont mis jusqu’à 3h à être reçus. Les confirmations de commande aussi.

⚠️ Cas #2 : Filtrage par mauvaise réputation

550-5.7.1 Our system has detected an unusual rate of unsolicited mail...

Analyse : domaine mal authentifié, IP neutre, contenu perçu comme suspect. Blocage complet.

⚠️ Cas #3 : Boucle interne

mail for client.com loops back to myself

Diagnostic : une erreur DNS provoquait un renvoi vers le même serveur → aucune livraison.

 

Comment les monitorer efficacement ?

  • En shell : tail -f /var/log/mail.log | grep status=
  • Avec des scripts Python (voir plus bas)
  • Intégration Prometheus + Grafana + Loki pour dashboarding
  • Alertes sur deferred > 10m ou bounce rate > 5%

 

Ce que vous pouvez en faire (et gagner)

  • Détecter un problème avant que les utilisateurs ne s’en plaignent

  • Identifier les domaines sensibles (Gmail, Outlook) qui réagissent mal

  • Améliorer votre warm-up / segmentation en fonction des réactions en live

  • Prévenir vos commerciaux d’une vague de mails non livrés

 

Conclusion

 

Les logs SMTP ne sont pas faits pour les robots. Ils sont faits pour vous.

En les lisant, vous prenez le contrôle de vos envois, de vos délais, de votre réputation.

Car oui : un email perdu, ce n’est pas qu’un pixel manquant. C’est une conversion évaporée.

Et chaque log vous en dit un peu plus sur comment ne plus la rater.

 

📅 Bonus

Fiche PDF : Lire un log SMTP Postfix en 5 min

 

Script Python : tracker automatique d’événements SMTP critiques
 

import re
from datetime import datetime

# Exemple de ligne de log postfix :
# Dec 12 10:12:34 mail postfix/smtp[1234]: ABC123: to=<user@gmail.com>, relay=gmail-smtp-in.l.google.com[74.125.20.26]:25, delay=2.1, delays=0.05/0.01/0.5/1.5, dsn=2.0.0, status=sent (250 2.0.0 OK  1702371154)

LOG_PATH = "/var/log/mail.log"

# Détection d'anomalies SMTP
def parse_smtp_logs(filepath):
    critical_events = []
    with open(filepath, 'r') as log:
        for line in log:
            if 'status=' in line:
                status_match = re.search(r'status=([a-z]+)', line)
                delay_match = re.search(r'delay=([0-9\.]+)', line)
                if status_match:
                    status = status_match.group(1)
                    delay = float(delay_match.group(1)) if delay_match else 0.0

                    if status in ['bounced', 'deferred'] or delay > 5:
                        timestamp = " ".join(line.split()[0:3])
                        message = f"[{timestamp}] {status.upper()} - Delay: {delay}s\n{line.strip()}"
                        critical_events.append(message)
    return critical_events

# Exemple d'utilisation
events = parse_smtp_logs(LOG_PATH)
for event in events:
    print(event)