作者 主題: Perl script 字串取得相關除錯問題  (閱讀 1723 次)

0 會員 與 1 訪客 正在閱讀本文。

baldur

  • 懷疑的國中生
  • **
  • 文章數: 55
    • 檢視個人資料
Perl script 字串取得相關除錯問題
« 於: 2014-08-07 14:07 »
小弟目前在套用網路上某人所寫, 用來分析郵件收送數量並給 cacti 繪製的 perl 程式, 除了 mess_rejected 一直
為 0 沒有加總, 其它均正常有數值及加總.

有試著將 if((($line=~/NOQUEUE/) && ($line=~/reject\=/)) || ($line =~/rejecting/)){
改為
if($line=~/reject/){
kill 及重新執行, 但仍是數值一直為 0  ... ( 用 tail 去看 maillog 可以看到有 NOQUEUE 及 reject )

請問如何除錯呢 ??



#!/usr/bin/perl
$debug=0;       # 1=Debug messages are displayed, 0=No debug messages are displayed
$daemon=1;      # 1=Daemonize the program, 0=Run interactive
$syslog=1;      # 1=Log stuff to syslog, 0=No logging to syslog
$self="/etc/cacti/watchmaillog/watchmaillog.sh";  # Location of this script
$counterfile="/etc/cacti/watchmaillog/watchmaillog_counters";   # Location to store the counter file
$resetfile="/etc/cacti/watchmaillog/watchmaillog_reset";   # Location of the reset counter flag file
$pidfile="/var/run/watchmaillog.pid";   # Location of the running process ID file (used in logrotate)

use Sys::Syslog;
use POSIX;
use Time::HiRes qw( gettimeofday tv_interval );

$|=1;

my $sigset = POSIX::SigSet->new();
my $hupaction = POSIX::SigAction->new('hup_signal_handler',
                                     $sigset,
                                     &POSIX::SA_NODEFER);
my $osigaction = POSIX::SigAction->new('signal_handler',
                                     $sigset,
                                     &POSIX::SA_NODEFER);
POSIX::sigaction(&POSIX::SIGHUP, $hupaction);
POSIX::sigaction(&POSIX::SIGINT, $osigaction);
POSIX::sigaction(&POSIX::SIGTERM, $osigaction);


if($daemon){
        $pid=fork;
   if($pid) {
      open(PID,">".$pidfile) or die "Cannot open PID file: $!.";
         print PID ("$pid\n");   # Write the PID out to the PID file for logrotate
      close(PID);
   }
        exit if $pid;
        die "Couldn't fork : $!" unless defined($pid);
        setsid() or die "Can't start a new session: $!";
   $time_to_die=0;
}

sub signal_handler {
        $time_to_die=1;
}

sub hup_signal_handler {
      if($debug){print "got SIGHUP\n";}
      close(MAILLOG);
      exec($self) or die "Couldn't restart: $!\n";
}

if($syslog){openlog("watchmaillog","pid","daemon");}
if($syslog){syslog("notice","Starting.");}
if($debug){print("watchmaillog is starting.\n");}

# Main part of the program
open(MAILLOG, "tail -n 0 -f /var/log/maillog|") or die "Cannot open maillog: $!.";
my $line="";
while(!$time_to_die){
   $line=<MAILLOG>;
   # Look for received messages where the sender is not from our domain(s)
               if(($line=~/from\=/) && ($line!~/\@domain1.com|\@domain2.com/)){
      $item="mess_recv";
      &readcounterfile;
      $counter{$item}++;
      if($debug){print("Found an inbound message, incrementing the message recieve counter to $counter{$item}.\n");}
      &writecounterfile;
   }
   # Look for messages sent to our domain(s), indicates an inbound message relayed to an internal server
   if(($line=~/=sent/) && ($line=~/\@domain1.com|\@domain2.com/)){
      $item="mess_relay";
      &readcounterfile;
      $counter{$item}++;
      if($debug){print("Found an clean inbound message, incrementing the clean message recieve counter to $counter{$item}.\n");}
      &writecounterfile;
   }
   # Look for sent messages to NOT our email domain(s), indicates an outbound message
   if(($line=~/=sent/) && ($line!~/\@domain1.com|\@domain2.com/)){
      $item="mess_sent";
      &readcounterfile;
      $counter{$item}++;
      if($debug){print("Found an outbound message, incrementing the message sent counter to $counter{$item}.\n");}
      &writecounterfile;
   }
   # Look for rejected messages
   if((($line=~/NOQUEUE/) && ($line=~/reject\=/)) || ($line =~/rejecting/)){
      $item="mess_rejected";
      &readcounterfile;
      $counter{$item}++;
      if($debug){print("Found a rejected message, incrementing the message rejected counter to $counter{$item}.\n");}
      &writecounterfile;
   }
   # Look for MailScanner spam scanning batch results
   if($line=~/Spam\ Checks\:\ Found/){
      $item="spam";
      $spam_count_pos = index($line,"Spam\ Checks\:\ Found");
      $spam_count_pos2 = index($line, "\ spam\ messages");
      $spam_count = substr($line,($spam_count_pos+19),($spam_count_pos2-($spam_count_pos+19)));
      &readcounterfile;
      $counter{$item}=$counter{$item}+$spam_count;
      if($debug){print("Found $spam_count SPAM in the MailScanner batch, incrementing the spam counter to $counter{$item}.\n");}
      &writecounterfile;
   }
   # Look for MainScanner virus scanning batch results
   if($line=~/Virus\ Scanning\:\ Found/){
      $item="virus";
      $virus_count_pos = index($line,"Virus\ Scanning\:\ Found");
      $virus_count_pos2 = index($line, "\ viruses");
      $virus_count = substr($line,($virus_count_pos+22),($virus_count_pos2-($virus_count_pos+22)));
      &readcounterfile;
      $counter{$item}=$counter{$item}+$virus_count;
      if($debug){print("Found $virus_count viruses in the MailScanner batch, incrementing the virus counter to $counter{$item}.\n");}
      &writecounterfile;
   }
   # Look for MailScanner waiting messages
   if($line=~/New\ Batch\:\ Found/){
      $item="mess_waiting";
      $mess_waiting_pos = index($line,"New\ Batch\:\ Found");
      $mess_waiting_pos2 = index($line,"\ messages\ waiting");
      $mess_waiting = substr($line,($mess_waiting_pos+17),($mess_waiting_pos2-($mess_waiting_pos+17)));
      &readcounterfile;
      $counter{$item}=$mess_waiting;
      if($debug){print("Mailscanner found $mess_waiting messages waiting, setting the mess_waiting counter to $counter{$item}.\n");}
      &writecounterfile;
   }
}
close(MAILLOG);
if($debug){print("watchmaillog is ending.\n");}
if($syslog){syslog("notice","Ending.");}
unlink($pidfile);

# Subroutine to read the contents of the counter file
sub readcounterfile {
   # Read the counter values from the file
   if($debug){print("Reading contents of counter file.\n");}
   open(COUNTER,$counterfile);
   while($line=<COUNTER>){
      @line=split(/\:/,$line);
      chop($line[1]); # Drop the trailing LF off the value
      # Check for reset counter flag file
      if(-e $resetfile."_".$line[0]){
         if($debug){print("Reset counter flag file found for counter $line[0], resetting counter value to 0.\n");}
         $counter{$line[0]}=0;
         unlink($resetfile."_".$line[0]);
      } else {
         $counter{$line[0]}=$line[1];
      }
      if($debug){print("Counter $line[0] = $counter{$line[0]}.\n");}
   }
   close(COUNTER);
}

# Subrouting to write the contents of the counter file
sub writecounterfile {
   if($debug){print("Writing counter values to counter file.\n");}
   open(COUNTER,">".$counterfile);
   # Write each counter item out to the counter file
   foreach $item (sort keys(%counter)) {
      print COUNTER ($item."\:".$counter{$item}."\n");
   }
   close(COUNTER);
   chmod(0666,$counterfile);
}
« 上次編輯: 2014-08-07 14:19 由 baldur »

Yamaka

  • 俺是博士!
  • *****
  • 文章數: 4913
    • 檢視個人資料
    • http://www.ecmagic.com
Re: Perl script 字串取得相關除錯問題
« 回覆 #1 於: 2014-08-07 14:41 »
小弟目前在套用網路上某人所寫, 用來分析郵件收送數量並給 cacti 繪製的 perl 程式, 除了 mess_rejected 一直
為 0 沒有加總, 其它均正常有數值及加總.

有試著將 if((($line=~/NOQUEUE/) && ($line=~/reject\=/)) || ($line =~/rejecting/)){
改為
if($line=~/reject/){
kill 及重新執行, 但仍是數值一直為 0  ... ( 用 tail 去看 maillog 可以看到有 NOQUEUE 及 reject )

請問如何除錯呢 ??

另外寫個只有這個條件過濾或是直接命令列用這個條件過濾看看有沒有東西出來?

baldur

  • 懷疑的國中生
  • **
  • 文章數: 55
    • 檢視個人資料
Re: Perl script 字串取得相關除錯問題
« 回覆 #2 於: 2014-08-07 16:59 »
改寫成讀 test_reject 及寫 counters,
只有第一次 echo reject >> ./test_reject
有 print 到畫面  "Found a rejected message, incrementing the message rejected counter to 1."
之後就沒有了...
counters 檔案 mess_rejected:1 一直沒變.
* echo reject >> ./test_reject 送了八次.


#!/usr/bin/perl

use Sys::Syslog;
use POSIX;
use Time::HiRes qw( gettimeofday tv_interval );

$counterfile="/etc/cacti/watchmaillog/counters";

$|=1;

open(MAILLOG, "tail -n 0 -f /etc/cacti/watchmaillog/test_reject|") or die "Cannot open maillog: $!.";
my $line="";

while(!$time_to_die){
   $line=<MAILLOG>;
   if($line=~/reject/){
      $item="mess_rejected";
      &readcounterfile;
      $counter{$item}++;
      print("Found a rejected message, incrementing the message rejected counter to $counter{$item}.\n");
      &writecounterfile;

   }

close(MAILLOG);
}

# Subroutine to read the contents of the counter file
sub readcounterfile {
   # Read the counter values from the file
   if($debug){print("Reading contents of counter file.\n");}
   open(COUNTER,$counterfile);
   while($line=<COUNTER>){
      @line=split(/\:/,$line);
      chop($line[1]); # Drop the trailing LF off the value
      # Check for reset counter flag file
      if(-e $resetfile."_".$line[0]){
         if($debug){print("Reset counter flag file found for counter $line[0], resetting counter value to 0.\n");}
         $counter{$line[0]}=0;
         unlink($resetfile."_".$line[0]);
      } else {
         $counter{$line[0]}=$line[1];
      }
      if($debug){print("Counter $line[0] = $counter{$line[0]}.\n");}
   }
   close(COUNTER);
}

# Subrouting to write the contents of the counter file
sub writecounterfile {
   if($debug){print("Writing counter values to counter file.\n");}
   open(COUNTER,">".$counterfile);
   # Write each counter item out to the counter file
   foreach $item (sort keys(%counter)) {
      print COUNTER ($item."\:".$counter{$item}."\n");
   }
   close(COUNTER);
   chmod(0666,$counterfile);
}

« 上次編輯: 2014-08-07 17:04 由 baldur »

baldur

  • 懷疑的國中生
  • **
  • 文章數: 55
    • 檢視個人資料
Re: Perl script 字串取得相關除錯問題
« 回覆 #3 於: 2014-08-07 17:12 »
1. 另外我改成 open(MAILLOG, "tail -n 0 -f /var/log/maillog|") or die "Cannot open maillog: $!.";
2. 由另一個 tty 執行 tail -n 0 -f /var/log/maillog| grep reject

1. 這程式就完成沒有 print
2. 這個會顯示出 reject 的內容...

目前沒有除錯的頭緒呢 ... 請求協助呢 =_=

 

hongbin

  • 憂鬱的高中生
  • ***
  • 文章數: 101
    • 檢視個人資料
Re: Perl script 字串取得相關除錯問題
« 回覆 #4 於: 2014-08-07 23:06 »
while(!$time_to_die){
   $line=<MAILLOG>;
   if($line=~/reject/){
      $item="mess_rejected";
      &readcounterfile;
      $counter{$item}++;
      print("Found a rejected message, incrementing the message rejected counter to $counter{$item}.\n");
      &writecounterfile;
   }
close(MAILLOG);
}

要將 MAILLOG close,應該是要等到 while 迴圈跑完吧,要不然只會秀出第1筆的資料而已啊


while(!$time_to_die){
   $line=<MAILLOG>;
   if($line=~/reject/){
      $item="mess_rejected";
      &readcounterfile;
      $counter{$item}++;
      print("Found a rejected message, incrementing the message rejected counter to $counter{$item}.\n");
      &writecounterfile;
   }
}
close( MAILLOG);



baldur

  • 懷疑的國中生
  • **
  • 文章數: 55
    • 檢視個人資料
Re: Perl script 字串取得相關除錯問題
« 回覆 #5 於: 2014-08-08 09:45 »
w.sh
是的 while 框錯位置了, 改正後只要 test_reject 或 maillog 內有 reject 就會一直計數.

watchmaillog.sh
看了一下原始的程式, 了解就是判讀順序的問題.. 原始作者的 reject 跟我要的不同, 目前是把 reject 為第一順位再來判讀接收...

以上供各位參考.



while(!$time_to_die){
   $line=<MAILLOG>;
   if($line=~/reject/){
      $item="mess_rejected";
      &readcounterfile;
      $counter{$item}++;
      print("Found a rejected message, incrementing the message rejected counter to $counter{$item}.\n");
      &writecounterfile;
   }
close(MAILLOG);
}

要將 MAILLOG close,應該是要等到 while 迴圈跑完吧,要不然只會秀出第1筆的資料而已啊


while(!$time_to_die){
   $line=<MAILLOG>;
   if($line=~/reject/){
      $item="mess_rejected";
      &readcounterfile;
      $counter{$item}++;
      print("Found a rejected message, incrementing the message rejected counter to $counter{$item}.\n");
      &writecounterfile;
   }
}
close( MAILLOG);



« 上次編輯: 2014-08-08 10:38 由 baldur »