1. 程式人生 > 其它 >linux中監控oracle alert 檔案中的ORA-xxx報錯資訊併發郵件perl指令碼

linux中監控oracle alert 檔案中的ORA-xxx報錯資訊併發郵件perl指令碼

監控alert 檔案中的 ORA-xxx 錯誤資訊。

alertlog.pl指令碼程式碼如下:

!/usr/bin/perl

Name: alertlog.pl

sub countSet{
open(OUT, ">$idFile");
printf(OUT "%d", $currCount); # 把當前行號寫入檔案
close(OUT);
}

--------------------------

Define Variables

--------------------------

$obase="/u01/app/oracle";
$SH_TOP="/home/oracle/general/sh";
$SID="$ARGV[0]";
$idFile="$SH_TOP/log/alert_${SID}.id"; # 只記錄 當次檔案已檢查過的開始行號和結束行號

if (! -f $idFile){ # 若檔案不存在
open (OUT, ">$idFile") ; # 則 建立 並 以寫入方式開啟檔案
printf (OUT "%s\n",1) ; # 寫入 1
close(OUT);
}

$alertFile="${obase}/admin/${SID}/bdump/alert_${SID}.log";
$errFile="$SH _TOP/err${SID}.txt";

$cmd="head -1 $idFile";
$preCount=qx/$cmd/;
chomp($preCount); # 去除字串變數值結尾的換行符
$cmd="wc -l $alertFile | awk '{print $1}'";
$currCount=qx/$cmd/;
printf ("$preCount:$currCount\n");

--Modified tail +preCount with tail -minusCount for Linux Compliance

$minusCount=$currCount-$preCount;
$cmd="tail -$minusCount $alertFile | grep "ORA-" | /bin/egrep -v -f $SH_TOP/errLogAlert.dat | sort -u> $errFile";
printf ("$cmd \n") ;

system($cmd);
Ssize=-s $errFile;
if ($size >1){
printf ("Sending Alert for $SID \n");
$cmd="$SH_TOP/alert_notification_db.ksh -s "Alert Log Error" -d $SID -h 'hostname' -f $errFile";

printf("$cmd \n");
system($cmd);
}

&countSet; # 執行 counterSet 把 $currCount寫入檔案$idFile

------------------------------

為執行上述監控指令碼,我們需要先在SORACLE_BASE/admin/$ORACLE_SID 目錄下bdump目錄,如/u01/app/oracle/admin/+ASM/bdump。
另外,我們還需要在bdump目建指向跟蹤目錄中alert_+ASM[i].log的符號連結。例子如下:

exaddb01:/u01/app/oracle/admin/+ASM/bdump
+ASM1 -oracle:1s -1tr
total 0
Irwxrwxrwx 1 oracle dba 57 Nov 13 2011 alert_+ASM.1og-→
/001/app/oracle/diag/asm/+asm/+ASM1/trace/alert_+ASM1.1og

在上面的例子中,被建立的符號連結為alert_+ASM.log(沒有使用ASM例項名稱),其指向 alert_+ASM1.log檔案。
這裡我們是故意如此,因為這樣做的話,就可以在每一個數據庫伺服器上配置同樣的cron任務,而不需要考慮該伺服器是獨立模式的還是RAC中的一個節點。
cron任務看起來如下所示:
--Monitor Alert Logs
0,10,20,30,40,50 * * * * /home/oracle/general/sh/alertlog.p1 +ASM >/tmp/alertlog_+ASM.log 2>&1

上述指令碼 alertlog.pl中的SH_TOP定義了從何處執行該指令碼。在SH_TOP目錄下,告警日誌最後一行的行號被記錄在日誌子目錄中。
該日誌子目錄應該作為告警日誌檔案監控配置的一部分而被建立:
exaddb01:/home/oracle/general/sh/log
TOOLSDEV1 - oracle:cat alert_+ASM.id
191126
如果基於某些理由,你想從告警日誌的開頭進行挖掘,則可以簡單地將alert_+ASM.id檔案的內容修改為0即可。
上述Perl指令碼中的 alert_notific ati on_db.ksh行 也可以被mail或者 mailx代替。
在我們的例子中,告警日誌檔案中每一個被檢測到的ORA-訊息都將被上傳到一張Oracle表中,以備日後做進一步的分析。

與資料庫告警日誌一樣,ASM的告警日誌也需要進行清理和歸檔:
exaddb01:/home/oracle/general/sh
+ASM1 - oracle: cat rotate_asm.ksh
export CONF=/tmp/asml.conf
cat <<!!>$CONF
/u01/app/oracle/diag/asm/+asm/+ASM1/trace/alert_+ASM1.log
weekly
copytruncate
rotate 4
compress
}
!!
1ogrotate -s $SH/1og_rotate_asml -f $CONF-s SSH/log_rotate_listener_scanl -f $CONF

上述命令中的-s選項能夠讓logrotate實用工具(linux下的日誌管理工具)指定其他狀態檔案。
為了讓Oracle或者 grid 使用者能夠執行logrotate命令,必須要指定-s選項。因為預設的狀態檔案為/var/lib/logrotate.status。
一般來講,只有root使用者有許可權對該檔案進行寫操作。-f選項則強制對日誌檔案進行輪調,即便logrotate工具認為這種輪調是不需要的。
最後一個選項指定了日誌輪調的配置檔案。在該配置檔案中,我們可以設定如下內容:
·要輪調的日誌檔案的位置以及輪調的選項
·輪調的頻率
·要保留的檔案數量
·是否使用壓縮
當我們第一次執行了日誌輪調指令碼之後,我們就可以看到舊的告警日誌已經被壓縮了,而新生成的日誌檔案大小為0位元組:
exaddb01:/u01/app/oracle/diag/asm/+asm/+ASM1/trace
+ASM1 - oracle: 1s -1 alert_+ASM*
-rw-r-----1 oracle dba 0 Dec 11 14:55 alert +ASM1.log
-rw-r-----1 oracle dba 643647 Dec 11 14:55 alert_+ASM1.log.1.gz

附:
####################################################################################

每15秒執行一次

* * * * * sleep 15;/home/oracle/general/sh/alertlog.p1 +ASM >/tmp/alertlog_+ASM.log 2>&1

####################################################################################