Analyse des logs postfix
Le script suivant analyse les logs postfix et retourne le nombre de messages par code erreur SMTP.
3 niveaux de visualisation sont proposés dont le jour et le mois en cours.
Pour fonctionner, le script à besoin d'un fichier additionnel répertoriant la liste des codes erreurs et leurs descriptions.
Téléchargement des fichiers :
Détail du fichier codeErrorSmtp :
$ cat codeErrorSmtp
X.1.0|Other address status
X.1.1|Bad destination mailbox address
X.1.2|Bad destination system address
X.1.3|Bad destination mailbox address syntax
X.1.4|Destination mailbox address ambiguous
X.1.5|Destination mailbox address valid
X.1.6|Mailbox has moved
X.1.7|Bad sender's mailbox address syntax
X.1.8|Bad sender's system address
X.2.0|Other or undefined mailbox status
X.2.1|Mailbox disabled, not accepting messages
X.2.2|Mailbox full
X.2.3|Message length exceeds administrative limit.
X.2.4|Mailing list expansion problem
X.3.0|Other or undefined mail system status
X.3.1|Mail system full
X.3.2|System not accepting network messages
X.3.3|System not capable of selected features
X.3.4|Message too big for system
X.4.0|Other or undefined network or routing status
X.4.1|No answer from host
X.4.2|Bad connection
X.4.3|Routing server failure
X.4.4|Unable to route
X.4.5|Network congestion
X.4.6|Routing loop detected
X.4.7|Delivery time expired
X.5.0|Other or undefined protocol status
X.5.1|Invalid command
X.5.2|Syntax error
X.5.3|Too many recipients
X.5.4|Invalid command arguments
X.5.5|Wrong protocol version
X.6.0|Other or undefined media error
X.6.1|Media not supported
X.6.2|Conversion required and prohibited
X.6.3|Conversion required but not supported
X.6.4|Conversion with loss performed
X.6.5|Conversion failed
X.7.0|Other or undefined security status
X.7.1|Delivery not authorized, message refused
X.7.2|Mailing list expansion prohibited
X.7.3|Security conversion required but not possible
X.7.4|Security features not supported
X.7.5|Cryptographic failure
X.7.6|Cryptographic algorithm not supported
X.7.7|Message integrity failure
$
Détail du script commenté :
$ nl mail.awk
1 BEGIN{
2 # Si le nombre d'arguments est egal a 1
3 # Arret du programme
4 # Il faut au moins 2 arguments (1 nom de fichier de log)
5 # Le script peut accepter plusieurs fichiers de log
6 if(ARGC==1){
7 print "Nombre d'arguments incorrect"
8 print "Syntaxe : awk -f mail.awk fichierLogMail1 [fichierLogMailn...]"
9 exit 1
10 }
11 # Initialisation de la variable contenant le nom du fichier
12 # des codes erreurs SMTP
13 errorSmtp="codeErrorSmtp"
14 # Execution d'une commande systeme pour tester si le fichier existe
15 # Arret du programme si le fichier n'existe pas
16 if((system("test -f " errorSmtp))==1){
17 print "Fichier codeErrorSmtp manquant"
18 exit 1
19 }
20 # Sauvegarde des donnees du fichier codeErrorSmtp
21 # dans un tableau associatif avec le code en cle
22 while((getline < errorSmtp) == 1){
23 ligne=$0
24 split(ligne,tab,"|")
25 tabErr[tab[1]]=tab[2]
26 }
27 # Fermeture du fichier codeErrorSmtp
28 close(errorSmtp)
29 # Affichage du menu
30 while(1){
31 # Si le choix est passe en argument
32 if(ARGV[1] ~ /^choix=/){
33 split(ARGV[1],tab,"=")
34 choix=tab[2]
35 if(choix>=1 && choix<=3) break
36 }
37 print "Choix date"
38 print " 1 - all"
39 print " 2 - day"
40 print " 3 - month"
41 printf("Choix : ")
42 # Lecture de l'entree clavier
43 # Si erreur, on quitte la boucle while
44 if((getline choix < "-")!=1) break
45 # Si aucune saisie, reaffichage du menu
46 if(length(choix)==0) continue
47 # Si le choix est compris entre 1 et 3 on quitte la boucle while
48 if(choix>=1 && choix<=3) break
49 }
50 deb=systime()
51 # Si le choix est egal a rien on quitte le programme
52 if(choix==""){
53 print "Bye"
54 exit 2
55 }
56 print "-------------------------------------------"
57 print "------- Analyse des fichiers de log -------"
58 print "-------------------------------------------"
59 }
60 # Lecture des fichiers de log
61 # Si la ligne courante contient l'expression recherchee
62 $0 ~ /[0-9][0-9][0-9] [0-9]\.[0-9]\.[0-9]/ && (choix==1 || (choix==2 && $1==getMonth() && $2==getDay()) || (choix==3 && $1==getMonth())) {
63 # Recherche de la position du premier caractere de l'expression xxx x.x.x
64 pos=match($0,/[0-9][0-9][0-9] [0-9]\.[0-9]\.[0-9]/)
65 # Extraction de l'expression xxx x.x.x
66 code=substr($0,pos,9)
67 # Sauvegarde de l'expression comme cle du tableau associatif
68 # et incrementation du compteur
69 codeSmtp[code]+=1
70 }
71 END{
72 # Parcourt du tableau associatif codeSmtp
73 totalMessages=0
74 for(i in codeSmtp){
75 # Affichage des lignes du tableau
76 # et de la description du code avec la fonction descCode
77 printf("Code %s (%-45s) ==> %5d message(s)\n",i,descCode(i),codeSmtp[i])
78 totalMessages+=codeSmtp[i]
79 }
80 # Fin du programme
81 fin=systime()
82 duree=fin-deb
83 printf("Total : %d messages\n%d lignes traitees en %d sec\n",totalMessages,NR,duree)
84 exit 0
85 }
86 # Fonction permettant la recherche de la description du code
87 function descCode(code){
88 # Extraction des 4 derniers caracteres du code à partir du 6eme caractere
89 codex=substr(code,6,4)
90 # Concatenation de la lettre "X" aux 4 derniers caracteres du code
91 codex="X" codex
92 # Extraction de la description en fonction du code
93 desc=tabErr[codex]
94 # Si le code erreur n'existe pas alors OK
95 desc=(desc != "" ? desc : "OK")
96 # Retour de la description au programme appelant
97 return desc
98 }
99 # Fonction permettant d'obtenir le numero du jour en cours
100 function getDay(){
101 day=int(strftime("%d"))
102 return day
103 }
104 # Fonction permettant d'obtenir le nom du mois en cours
105 function getMonth(){
106 month=strftime("%b")
107 return month
108 }
$
Exécution du script :
$ awk -f mail.awk /var/log/mail.log
Choix date
1 - all
2 - day
3 - month
Choix : 3
-------------------------------------------
------- Analyse des fichiers de log -------
-------------------------------------------
Code 554 5.7.1 (Delivery not authorized, message refused ) ==> 1992 message(s)
Code 550 5.1.1 (Bad destination mailbox address ) ==> 23 message(s)
Code 250 2.0.0 (OK ) ==> 1620 message(s)
Total : 3635 messages
42719 lignes traitees en 0 sec
$
En passant le choix de la date en argument :
$ awk -f mail.awk choix=3 /var/log/mail.log
-------------------------------------------
------- Analyse des fichiers de log -------
-------------------------------------------
Code 554 5.7.1 (Delivery not authorized, message refused ) ==> 1992 message(s)
Code 550 5.1.1 (Bad destination mailbox address ) ==> 23 message(s)
Code 250 2.0.0 (OK ) ==> 1620 message(s)
Total : 3635 messages
42719 lignes traitees en 0 sec
$
Commentaires
Karl (non vérifié)
jeu, 14/11/2019 - 14:46
Permalien
utilisation du script
Bonjour,
sous RedHat, le nom du fichier de log se nomme maillog, mais à part ce point, le script fonctionne très bien.
Merci encore.
cordialement,
Karl
Stéphane (non vérifié)
jeu, 05/03/2020 - 10:32
Permalien
Petite modification?
Bonjour,
Tout d'abord, merci pour ce script qui m'a été très utile.
J'ai une petite demande de modification.
Par notre serveur postfix, nous avons envoyé une campagne d'émailing et nous voudrions connaître l'état des mails envoyés (environ 13000).
Je voudrai donc pouvoir entrer en paramètre du script l'adresse de l'expéditeur car sinon j'ai les infos pour toutes les adresses d'envoi.
Mais je ne sais pas comment faire :/
Pensez-vous que c'est possible et si oui, comment? Merci de votre aide.
Bien à vous,
ronan
ven, 06/03/2020 - 11:06
Permalien
Bonjour,
La première idée qui me vient à l'esprit est la chose suivante.
A vérifier bien sûr en faisant une comparaison manuelle
$ grep -F 'from=<user@domaine.fr>' /var/log/mail.log | gawk -f mail.awk choix=1
Je pense que ça doit fonctionner car j'ai constaté que l'adresse mail de l'expéditeur et le code de retour sont sur la même ligne dans les fichiers de logs.
Stéphane (non vérifié)
ven, 06/03/2020 - 15:19
Permalien
Pas tout à fait cela
Bonjour,
Merci de ta réponse rapide.
Lorsque exécute la commande ci-dessus, j'obtiens quelques lignes comme celle-ci:
Feb 28 09:43:59 nom_serveur postfix/qmgr[23080]: 2D9B4221790: from=, size=5465, nrcpt=3 (queue active)
Mais pas le résultat escompté. As-tu un idée? Merci d'avance.
Bien à toi.
ronan
ven, 06/03/2020 - 15:32
Permalien
C'est ce que je craignais
Utilise le lien https://www.quennec.fr/c0nt%40ct
Ce sera plus simple que via des commentaires.
J'ai une petite idée sur la question mais il faudrait faire un petit script python à la place je mense.
Ce serait beaucoup plus simple.
Envoi moi un message via mon formulaire de contact de cette manière j'aurais ton adresse mail et nous pourrons communiquer plus facilement.
Stéphane (non vérifié)
mar, 15/12/2020 - 09:27
Permalien
pflogsumm
Bonjour,
Via ce lien, je récupère tout ce qu'il se passe sur mon serveur postfix:
https://blog.microlinux.fr/pflogsumm-centos-7/
Nickel ^^
Bonne journée.
Stéphane (non vérifié)
mar, 15/12/2020 - 09:28
Permalien
pflogsumm
Bonjour Ronan,
Sur cette page, le script exécute tout ce donc j'ai besoin:
https://blog.microlinux.fr/pflogsumm-centos-7/
@+
ronan
mar, 15/12/2020 - 09:35
Permalien
A chaque problème...
... sa solution
Ajouter un commentaire