IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Programmation et administration système Perl Discussion :

notification de mail entrant - postfix/linux


Sujet :

Programmation et administration système Perl

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut notification de mail entrant - postfix/linux
    Bonjour,

    je cherche un petit script permettant d'analyser le fichier /var/log/mail.log puis extraire les infos comme :
    Date
    mail_from
    mail_to
    enfin les envoyer à user@domain.local. Dans un premier temps je les affiche pour voir déjà si ça marche.

    Je ne maîtrise pas Perl et encore moins les expressions régulières. Est ce que quelqu'un peut me donner un coup de main, pour faire ce script ?

    J'imagine un début de ce type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #!/usr/bin/perl -w
    use strict;
     
    my $mail_from;
    my $mail_to;
    my $date;
     
    open(FILE, "/var/log/mail.log") or die "je n'ai pas pu ouvrir le fichier mail.log: $!; aborting";
    while (<FILE>) {
    if ($_ =~ belle expression régulière) {
    $date = $1;
    $mail_from = $2;
    $mail_to = $3;
     
    print "date: \t", $date,"\n";
    print "mail_from: \t", $mail_from,"\n";
    print "mail_to: \t", $mail_to,"\n\n";
    }
    }
    close(FILE)
    ;

  2. #2
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 247
    Points : 406
    Points
    406
    Par défaut
    c'est un bon début mais le problème c'est qu'une expression régulière est étroitement lié au format des données alors à moins d'être magicien....

    mets nous un exemple du format de tes données et on t'aidera

  3. #3
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    En effet, sans voir les données en entrée, on ne pourra pas trop t'aider à construire ton expression régulière.

    Un ou deux conseils cependant.

    Utilise plutôt "use warnings;" que la syntaxe "-w" plus ancienne et bien moins pratique.

    Ne déclare pas tes variables en début de programme mais dans le scope où tu en as besoin.

    Surtout, prends l'habitude de bien indenter ton code, c'est bien plus lisible et t'évitera de nombreux bugs. Par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #!/usr/bin/perl
    use strict;
    use warnings;
     
    open my $FILE, "<", "/var/log/mail.log" or die "je n'ai pas pu ouvrir le fichier mail.log: $!; aborting";
    while (<$FILE>) {
         if ($_ =~ belle expression régulière) {
              my $date = $1;
              my $mail_from = $2;
              my $mail_to = $3;
     
              print "date: \t", $date,"\n";
              print "mail_from: \t", $mail_from,"\n";
              print "mail_to: \t", $mail_to,"\n\n";
         }
    }
    close($FILE);
    Regarde aussi la syntaxe que j'ai employée pour l'ouverture du fichier.

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Avec toutes mes excuses.

    J'utilise postfix sous linux. Je n'ai pas trouvé une documentation sur le format des données.
    Le lien suivant donne quelques exemples d'expressions régulières pour extraire certaines informations :http://activedeveloper.info/a-thing-...-analysis.html

    A priori, on peut extraire l'adresse mail_from (sender) et la date dans l'entrée "postfix/qmgr".
    mail_to ( destination) dans "postfix/smtp"
    l'IP du client (sender) qui se connecte au serveur SMTP, dans "postfix/smtpd".

    Lolo78, j'ai intégré l'ensemble de tes préconisations. Merci

    Merci

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Pas de raison de d'excuser, il n'y a eu aucun mal.

    Pour commencer, donne juste un extrait du fichier que tu veux étudier. Quelques dizaines de lignes suffiront, au moins pour commencer. On verra plus tard si on a besoin de plus d'exemples.

    Nous n'avons sans doute pas besoin d'aide pour trouver les bonnes expressions régulières, qui ne sont sans doute pas très complexes, mais il est impossible d'écrire une expression régulière sans voir les données qu'elle cherche à reconnaître (ou avoir une spécification très précise de leur format, mais là, il est presque certain que je rêve). Donc, un échantillon du fichier, et une explication de ce que tu veux extraire si ça n'est pas clair.

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 71
    Points : 87
    Points
    87
    Par défaut
    salut,

    attention, si tu es sur un serveur distant ( même en local je dirai ), le fait d'afficher sur 3 lignes les mails risquent à long terme d'être illisible ( en fonction de la quantité de mails gérés journalièrement par le serveur ).

    il faudrait par exemple, à la fin de l’exécution de ton script soit faire une copie de /var/log/mail.log de manière a ensuite pouvoir créer un nouveau fichier ( /var/log/mail.log ) et ainsi, tu n'afficheras que les mails que tu n'as pas vérifié.

    ou alors de t'envoyer par mail le résultat si tu es sur un serveur distant ou de l'enregistrer dans un fichier si tu es en local. l'avantage, c'est que tu pourrais faire un crontab et te permettrait d'avoir un log pas trop lourd et assez bien classé ( 1 fois par semaine/mois par exemple ).

    pense à vérifier aussi le fichier de conf de syslog ( de mémoire /etc/syslog.conf ) de manière a ce que ne soit stocké dans /var/log/mail.log que les mails entrants et sortants ( postfix utilise le daemon de syslog ).

    quelques infos interessantes : sur le send/recp et delivery attempt et un exemple ici ou tu pourras voir que la, tu as des erreurs, et pas que le send/recep regarde aussi ici : rotatelog devrait t interesser .

    cordialement

    ours

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Merci pour les liens/ la doc. Je ne cherche pas afficher les mails sur 3 lignes. Je veux juste extraire 3 infos dans le fichier mail.log, pour chaque email reçu. Enfin, envoyer ces 3 infos par mail comme notification de réception de message par le serveur mail.

    L'un des liens que tu as rapporté (http://www.developpez.net/forums/red...2Ft-15795.html) donne un exemple du contenu de mail.log avec certaines logs postfix.

    Par exemple, quelle est l'expression qui permet d'extraire la date et le champ "to" dans la ligne suivante ? :
    Mar 31 14:44:44 ns39531 postfix/smtp[3677]: 9F7639AED8: to=<klmn@yahoo.com.tw>, relay=mx2.mail.tw.yahoo.com[203.188.197.10]:25, delay=64574, delays=63690/880/3.5/0, dsn=4.0.0, status=deferred (host mx2.mail.tw.yahoo.com[203.188.197.10] refused to talk to me: 453 Mail from 91.121.23.77 not allowed - [90])comment

  8. #8
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    voici un exemple de regex qui marche dans le cas de la ligne en question, testée ici sous le debugger Perl:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      DB<1>  $_ = 'Mar 31 14:44:44 ns39531 postfix/smtp[3677]: 9F7639AED8: to=<klmn@yahoo.com.tw>, relay=mx2.mail.tw.yahoo.com[203.188.197.10]:25, '
     
      DB<2>  ($date, $to) = /^(\w{3} \d+ \d+:\d+:\d+)[^=]+ to=<([^>]+)>,/;
     
      DB<3> x  ($date, $to)
    0  'Mar 31 14:44:44'
    1  'klmn@yahoo.com.tw'
    N'hésite pas à demander si tu veux des explications complémentaires.

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Merci beaucoup. ça marche. Par contre, il s’arrête au 31 décembre minuit.
    Ci-dessous le programme de test

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #!/usr/bin/perl
    use strict;
    use warnings;
    #use Email::MIME;
    #use Email::Sender::Simple qw(sendmail);
     
    open(my $FILE, "<", "/var/log/mail.log") or die "je n'ai pas pu ouvrir le fichier mail.log: $!; aborting";
    while (<$FILE>) {
     
    if ($_ =/^(\w{3} \d+ \d+:\d+:\d+)[^=]+ to=<([^>]+)>,/)
            {
            my $date;
            my $mail_to;
            $date = $1;
            $mail_to = $2;
            print "date: \t", $date,"\n";
            print "mail_to: \t", $mail_to,"\n\n";
            }
    }
    close(FILE);

  10. #10
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par FFFF_FR Voir le message
    Par contre, il s’arrête au 31 décembre minuit.
    Hum, il faudrait que tu montres une ligne correspondant à début janvier, mais il est probable que la date n'aie pas tout-à-fait le même format en début de mois (jour du mois sur un chiffre, et deux espaces avant), même chose pour l'heure quand elle est inférieure à 10 (un seul chiffre). Essaie de changer l'expression régulière comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my ($date, $to) = /^(\w{3} +\d+ +\d+:\d+:\d+)[^=]+ to=<([^>]+)>,/;
    Cela devrait marcher. Mais sinon, montre la ligne non reconnue, on trouvera. Comme je l'ai déjà dit, l'utilisation d'expressions régulières nécessite de très bien connaître les données en entrée.

    Le mieux serait cependant que tu commences à apprendre à comprendre les expressions régulières, tu pourrais faire les ajustements toi-même. Cela paraît hautement cryptique quand on ne connaît pas, mais c'est vraiment pas si compliqué en fait.

  11. #11
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Merci Lolo78,
    Elle est passée. Je vais m'y mettre bien que je ne suis pas du tout développeur.
    Connais-tu un lien Internet genre "expressions régulières pour les nuls" ? Cela me permet de débuter avant d'acheter un livre qui traite du sujet...

    Bien entendu, si tu peux donner quelques commentaires sur l'une des deux expressions régulières que tu as postées, je suis preneur. si c'est long, ne te casses pas la tête, je trouverai au fur et à mesure de mes recherches...

    J'ai une petite question:
    Dans un autre programme je lirai la fin d'un fichier généré en partie grace au premier programme, pour envoyer le contenu de $1, $2 et $3 par mail.

    (Le click sur les balises [_code] et [/code_], permettant de rendre le texte suivant plus lisible, ne semble pas fonctionner avec mon navigateur. Je les ai saisies manuellement).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    my $message = Email::MIME->create(
      header_str => [
                           From => 'root@domaine.fr',
                           To => 'newmail@domaine.fr',
                           Subject => 'nouveau message!',
                           ],
      attributes => 
                       {
                       encoding => 'quoted-printable',
                       charset  => 'ISO-8859-1',
                       },
    #body_str => "cette fonction n'envoie que du texte, alors que j'aimerai envoyer dans le corps du mail les infos date, mail_from et mail_to. Q'elle autre fonction faudra t-il utiliser ?\n",

  12. #12
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Euh, le module Email::MIME, je ne l'ai jamais utilisé, je ne vais pas trop pouvoir t'aider à ce sujet.

    Sur les expressions régulières, voici une explication de la dernière version que j'ai proposée:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /^(\w{3} +\d+ +\d+:\d+:\d+)[^=]+ to=<([^>]+)>,/;
    Une regex décrit progressivement le texte à reconnaître:
    • '^' : début de la chaîne, suivi de
    • '(' : parenthèse indiquant le début de la première capture ($1)
    • '\w{3}' : trois caractères alphanumériques, suivi de
    • ' +' : un ou plusieurs espaces, suivi de
    • '\d+' :un ou plusieurs chiffres, suivi de
    • ' +' :un ou plusieurs espaces, suivi de
    • '\d+:' : un ou plusieurs chiffres, suivi d'un ':', suivi de
    • '\d+:' : un ou plusieurs chiffres, suivi d'un ':', suivi de
    • '\d+' un ou plusieurs chiffres, suivi de
    • ')' : fin de la première capture ($1)
    • '[^=]+' : Les crochets indiquent une classe de caractères, le ^ en début de classe de caractère indique tous les caractères sauf ceux définis dans le reste de la classe; '[^=]+' indique donc un ou plusieurs (autant que possible) caractères autres que le '='; suivi de
    • 'to=<' : la suite littérale de caractères 'to=<', suivi de
    • '(' : parenthèse indiquant le début de la seconde capture ($2)
    • '[^>]+' : nouvelle classe de caractères indiquant un ou plusieurs caractères (autant que possible) autres que '>', suivi de
    • ')' : fin de la seconde capture ($2)
    • '>,' : la suite littérale de caractères '>,'


    Certes, il y a quelques éléments de syntaxe à connaître, mais j'espère que tu vois, en décortiquant pas à pas, que ce n'est finalement pas si mystérieux que ça peut en avoir l'air.

  13. #13
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Merci pour toutes ces définitions; J'ai compris pour les parenthèses
    Pour les autres, euh...ça va venir....un jour.

    Je vais faire quelques exercices avec mon fichier mail.log.

  14. #14
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    En effet, c'est accessible. YAKA s'habituer...
    J'ai superposé ton expression avec la ligne de log pour faire la correspondance entre chacun des caractères de l’expression avec ceux qui leur correspondent dans cette ligne de log. Je crois pouvoir extraire d'autres données, enfin j'espère

Discussions similaires

  1. Réponses: 1
    Dernier message: 16/05/2008, 08h23
  2. [Continuum] [1.1-alpha-2] notification par mail
    Par marcxa44 dans le forum Intégration Continue
    Réponses: 12
    Dernier message: 30/04/2008, 12h52
  3. [Continuum] Notification par mail
    Par marcxa44 dans le forum Intégration Continue
    Réponses: 24
    Dernier message: 11/06/2007, 11h15
  4. Réponses: 3
    Dernier message: 25/01/2007, 11h10
  5. Réponses: 2
    Dernier message: 09/05/2006, 13h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo