[Perl] Besoin d'aide - Page 2

  1. Salut lamj ;)

    J'ai testé ta dernière version,

    La ligne alloclips apparait toujours en 1er hors elle devrait apparaitre en derniers vu qu'il n'y a qu'une seul occurence de celle-ci dans access.log, non ?

    Merci
    0
    1. Modérateur
      Salut,

      Ben, alors on ne teste pas les même fichiers.
      Chez moi est affichée en dernier.
      0
  2. autant pour moi ca marhce très bien !

    ;)

    L'objectif suivant c'est de faire un cut de chaque groupe d'oocurences de ce que l'on obtiens de "sort @$_ for @trie" et de les placées dans un fichier (vhostjjmmaaaa.log)dans le path log correspondant a cette ocurrence(@f2).

    C'est dur ? tu t'y prendrais comment ?
    0
    1. Modérateur
      Re,

      Mets dans le script ce ces lignes et exécute le script.
      Ensuite affiche le résultat.

      print scalar @trie,"\n";
      print scalar @$_ for @trie;print for sort @reste;

      0
      1. tiens après exucution:

        sudo perl scriptlol.pl
        6
        2565111"access.log" [readonly][converted] 65641L, 17119557C
        0
        1. Modérateur
          Re,

          de les placées dans un fichier (vhostjjmmaaaa.log)
          ça ce n'est pas difficile

          dans le path log correspondant a cette ocurrence(@f2).
          Ça, je n'ai pas compris.

          Tu peux me donner un exemple?
          0
          1. Désolé j'ai du mal m'exprimé.

            Chaque lignes de logs pour ce groupe d'occurences (en s'occupant en 1er du vhost qui a le plus d'occurences) devra etre gréppé du résultat et etre placé dans un fichier vhostjjmmaaaa.log a l'adresse "pathlog" qui lui correspond dans vhost.conf (ex /mnt/filer-genet-3/a/b/ab......com/ftp/logs/).

            J'ai été plsu claire ? :(

            lol
            0
            1. Modérateur
              Re,

              Essaie ça
              #!/usr/bin/perl
              use strict;use warnings;
              
              open F,"access.log"  or die "E/S: $!\n";
              open FF,"vhost.conf" or die "E/S: $!\n";
              open FFF,">vhostjjmmaaaa.log" or die "E/S: $!\n";
              
              # 1ère partie : obtenir les tableaux
              my (@f1,@f2,@reste,%h);
              push @f1,(split ":",$_)[0] and push @f2,(split ":",$_)[1] while(<FF>);
              chomp@f2;
              
              # 2ème partie : faire le tri par rapport au tableau @f1
              while (<F>){
                        /^(.*?)\s/;push @{$h{$1}},$_ if grep{/$1/} @f1;
                          push @reste,$_ unless grep{/$1/}@f1;
              }
              
              my @trie = map  { $_->[1] }
                         sort { $b->[0] <=> $a->[0] }
                         map  { [ @$_+0, $_ ] } values %h;
              
              print sort @$_ for @trie;print for sort @reste;
              
              for my $e(@trie){
                for (@{$e}){
                  /^(.*?)\s.*/ and print FFF grep { /^$1/ } qx/cat vhost.conf/;
                }
              }
              __END__
              
              0
              1. Modérateur
                Salut,

                Essaie ce script.
                Toutefois, il n'est pas très performant vu qu'il y a trop d'appels système.
                En fait vu le résultat que tu veux obtenir, je ne vois pas à quoi ça sers de faire un tri par nombre d'occurrences, à moins que tu as un traitement particulier dont tu n'as pas parlé.

                Je vais pensé l'week-end prochain pour une optimisation.

                #!/usr/bin/perl
                use strict;use warnings;
                
                open F,"access.log"  or die "E/S: $!\n";
                open FF,"vhost.conf" or die "E/S: $!\n";
                
                # 1ère partie : obtenir les tableaux
                my (@f1,@f2,@reste,%h);
                push @f1,(split ":",$_)[0] and push @f2,(split ":",$_)[1] while(<FF>);
                chomp@f2;
                
                # 2ème partie : faire le tri par rapport au tableau @f1
                while (<F>){
                          /^(.*?)\s/;push @{$h{$1}},$_ if grep{/$1/} @f1;
                            push @reste,$_ unless grep{/$1/}@f1;
                }
                
                my @trie = map  { $_->[1] }
                           sort { $b->[0] <=> $a->[0] }
                           map  { [ @$_+0, $_ ] } values %h;
                
                #print sort @$_ for @trie;print for sort @reste;
                
                for my $e(@trie){
                  for (@{$e}){
                    /^((.*?\.).*?)\s.*/;
                    my $fic = "$2" . qx/date '+%d%m%Y'/;
                    open FFF,">>$fic" or die "E/S : $!\n";
                    print FFF grep { /^$1/ } qx/cat vhost.conf/;
                    close $fic;
                
                  }
                }
                __END__
                
                0
                1. Tu assures en attendant, je test ca demain !
                  0
                  1. Modérateur
                    Re,

                    Essaie plutôt ça et dit si ça te conviens.
                    #!/usr/bin/perl
                    use strict;use warnings;
                    open F,"access.log"  or die "E/S: $!\n";
                    my %h;
                    
                    while(<F>){
                      next unless /^(.*?)\s.*/;
                      $h{$1}++;
                    }
                    for (keys %h){
                      my $z=$_;
                      /^(.*?\.).*/;
                      chomp(my $fic="$1" . qx/date '+%d%m%Y'/);
                      my $c = grep { /^$z/ } qx/cat vhost.conf/;
                      if($c>0){
                        open FFF,">>$fic" or die "E/S : $!\n";
                        print FFF grep { /^$z/ } qx/cat access.log/;
                        close $fic;
                      }
                    }
                    __END__
                    
                    0
                    1. Sinon tu donnes des cours ? Combien de l'heure ? J'achète !

                      Merci ca fais vraiment plaisir de voir des gens comme toi, je test ça demain.
                      0
                      1. Modérateur
                        Salut,

                        Le dernier script que je te donné, selon moi, fonctionne (j'ai testé sur les deux fichiers que tu m'as donné).
                        En revanche access.log n'est pas grand.
                        J'ai fait un test sur un access.log de 200 Mo et le traitement a été fait en 1 minute (Athlon XP 1,5 Mhz, 512 DDRAM + 400 Mo swap)

                        Toutefois, je pense qu'on peut encore améliorer.
                        Si tu regardes bien, dans le script le fichiers access.log est parcouru plusieurs fois.
                        - une fois quand on stocke les host (voir la 1ère boucle while)
                        - dans la boucle for est parcouru en fonctionne de nombre de host trouvé et qui correspondent avec vhost
                        Donc ce n'est pas très efficace sur un fichier de quelque Go par exemple.

                        L'idéal sera de parcourrir le fichier access.log une seule fois et d'écrire dans vhostjjmmaa.log les lignes trouvées.

                        Je suis en train de penser à une solution.
                        D'ailleurs ce qui t'interesse c'est qu'en partant de l'access.log tu dois créer un vhostjjmmaa.log pour chaque vhost qui se trouve dans vhost.

                        Donc j'ai suivi ton raisonnement, et je suis parti à la recherche d'abord de vhost dans access.log (ce qui implique le 1ère parcours de access.log) et ensuite reprendre le vhost.conf pour voir si les vhost correspondent et ensuite pourcourrir le access.log pour chaque vhost.

                        Mon idée est en fait de lire le vhost.conf et ensuite de parcourrir une seule fois access.log et dès qu'en vhost est rencontré alors on écrit dans le fichier vhostjjmmaa.log.
                        Tu vois ce que je veux dire?

                        0
                        1. Modérateur
                          Salut,

                          Je viens de faire un test avec la dernière version que je t'ai donné et aussi avec une nouvelle que j'ai écrit selon le raisonnement de mon dernier message (Message N° 33 )

                          Le test je l'ai fait sur
                          lami20j@debian:~$ cat /proc/cpuinfo
                          processor : 0
                          vendor_id : AuthenticAMD
                          cpu family : 6
                          model : 8
                          model name : AMD Athlon(tm) XP 2200+
                          stepping : 0
                          cpu MHz : 1793.189

                          lami20j@debian:~$ free
                          total used free shared buffers cached
                          Mem: 516300 411508 104792 0 10540 170024
                          -/+ buffers/cache: 230944 285356
                          Swap: 393552 112172 281380

                          lami20j@debian:~$ uname -a
                          Linux debian 2.6.26-2-686 #1 SMP Wed Aug 19 06:06:52 UTC 2009 i686 GNU/Linux


                          J'ai utilisé un fichier access.log de 3.4 Go et plus de 20 millions lignes
                          lami20j@debian:/mnt/hda5/accesslog$ wc -l access.log; du -h access.log
                          20054931 access.log
                          3,4G    access.log


                          Pour la version du message 13 après presque 2heures j'ai eu Out of memory sans avoir le résultat voulu
                          lami20j@debian:/mnt/hda5/accesslog$ time perl stock_accesslog_v4.pl
                          Complété
                          
                          real    116m2.399s
                          user    2m49.391s
                          sys     0m42.367s
                          

                          En revanche avec une autre version le traitement a été effectué correctement dans 8minutes 32secondes
                          lami20j@debian:/mnt/hda5/accesslog$ time perl stock_accesslog_v5.pl
                          
                          real    8m39.852s
                          user    2m51.499s
                          sys     0m31.422s
                          

                          Il faudra qu'on parle en ce qui concerne cette dernière version.(Le chemin des logs n'est pas pris en compte. Un fichier vide sera crée pour chaque vhost, ce qui normalement ne dérange pas vu le gagne de performance.)
                          #!/usr/bin/perl
                          open F,"access.log" or die "E/S: $!\n";
                          open FF,"vhost.conf" or die "E/S: $!\n";
                          my (%h,%vhost);
                          chomp(my $date=qx/date '+%d%m%Y'/);
                          
                          while(<FF>){
                            /^(.*):.*/;
                            $vhost{$1}++;
                          }
                          
                          for(keys %vhost){
                            /^(.*?)\..*/;
                            my $vhostjjmmaa = "$1.$date";
                            open $vhostjjmmaa,">>${vhostjjmmaa}.log" or die "E/S: $!\n";
                          }
                          
                          while(<F>){
                            next unless /^((.*?)\..*?)\s.*/;
                            my $FH = "$2." . $date;
                            print $FH $_;
                          }
                          
                          for(keys %vhost){
                            /^(.*?)\..*/;
                            close "$1.$date";
                          }
                          __END__
                          

                          Mais après cette histoire, je me pose une question.
                          Pourquoi ne pas configurer une des directives (TransferLog, CustomLog) directement dans la configuration des VirtualHost ?
                          Comme ça il n'y a plus besoin d'un script Perl pour avoir les logs par vhost.
                          Apache s'occupera lui même.

                          0
                          1. Modérateur
                            Salut,

                            Pour la version du message 13
                            Correction : Pour la version du message 31
                            0
                            1. C'est un test en version non optimisé ? 410 mega en used, en effet pour un fichier de test access.log (de 200 méga, si mes souvenirs sont bons) ça fais beaucoup...

                              Je vois que tu me concoctes un truc au ptits oignons, je ne sais pas comment te remercier !

                              Tu aimes le vin de bourgogne ?
                              0
                          2. Modérateur
                            Re,

                            Ben, le script est dans le message.
                            Il est complétement modifié.
                            Je parcours le fichier access.log une seule fois, d''où le gagne de performances.

                            Mon raisonnement est dans le message 33
                            0
                            1. Pfff quel boulet !

                              Dslé j'ai pas cliquer sur la fenêtre qui donne le totalité du post (fatigue lol)

                              C'est un tres bonne nouvelle tout ca ! franchement Bravo !

                              en ce qui concerne ta question:

                              Mais après cette histoire, je me pose une question.
                              Pourquoi ne pas configurer une des directives (TransferLog, CustomLog) directement dans la configuration des VirtualHost ?
                              Comme ça il n'y a plus besoin d'un script Perl pour avoir les logs par vhost.
                              Apache s'occupera lui même.
                              


                              Oui je suis d'accords avce toi, je ne connais pas cette fonction je vais faire qq recherches la dessus.
                              Mais vu y'aura des fichiers genére genre dl.082009.log pour un vhost et peut etre un autre du même nom pour un autre vhost (vu que dl représente juste le serivce de download)... tu voit ce que je veux dire ???
                              0
                              1. Modérateur
                                Re,

                                J'ai créer les répertoire selon vhost.conf.
                                Les fichiers logs sont créer dans le répertorie correspondant.
                                Les fichiers vides seront supprimé à la fin.
                                Le test sur le même fichier de 3.4 Go varie chez moi (en fonction de la charge de mon pc, puisque je fais d'autre choses aussi ;-) entre 8minutes et 10 minutes
                                A savoir que peut être les noms des fichiers on le nom
                                nomdomainejusque1erpoint.jjmmaa.log

                                Voici le script.
                                Tu me diras le résultat des tests.
                                A savoir que le script doit être exécuter en root vu qu'on écrit un peu partout dans /mnt
                                
                                #!/usr/bin/perl
                                open F,"access.log" or die "E/S: $!\n";
                                open FF,"vhost.conf" or die "E/S: $!\n";
                                my (%h,%vhost);
                                chomp(my $date=qx/date '+%d%m%Y'/);
                                
                                while(<FF>){
                                  s/\s*$//g;
                                  /^(.*):(.*)/;
                                  $vhost{$1}=$2;
                                }
                                
                                for(keys %vhost){
                                  s/^\s*//g;
                                  /^(.*?)\..*/;
                                  my $vhostjjmmaa = "$1.$date";
                                  my $handle=$_;
                                  open $handle,">$vhost{$_}${vhostjjmmaa}.log" or die "E/S: $!\n";
                                }
                                
                                while(<F>){
                                  next unless /^((.*?)\..*?)\s.*/;
                                  my $FH=$1;
                                  print $FH $_;
                                }
                                
                                for(keys %vhost){ close $_;}
                                
                                for(values %vhost){
                                  opendir(REP,$_);
                                  while(my $fic=readdir REP){
                                    next if $fic=~/\.\.?$/;
                                    chomp(my $taille = qx/du -sh "$_$fic"/);
                                    unlink "$_$fic" if $taille=~/^0/;
                                  }
                                  close REP;
                                }
                                
                                __END__
                                
                                0
                                1. merci beaucoup je pourrais tester que en live car focément j'ai pas les droit pour tester ça seul...

                                  Peut tu me commenter tout ça ?

                                  Merci encore pour cette contribution énorme !
                                  0
                                  1. Modérateur
                                    Re,

                                    #!/usr/bin/perl
                                    open F,"access.log" or die "E/S: $!\n";
                                    open FF,"vhost.conf" or die "E/S: $!\n";
                                    my (%h,%vhost);
                                    # la date du système
                                    chomp(my $date=qx/date '+%d%m%Y'/);
                                    
                                    # la cle du hash    = le nom de domaine
                                    # la valeur du hash = le répertoire /mnt/....
                                    while(<FF>){
                                      s/\s*$//g;
                                      /^(.*):(.*)/;
                                      $vhost{$1}=$2;
                                    }
                                    
                                    # ouverture d'un handle de fichier en écriture
                                    # pour chaque fichier (dans /mnt/...)
                                    for(keys %vhost){
                                      s/^\s*//g;
                                      /^(.*?)\..*/;
                                      my $vhostjjmmaa = "$1.$date";
                                      my $handle=$_;
                                      open $handle,">$vhost{$_}${vhostjjmmaa}.log" or die "E/S: $!\n";
                                    }
                                    
                                    # access.log est parcouru une seule fois
                                    while(<F>){
                                    # saute les lignes qui ne correspondent aux nom domaines
                                      next unless /^((.*?)\..*?)\s.*/;
                                      my $FH=$1; # je stocke la chaîne de caractères
                                                 # qui corresponde aux handle ouvert
                                      print $FH $_; # j'écris dans le handle (le fichier /mnt/../vhostjjmmaa.log
                                    }
                                    
                                    # fermeture des handles ouverts
                                    for(keys %vhost){ close $_;}
                                    
                                    # suppression des fichiers vides dans /mnt/..
                                    for(values %vhost){ # pour chaque vhost
                                      opendir(REP,$_);  # handle vers /mnt/..
                                      while(my $fic=readdir REP){ # chaque fichier
                                        next if $fic=~/\.\.?$/;   # sauf . et ..
                                        chomp(my $taille = qx/du -sh "$_$fic"/); # je calcule la taille
                                        unlink "$_$fic" if $taille=~/^0/;        # si zéro je supprime
                                      }
                                      close REP; # fermeture de handle en cours
                                    }
                                    
                                    __END__
                                    
                                    0
                                    Précédent
                                    • 1
                                    • 2
                                    • 3