perl分析ORACLE监听日志(登录情况)

来源:互联网 发布:淘宝客推广爆款的技巧 编辑:程序博客网 时间:2024/06/05 08:45
perl分析ORACLE监听日志(登录情况)

perl分析ORACLE监听日志

QQ:274906097
Longshine-DBA
时间: 2013-06-10

关键字:perl  listener分析,分析ORACLE登录 、分析ORACLE连接

    开发中心长期不使用的数据库,可以将此实例停掉或数据库备份后移出服务器,从而高效的利用主机内存和硬盘空间。
那么几百套数据库,如何高效准确的检查出那些数据库是长期不用的呢?

于是利用shell脚本编写了一个日志分析,将分析的数据生成SQL文件,结果发现shell分析速度不太理想,太慢。
改用perl分析监听日志,速度用极快来形容。

以下监听日志内容格式:
\ anlog.sh inputlog.sh listener.log perllog.pl sqlnet.log temp.sql test.pl
[oracle@Tanxuefeng log]$ pwd
/app/oracle/base/product/10.2.0/db_1/network/log
[oracle@Tanxuefeng log]$ tail -100 listener.log
23-MAY-2013 07:38:01 * service_update * ora * 0
23-MAY-2013 07:48:02 * service_update * ora * 0
23-MAY-2013 08:58:11 * service_update * ora * 0
23-MAY-2013 09:08:12 * service_update * ora * 0
23-MAY-2013 09:12:18 * (CONNECT_DATA=(SERVICE_NAME=ora)(CID=(PROGRAM=D:\oracle\PLSQL?Developer9\PLSQL?Developer\PLSQLDeveloper9.exe)(HOST=XUEFENGT-PC)(USER=xuefengt))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.164.1)(PORT=3776)) * establish * ora * 0
23-MAY-2013 09:12:19 * service_update * ora * 0
23-MAY-2013 09:12:22 * (CONNECT_DATA=(SERVICE_NAME=ora)(CID=(PROGRAM=D:\oracle\PLSQL?Developer9\PLSQL?Developer\PLSQLDeveloper9.exe)(HOST=XUEFENGT-PC)(USER=xuefengt))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.164.1)(PORT=3779)) * establish * ora * 0
23-MAY-2013 09:12:24 * (CONNECT_DATA=(SERVICE_NAME=ora)(CID=(PROGRAM=D:\oracle\PLSQL?Developer9\PLSQL?Developer\PLSQLDeveloper9.exe)(HOST=XUEFENGT-PC)(USER=xuefengt))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.164.1)(PORT=3781)) * establish * ora * 0

监听日志格式大致分四段:
时间 * 客户端连接信息 * 客户IP及端口信息 * 标识 * 实例名 * 0

以下代码将功能 :
1、获取本地主机IP信息
2、分解带标识符的记录行信息,分解出其中的时间,标识、实例名 信息。
3、将分解出的信息拼装成数组
4、在数组仅保留实例最后一次写入的时间点。

PERL源码:
#!/usr/bin/perl
#use strict;  
use Socket; 
use Sys::Hostname; 
my @array_instance=(); 
my $array_instance_ln = \@array_instance;  #数组长度
my @array_print=(); 

#自定义函数get_mon 用于将英文月份简写转为两位数字
sub get_mon {
  my $j;
  my $i;
  my @subarry=("JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"); 
 
  for($i=0;$i<12;$i++) 
   { if ( @subarry[$i] eq $_[0] )  {last;}; } 
    
  $i=$i+1;
  if ($i < 10){ $j="0"."$i";}
  if ($i > 12){ $j="";}
  $j;   # 返回 结果 即函数的输出结果。
}

#以下获取主机名与IP地址,实际读取/etc/hosts文件
my $host = hostname; #获取主机名
print "Host name: ",$host,"\n";
my $name = gethostbyname($host);
my $ip_addr = inet_ntoa($name); #转义为IP
print $ip_addr,"\n";
print "ANLAY listener.log on login DATABASE;\n";

#获取本地时间,并格式分显示出来
my ($sec,$min,$hour,$mday,$mon,$year,$wday, $yday,$isdst)=localtime();
printf "%4d-%02d-%02d %2d:%2d:%2d\n", $year+1900, $mon+1, $mday,$hour,$min,$sec;
print "-------------------------------------\n";
#print "Create SQL file temp.sql ,Begin.......\n";

$year=$year+1900;
$mon =$mon+1;
my $dat= $year.'-'.$mon.'-'.$mday;

#只读打开 监听日志
open(FILE,"D:/log/listener.log") or die "open error: $!";

#覆盖写入方式打开文件
open(SQLFILE,">D:/log/temp".$dat.".txt") or die "open temp.sql error:$!"; 

print SQLFILE "Host name: ",$host,"\n";
print SQLFILE $ip_addr,"\n";
print SQLFILE "ANLAY listener.log on login DATABASE;\n";
printf SQLFILE "%4d-%02d-%02d %2d:%2d:%2d\n", $year+1900, $mon+1, $mday,$hour,$min,$sec;
print SQLFILE "-------------------------------------\n";

while(<FILE>)
{
  chomp; #去掉换行符(/n)
  my $rec=index($_,"establish"); 
  if ($rec > 0){
    #($date_time,$str1,$str2,$str3,$status,$instance,$str4)=split(/\x2A/,$_);
    my ($date_time,$str1,$str2,$status,$instance,$str4)=split(/\s\*\s/,$_); 
   # my $date=substr($date_time,0,11); #截取日期字符串前12位
   # my ($day,$mon,$year)=split(/\-/,$date); #将23-MAY-2013 中年、月、日拆分出来。
   # $mon=get_mon($mon); #调用自定义函数 转化为 数字 月份。
   # $date="$year"."-"."$mon"."-"."$day"; 
  
    #将 获取的信息写入SQL文件 temp.sql中。
  #  print SQLFILE "insert into test.t1(date_time,status,instance_name,host_name,host_ip) values('$date','$status','$instance','$host','$ip_addr');\n";
    
    #使用数组处理
  #  for ( $ii=0; $ii<= $#$array_instance_ln; $ii++) {
  #    if (index( $array_instance[$ii],$instance.' ') >-1
  #      { delete @array_instance[$ii];}   
  #  }
    
    # 将值增加
  #  push @array_instance, $instance.' '.$date.' '.$ip_addr.' '.$host;
    
   my $i=0;
    for ( $ii=0; $ii<= $#$array_instance_ln; $ii++) 
    {
      if (index( $array_instance[$ii],$instance.' ') >-1) { $is=$ii;} 
    }
    
    if ($is>-1)
       {$array_instance[$is]=$instance.' '.$date_time.' '.$ip_addr.' '.$host;}
    else
       {push @array_instance, $instance.' '.$date_time.' '.$ip_addr.' '.$host;}  

  };
}

#打印数组
#for $row (@array_instance) { print "$row\n"; } 
    for ( $ji=0; $ji<= $#$array_instance_ln; $ji++) {
       if (length(@array_instance[$ji])>0) {
          print SQLFILE @array_instance[$ji]."\n" ;
          print SQLFILE @array_instance[$ji]."\n" ;
        };
     }
print SQLFILE ".............................................OK,END!\n";
close(FILE);
close(SQLFILE);
print ".............................................OK,END!\n";

#获取本地时间,分解出秒,分,时,日,月,年
($sec,$min,$hour,$mday,$mon,$year,$wday, $yday,$isdst)=localtime();
printf "%4d-%02d-%02d %2d:%2d:%2d\n", $year+1900, $mon+1, $mday,$hour,$min,$sec;

以上代码执行结果:

从oracle 监听日志中,分解出 客户端 连接实例的详细信息。


以上内容仅供参考,欢迎拍砖。


0 0
原创粉丝点击