IT-Expert
  IT-Expert / Веблог / Простой демон-коллектор на Perl, адаптирован к запуску из rc.d
Авторизация
Логин:
Пароль:


 
Поиск по записям:

Ключевые слова:
Записей в блоге
 за 2023 год
 за 2022 год
 за 2021 год
 за 2015 год
 за 2014 год
 за 2013 год
 за 2012 год
 за 2011 год

     за 2010 год

       за 2009 год
       за 2008 год
       за 2007 год
       за 2006 год
       за 2005 год
      RSS лента Лента новостей IT-Expert 

      Простой демон-коллектор на Perl, адаптирован к запуску из rc.d

      16:01, 16 января 2006 ( Administration FreeBSD  )

      Перл мне понравился Cool

      Как только вышел из под пальцев первый тестовый скрипт, тут же меня потянуло на написание разнообразных скриптов запуска, перезапуска, снятия статистик, коллекторов и прочего.

      Нижеследующий скрипт является плодом перекапывания документации, двухдневного кодирования и содержит приемы работы с сигналами, работу с базой MySQL и распарсиванием строк лога squid, демонизированием скрипта (fork). И есессено, скрипт далек от идеала. Является легкой переработкой squid2mysql-1.0.0.

      По сути это демон-коллектор из логов squid в базу.

      Настройка по шагам:

      создаем "трубу"
      mkfifo /dev/squid 

      прописываем в squid.conf:
      cache_access_log /dev/squid # это будет выталкивать в трубу строки лога

      Ну и в самом скрипте мы будем просто читать из /dev/squid :)

      Да-да, изредка сквид падает, рекомендуемый костыль - проверка в крон на наличие сквид-процесса, и , в случае необходимости, запуск. Что мы и оставим читателю в качестве упражнения.


      #!/usr/bin/perl
      use DBI;
      use DBI::DBD;

      $db_name="squidlog";
      $db_user="nexus";
      $db_host="balu.it.group";
      $db_passwd="xxxxxx";

      $output_squid_log="/home/logs/mysquid.log";

      $output_log="/home/logs/squid2db.log";

      $pid_file="/home/logs/squid2db.pid";

      $dieFlag=1;
      $reconnectFlag=0;

      $start_args=$ARGV[0];

      if($start_args eq "stop"){
          if(-e $pid_file){
              open (FP, $pid_file);
       $child_pid=<FP>;
              kill KILL => $child_pid;
       close FP;
       unlink $pid_file;
       die "Child process $child_pid was killed";
          } else { die "Not running ...\n"};
      };

      if($start_args eq "restart"){
           if(-e $pid_file){
               open (FP, $pid_file);
               $child_pid=<FP>;
               kill HUP => $child_pid;
               close FP;
               die "Child process $child_pid was restarted";
          } else { print "Not running ... started\n" };
      };

      if($start_args eq "" || $start_args eq "start"){
      # check if running
           if(-e $pid_file){
               open (FP, $pid_file);
               $child_pid=<FP>;
               close FP;
        if($child_pid>0){die "Child process $child_pid already running"};
       
          };
      };

      $dbh = DBI->connect("DBI:mysql:database=$db_name;host=$db_host;",$db_user,$db_passwd,{AutoCommit=>1,RaiseError=>0,PrintError=>1});
      $dbh->{mysql_auto_reconnect}=1;

      appendfile($output_log, "mysql connection ...\n");

      $SIG{'HUP'} = $SIG{'ALRM'} = 'HUPHandler';
      $SIG{'KILL'} = 'KILLHandler';

      open (FILEHANDLE, "/dev/squid");

      &Daemonize;

      while($dieFlag){
          if($reconnectFlag){
       &Reconnect();
      # clear reconnect flag 
       $reconnectFlag=0;
          };

        $data = readline(FILEHANDLE);
        chop($data);
       
      #  print OUTLOG $data;
       
        @lines=split(' ',$data);

      $sth=$dbh->prepare("INSERT INTO logger(date,time,elapsed,bill,code,\
      status,bytes,url,userident,host,urn)\
       VALUES(?,?,?,?,?,?,?,?,?,?,?)");
      #     timestamp
          $lines[0]=~tr/./ /;
          @_timestamp=split(' ',$lines[0]);
          $cts=$_timestamp[0];

      #   date=
          ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($cts);
          $year=$year+1900;
          $mon=$mon+1;
          $hour=$hour+3;
          if ($hour>24) {
       $hour=$hour-24;
       $mday=$mday+1;
          }
          $cdate="$year-$mon-$mday";

      #   time=
          $ctime="$hour:$min:$sec";

      #   elapsed=   
          $duration=$lines[1];
      #   host=
          $remotehost=$lines[2];
         
          @codestatus=split('/',$lines[3]);
          if ($codestatus[0] eq "TCP_HIT") { $_code=0; }
          if ($codestatus[0] eq "TCP_MISS") { $_code=1; }
          if ($codestatus[0] eq "TCP_REFRESH_HIT") { $_code=2; }
          if ($codestatus[0] eq "TCP_REF_FAIL_HIT") { $_code=3; }
          if ($codestatus[0] eq "TCP_REFRESH_MISS") { $_code=4; }
          if ($codestatus[0] eq "TCP_CLIENT_REFRESH_MISS") { $_code=5; }
          if ($codestatus[0] eq "TCP_IMS_HIT") { $_code=6; }
          if ($codestatus[0] eq "TCP_SWAPFILE_MISS") { $_code=7; }
          if ($codestatus[0] eq "TCP_NEGATIVE_HIT") { $_code=8; }
          if ($codestatus[0] eq "TCP_MEM_HIT") { $_code=9; }
          if ($codestatus[0] eq "TCP_DENIED") { $_code=10; }
          if ($codestatus[0] eq "TCP_OFFLINE_HIT") { $_code=11; }
          if ($codestatus[0] eq "UDP_HIT") { $_code=12; }
          if ($codestatus[0] eq "UDP_MISS") { $_code=13; }
          if ($codestatus[0] eq "UDP_DENIED") { $_code=14; }
          if ($codestatus[0] eq "UDP_INVALID") { $_code=15; }
          if ($codestatus[0] eq "UDP_MISS_NOFETCH") { $_code=16; }
          if ($codestatus[0] eq "NONE") { $_code=17; }
      #   status=
          $_status=$codestatus[1];
      #   bytes=   
          $objectsize=$lines[4];
      #   bill=   
          $bill=(($duration/60000)*($valueperhour/60))+(($objectsize/1048576)*$valuepermeg);
      #   method=
          $fetchmethod=$lines[5];
      #      
          $URLlink=$lines[6];
      ### for index
          $URLlink =~ m/:\/\/(.+?)\//;
          $urn = $1;
      #    $urn=$URLlink;
         
          $username=$lines[7];
         
          @peerstatus_host=split('/',$lines[8]);
          $peerstatus=$peerstatus_host[0];
          $peerhost=$peerstatus_host[1];
         
          $objecttype=$lines[9];
         
      ############################################################
      ##
      ##  transfer data to mysql table
      ##
      ############################################################

      ##if (($_code ne "10")&&($username ne "-")&&($_status ne "404")&&($_status ne "400")) {
      if (($_code ne "10")&&($_status ne "404")&&($_status ne "400")) {

          $sth->execute($cdate,
          $ctime,
          $duration,
          $bill,
          $_code,
          $_status,
          $objectsize,
          $URLlink,
          $username,
          $remotehost,
          $urn) || &Reconnect;

          $aff="SELECT * FROM rdnload WHERE userident='$username' AND date='$cdate'";
          $rows_affected=$dbh->do($aff);
          if ($rows_affected < 1) {
       $stn=$dbh->prepare("INSERT INTO rdnload(userident,date,download) VALUES (?,?,?)");
       $stn->execute($username,$cdate,$objectsize);
          }
          $aff="UPDATE rdnload SET download=download+$objectsize WHERE userident='$username' AND date='$cdate'";
          $rows_affected=$dbh->do($aff);
      }

      };

      $dbh->disconnect;
      close FILEHANDLE;

      exit;

      sub Daemonize {
          print "Daemonizing phone2db ...";
         open(STDIN,"</dev/null");
         open(STDOUT,">/dev/null");
         open(STDERR, '>&STDOUT');

          defined(my $pid = fork)   or die "Can't fork: $!";
          exit if $pid;
          setsid                    or die "Can't start a new session: $!";
          umask 0;
          open(FP,">$pid_file");
          print FP $$;
          close FP;
          print " [ OK ]\n";
      }

      sub Reconnect {
       $dbh->disconnect;
       sleep 5;
       $dbh = DBI->connect("DBI:mysql:database=$db_name;host=$db_host;",$db_user,$db_passwd,{AutoCommit=>1,RaiseError=>0,PrintError=>1});
       appendfile($output_log,"\nreconnect occured\n");
      }
      sub HUPHandler {
      # &Reconnect;
       $reconnectFlag=1;
       appendfile($output_log, "HUP signal handled\n");
      }

      sub KILLHandler {
          appendfile($output_log, "KILL signal handled");
      ## Kill process   
          $dieFlag=0;
      }

      sub appendfile {
          my ($fp, $msg) = @_;
         
          if (open(FILE, ">>$fp")) {
              print FILE ("$msg\n");
              close FILE;
          }
      }    

      sub usage{
          print "Usage: start|stop|restart\n";
      }

      # 0 timestamp.millisec
      # 1 duration
      # 2 remotehost
      # 3 code/status
      # 4 bytes
      # 5 method
      # 6 URL
      # 7 username
      # 8 peerstatus/peerhost
      # 9 type


      Оставить комментарий
      © Максим Прокопов 2005-2024 О сервере