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
$