2012年5月3日木曜日

perlでsqlplusを実行する

リアルタイムでOracleの動的パフォーマンスビューの状況を確認したい場合がありますよね?

自分は結構あります。その時に書く捨てスクリプトがこんな感じです。
1分くらいで書けるのでよく使っています。

下記のスクリプトは1秒毎に日時と一緒にv$sessionの件数を出力するものです。
適宜変更して使ってみてください。

use warnings;
use strict;
use utf8;
use Fatal qw(open close);

$ENV{LANG}="C";
open my $sqlplus , "| sqlplus -s scott/tiger";
for (1..1000){
    print `date`;
    print $sqlplus q{ select count(*) from v$session; },"\n";
    sleep 1;
}
print $sqlplus "exit;","\n";
close $sqlplus;

2012年4月30日月曜日

Oracle アラートログをgrepしたいよね

アラートログをgrepしたいときってありますよね?
でも問題があります。
ログ行に必ず、タイムスタンプがついていませんよね。
ガーン。。。
※みんな同意してくれると思っています。
で、結局目で追っていかないといけなくなるわけです。。。
それも面倒なのでperlでちょっとしたプログラムをこしらえてみました。
あんまり、テストしていませんが置いておきますので何かの参考になれば
#!/usr/bin/perl
use warnings;
use strict;
use utf8;
use Carp;
use Fatal qw/ open close/ ;
use Time::Piece;

&_usage() if (scalar @ARGV == 0 or scalar @ARGV != 2);

my $alert_log_file = validate_target_file( shift );
my $search_string = shift || "";

my $dates=q{};

open my $af, "<" , $alert_log_file;

my $current_date = q{};
my @events;

while (my $line = <$af>){
    chomp $line;

    if (is_date($line)){

        next if $current_date eq $line;

        $current_date = $line;
        my @current_events = @events;
        @events=();
        $dates->{_translate_date($current_date)} = \@current_events;
    }
    else {
        next if $line !~ /$search_string/;
        push @events, $line;
    }
}

close $af;

for my $date (sort keys %$dates){

    next if ( (scalar @{$dates->{$date}}) == 0 );
    print $date,"\n";
    for my $event ( @{$dates->{$date}} ){
        print "\t";
        print $event, "\n";
    }
}

sub _usage {
    print << 'EOF'
Usage :     grep_ora_alertlog [ALERT_LOGFILE] [PATTERN (Perl Regular Expressions)]
EOF ;
exit;
} 

sub validate_target_file {
    $alert_log_file = shift;
    die "target file is not exist:$alert_log_file" if not -f $alert_log_file ;
    die "target file is not standard file:$alert_log_file" if not -f $alert_log_file ;
    return $alert_log_file;
} 

sub is_date {
    my $date_string = shift;
    my $t;
    eval { $t = Time::Piece->strptime($date_string, q{%a %b %d %H:%M:%S %Y}); };

    if (not $@){
        return 1;
    }
    else{
        return 0;
    }
}

sub _translate_date {
    my $date_string = shift;
    my $t;
    eval { $t = Time::Piece->strptime($date_string, q{%a %b %d %H:%M:%S %Y}); };
    return $t->strftime('%Y-%m-%d %H:%M:%S');
}
実行するとこんな感じ
[xxxxx@lenovo bin]$ grep_alertlog /u01/app/oracle/112/diag/rdbms/ora112/ora112/trace/alert_ora112.log memory
2011-08-26 20:53:19
 Shared memory segment for instance monitoring created
   memory_target            = 468M
2011-08-26 20:55:24
   memory_target            = 468M
2011-08-26 20:59:00
   memory_target            = 468M
2011-10-24 03:47:32
   memory_target            = 512M
2011-10-24 05:45:43
   memory_target            = 512M
2011-10-24 07:13:40
   memory_target            = 512M
2012-01-14 12:23:32
   memory_target            = 512M
2012-01-15 13:25:15
   memory_target            = 512M
2012-01-21 21:08:15
   memory_target            = 512M
2012-01-28 13:05:24
   memory_target            = 512M
2012-03-03 11:28:07
   memory_target            = 512M
2012-03-03 11:28:57
   memory_target            = 512M
2012-03-03 11:30:36
   memory_target            = 512M
2012-03-03 11:36:35
   memory_target            = 512M
2012-03-03 11:38:55
   memory_target            = 512M
2012-03-30 23:56:00
   memory_target            = 512M
2012-04-07 19:17:50
   memory_target            = 512M
2012-04-29 21:55:36
   memory_target            = 512M
2012-04-29 22:57:15
   memory_target            = 512M
Time::Pieceを使っているので、perl -v が 5.9.5以降ですかね?
[xxxx@lenovo bin]$ corelist Time::Piece

Time::Piece was first released with perl v5.9.5
よく考えたら grep って PATTERN FILE だった。。