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
####################################################################################