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 :

analyse log apache


Sujet :

Programmation et administration système Perl

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut analyse log apache
    Bonjour à tous,

    Je souhaiterai créer un analyseur de log apache (bien que il en existe déjà) dans un but ludique.

    Pour cela je suis amené à réfléchir sur la façon dont procéder sachant que j'aimerai faire des statistiques.

    Prenons un exemple :

    90.90.90.90 - - [11/Feb/2009:19:45:42 +0100] "GET /index.php" 200 907 "http://www.developpez.com" "Mozilla/4.0 (compatible; MSIE 7.0; Windows)"
    L'idée serai de faire un découpage de chaque ensemble et de vérifier si à la ligne suivante on retrouve la même chose.

    Cela aurai pour but de définir les utilisateurs visitants le plus de site, les URLs les plus visitées etc...

    Avez-vous des conseils pour la façon dont procéder ?

    Expression régulière ? split ?

    Merci à vous

    PS : pardon si le sujet a déjà été abordé dans d'autres posts antérieurs.

  2. #2
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Voici un exemple élémentaire pour te donner des idées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/usr/bin/env perl
    use strict; use warnings;
     
    my %ip;
    while (<>) {
    	$ip{ (split /\s+/)[0] }++;
    }
     
    print map { $_, "\t", $ip{$_}, "\n" } 
    	sort { $ip{$b} <=> $ip{$a} } keys %ip;
    Comme tu l'as certainement compris, on comptabilise les addresses IP en incrémentant les valeurs d'un tableau associatif (dont les clés sont les IP), puis on affiche les clés par ordre décroissant d'occurrence.

    Tu peux raffiner en testant si le premier élément de ta ligne est bien une adresse IP (en l'extrayant avec une expr. reg. plutôt qu'avec le split).

    Tel quel, on lit l'entrée standart. Tu peux aussi lire des fichiers compressés (cas des logs généralement) si tu veux.

    Amuse-toi bien.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut
    plop iblis,

    Tout d'abord merci pour ta réponse

    Il va falloir que je boss les hash car je ne suis pas au point !

    Si je veux ressortir "l'IP : nombre de fois qu'elle apparait" dans la sortie du code, je me sert de quel variable ?

    En sortie je me retrouve actuellement avec une tabulation, le nombre de fois que l'IP apparait et un saut de ligne.

    Merci ^^

  4. #4
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Citation Envoyé par Nickname Voir le message
    En sortie je me retrouve actuellement avec une tabulation, le nombre de fois que l'IP apparait et un saut de ligne.
    As-tu modifié l'exemple ? Tel quel le bout de script parse un log apache du type de celui que tu as donné dans ton premier post.

    Change le split ou utilise une capture avec une regex.

    Pour le hash, on incrémente sa valeur pour chaque ip passé en clé.

    Voilà un exemple pas très propre mais fonctionnel pour capturer l'IP en début de ligne avec une regex et incrémenter le hash avec la valeur capturée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ip{ $1 }++ if /^(\d{,3}\.\d{,3}\.\d{,3}\.\d{,3})/;

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut
    Autant pour moi cela marche très bien.

    Voici mon code actuel (les indices IIS ne sont pas les bons) :

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
     
    #!/usr/bin/perl
    use strict;
    system("cls");
     
    print "Bienvenu dans le programme d\'analyseur de log\n";
    print " Quel type de log voulez-vous analyser ?\n\n";
    print "    1.Apache\n";
    print "    2.IIS\n\n";
    my $num = (<STDIN>);
    system("cls");
     
    print " Veuillez entrer le numero correspondant a l\'action voulue :\n\n";
    print "    1.Hits des adresses IP\n";
    print "    2.Hits des pages les plus visitees\n";
    print "    3.Hits des Referer\n";
    print "    4.Hits en Ko\n";
    print "    5.Hits des navigateurs\n";
    print "    6.Quitter le programme\n\n";
     
    open(Fichier, "log") || die "Problème à l\'ouverture : $!";
    my($ligne,@ips,$ip,%total,@pages,$page,%total1,@ref,$ref,%total2,@ko,$ko,%total3,@nav,$nav,%total4);
     
    if ($num == "1") {
       while (<Fichier>) {
     
         	 @ips = (split /\s+/)[0];
         	 foreach $ip (@ips) {
                  	  $total{$ip}++;
    }
     
       	 @pages = (split /\s+/)[6];
      	 foreach $page (@pages) {
              	  $total1{$page}++;
         }
     
            @ref = (split /\s+/)[9];
            foreach $ref (@ref) {
                      $total2{$ref}++;
         }
     
            @ko = (split /\s+/)[8];
            foreach $ko (@ko) {
              $total3{$ko}++;
         }
     
            @nav = (split /\s+/)[10];
            foreach $nav (@nav) {
              $total4{$nav}++;
         }
     
      }
    }
     
    elsif ($num == "2") {
         while (<Fichier>) {
     
            @ips = (split /\s+/)[0];
            foreach $ip (@ips) {
                     $total{$ip}++;
         }
     
            @pages = (split /\s+/)[3];
            foreach $page (@pages) {
                     $total1{$page}++;
         }
     
            @ref = (split /\s+/)[6];
            foreach $ref (@ref) {
              	 $total2{$ref}++;
         }
     
            @ko = (split /\s+/)[8];
            foreach $ko (@ko) {
                     $total3{$ko}++;
         }
     
            @nav = (split /\s+/)[12];
            foreach $nav (@nav) {
                     $total4{$nav}++;
         }
     
      }
    }
     
    else {
       print "\nNumero invalide - Au revoir\n";
       exit;
    }
     
    close(Fichier);
     
    my $num1 = (<STDIN>);
    if ($num1 == "1") {
    &subip();
    }
     
    elsif ($num1 == "2") {
    &subpage();
    }
     
    elsif ($num1 == "3") {
    &subref();
    }
     
    elsif ($num1 == "4") {
    &subko();
    }
     
    elsif ($num1 == "5") {
    &subnav();
    }
     
    else {
    print "\nA bientot\n";
    exit;
    }
     
    sub subip {
    foreach $ip (sort keys %total)
         {
        print "IP : $ip a ete rencontre $total{$ip} fois\n";
    }
    exit;
    }
     
    sub subpage {
    foreach $page (sort keys %total1)
         {
        print "La Page \"$page a ete visitee $total1{$page} fois.\n";
    }
    exit;
    }
    sub subref {
    foreach $ref (sort keys %total2)
         {
        print "Le referer $ref a ete vu $total2{$ref} fois.\n";
    }
    exit;
    }
    sub subko {
    foreach $ko (sort keys %total3)
         {
        print "Voici le hit des Kilos octets : $ko ko\n";
    }
    exit;
    }
    sub subnav {
    foreach $nav (sort keys %total4)
         {
        print "Le navigateur $nav a ete rencontre $total4{$nav} fois.\n";
    }
    exit;
    }
    Le script n'est cependant pas très optimisé.

    Maintenant j'aimerai faire un trie selon la date.

    L'utilisateur entre une plage : 01/Apr/2009 10/Apr/2009 et le script fait son analyse seulement sur cet intervalle.

    Avez-vous une idée comment procéder ?

    Une condition ne suffirait-elle pas ? le problème viendra du calcul de la plage date. J'aurai aimé faire sans module, mais je pense pas avoir le choix.

    Merci à vous

  6. #6
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Il doit surement exister des modules tout fait sur le CPAN pour gérer les log, t'as cherché un peu ?

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut
    Plop djibril,

    Oui il existe certain module comme Apache::log
    http://search.cpan.org/~gozer/mod_perl-1.30/Log/Log.pm

    Mais il est vrai que ces derniers sont assez mal documentés.

    De plus je dois rendre mon script compatible avec des log de type IIS.

    Niveau optimisation on m'a indiquer qu'il est préférable de mette le split dans un tableau @tab = split() afin de gagner en temps processeur.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut
    yop,

    Je viens de remarqué outre mon problème de date, un autre souci.

    Je n'ai pas un affichage dans l'ordre des IP qui ont le plus visitées le site.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    sub subip {
    foreach $ip (sort keys %total)
         {
             print "IP : $ip a ete rencontre $total{$ip} fois\n";
    }
    exit;
    }
    Le sort doit se faire sur l'ip ici au lieu du nombre de visite.

    Une idée ?

    Merci.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut
    Plop,

    J'ai tenté de faire d'une autre façon mais j'ai actuellement le même problème.

    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
     
     
    #!/usr/bin/perl -w
    use strict;
    use warnings;
     
    my $argu = @ARGV;
    my $EXPREG = q{(.*) \- \- \[(.*)\] \"(.*) (.*)\" ([0-9]*) ([0-9]*) \"(.*)\" \"(.*)\"};
    my %haship;
    open (Fichier, "< $ARGV[0]") or die "Ne peux pas ouvrir le fichier $ARGV[0]\n";
    while (my $ligne = <Fichier>){
                   my ($ip,$date,$method,$url,$ret_code,$byte,$referer,$user_a) = $ligne =~ $EXPREG;
                   $haship{$ip} += 1;
        }
    print map { "IP : $_ Nombre de fois : $haship{$_}\n" } sort keys %haship;
    close(Fichier);
    Une idée pourquoi le trie ne s'effectue pas ?

    Thx

  10. #10
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    essaye
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach $ip ( sort {$a <=> $b} keys %total) {
      #...
    }
    Peux tu nous afficher un exemple d'affichage de tes IPs

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut
    voila le résultat (avec ton code) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    IP : 13.99.90.90 a ete rencontre 1 fois
    IP : 20.90.90.90 a ete rencontre 1 fois
    IP : 32.90.90.90 a ete rencontre 1 fois
    IP : 88.90.90.90 a ete rencontre 1 fois
    IP : 90.90.92.91 a ete rencontre 1 fois
    IP : 90.90.90.90 a ete rencontre 2 fois
    IP : 92.90.90.90 a ete rencontre 2 fois
    IP : 120.90.90.90 a ete rencontre 1 fois
    IP : 142.90.90.90 a ete rencontre 2 fois
    IP : 144.90.90.91 a ete rencontre 1 fois
    IP : 200.90.90.90 a ete rencontre 1 fois
    IP : 202.92.90.90 a ete rencontre 1 fois
    Ici nous avons un trie sur l'adresse IP, et non sur le nombre de fois que l'ip est apparût.

  12. #12
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    et ? c'est pas ce que tu veux ?
    si tu veux trier sur les ip et ensuite visite, tu fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach $ip ( sort { $a <=> $b and $total{$a} <=> $total{$b} } keys %total) {
      #...
    }

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut
    J'aimerai faire un trie mais par rapport à la quantité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    IP : 13.99.90.90 a ete rencontre 10 fois
    IP : 20.90.90.90 a ete rencontre 8 fois
    IP : 32.90.90.90 a ete rencontre 5 fois
    IP : 88.90.90.90 a ete rencontre 2 fois
    IP : 90.90.92.91 a ete rencontre 2 fois
    IP : 90.90.90.90 a ete rencontre 1 fois
    IP : 92.90.90.90 a ete rencontre 1 fois

  14. #14
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach $ip ( $total{$b} <=> $total{$a} } keys %total) {
      #...
    }

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut
    yeahhh niquel

    Grand merci djibril !


    J'ai une autre petite question, je sais pas si tu aurai une idée au niveau des dates.

    Mon fichier de log est du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    90.90.90.90 - - [11/Feb/2009:19:45:42 +0100] "GET /index.php" 200 907 "http://www.developpez.com" "Mozilla/4.0 (compatible; MSIE 7.0; Windows)"
    J'aimerai que l'utilisateur donne une plage de date puis que le programme n'affiche le hit que de lesdites pages.

    Est-il nécessaire ou plus judicieux de passer par un module ?

    Thx pour ton aide ! bon app

  16. #16
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    regarde ici : http://perl.developpez.com/sources/?page=section3

    Tu peux jongler avec ces codes pour faire ce que tu veux.

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut
    Sympa tes codes sources pour la gestion des dates etc...

    Je vais essayé d'intégrer cela à mon script

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    161
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 161
    Points : 89
    Points
    89
    Par défaut
    Je viens d'essayer, avant de continuer au niveau des dates, de refaire la même chose sur les pages, referer etc...

    Mais je n'ai pas le trie qui s'effectue alors que pour l'IP le trie s'est bien déroulé.

    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
     
     
    sub subip {
    foreach $ip ( sort { $a <=> $b and $total{$b} <=> $total{$a} } keys %total)
         {
        print "IP : $ip a ete rencontre $total{$ip} fois\n";
    }
    print "\n\nAu revoir\n";
    exit;
    }
     
    sub subpage {
    foreach $page ( sort { $a <=> $b and $total1{$b} <=> $total1{$a} } keys %total1)
         {
        print "La Page \"$page a ete visitee $total1{$page} fois.\n";
    }
    print "\n\nAu revoir\n";
    exit;
    }
    Et il m'affiche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Le referer "http://www.dev.com" a ete vu 1 fois.
    Le referer "http://www.developpez.com" a ete vu 3 fois.
    Le referer "http://www.developp.com" a ete vu 6 fois.
    Le referer "http://www.truc.com" a ete vu 4 fois.
    Le referer "http://www.bidule.com" a ete vu 1 fois.
    Une idée ? Thx ^_^

    Edit : C'est bon enfait je ferme le topic, j'en ouvre un autre pour mes problèmes de date.

    Merci djibril

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Analyser logs apache, vérifer ip
    Par Merfolk dans le forum Apache
    Réponses: 4
    Dernier message: 22/05/2008, 22h45
  2. Analyser un fichier de log Apache
    Par altecad dans le forum Langage
    Réponses: 1
    Dernier message: 10/09/2007, 22h51
  3. Modif logs apache ?
    Par Cako19 dans le forum Apache
    Réponses: 2
    Dernier message: 10/01/2006, 11h36
  4. Logs apache
    Par knecmotet dans le forum Apache
    Réponses: 3
    Dernier message: 31/05/2005, 18h36
  5. Fichier Log apache et Redolog
    Par blids dans le forum Administration
    Réponses: 10
    Dernier message: 11/10/2004, 10h45

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