#!/usr/local/bin/perl # # $Header: emdb/sysman/admin/scripts/alertlogAdr_util.pl /st_emdbsa_11.2/1 2009/03/12 10:39:00 fagonzal Exp $ # # alertlogAdr_util.pl # # Copyright (c) 2006, 2009, Oracle and/or its affiliates.All rights reserved. # # NAME # alertlogAdr_util.pl - ADR alert log monitoring utilities # # DESCRIPTION # Utilities for reading the ADR alert log # # NOTES # # # MODIFIED (MM/DD/YY) # fagonzal 02/18/09 - Parsing number of ASM checker failures # keiwong 04/03/07 - fix bug 5898320 # keiwong 02/19/07 - add adrAlertLogDataFailure metric # keiwong 09/07/06 - Fixed ADR_HOME path # keiwong 07/19/06 - Creation # require "emd_common.pl"; use strict; use File::Spec; use Time::Local; use Time::localtime; use vars qw($STACK_BEGIN_PATTERN $STACK_TIME_PATTERN $STACK_DETAIL_PATH_PATTERN $STACK_TRACE_FILE_PATTERN); use vars qw($STACK_PROB_KEY_PATTERN $STACK_TXT_BEGIN_PATTERN $STACK_TXT_END_PATTERN $TIMESTAMP_PATTERN); use vars qw($STACK_ATTR_BEGIN_PATTERN $STACK_ATTR_NAME_PATTERN $STACK_ATTR_VALUE_PATTERN $STACK_ERRID_PATTERN $STACK_NUMBER_OF_FAILURES_PATTERN); $STACK_BEGIN_PATTERN = q//; $STACK_TXT_END_PATTERN = q##; $STACK_ATTR_BEGIN_PATTERN = q/catdir($adr_home, 'alert'); EMD_PERL_DEBUG("get_adr_alert_dir: alert_dir=$alert_dir"); return $alert_dir; } # # subroutine get_adr_alert_logs # Return the alert log files in alert directory of ADR, sorted by suffix # # $_[0] - value of ADR home # $_[1] - exclude (1) or include (0, default) directory path # sub get_adr_alert_logs { my ($adr_home, $exclude_path) = @_; my @log_files = (); if (!$adr_home) { return @log_files; } my $alert_dir = get_adr_alert_dir($adr_home); if (!$alert_dir) { return @log_files; } chdir $alert_dir || return; opendir ALERT_DIR, "." || return; @log_files = grep -f && /^log\.xml(|\.\d+)$/, readdir ALERT_DIR; closedir ALERT_DIR; if (!$exclude_path) { @log_files = map { File::Spec->catfile($alert_dir, $_) } @log_files; } # sort files by suffix @log_files = sort { (my $x = $a) =~ s/[^\d]*(|\.(\d+))$/\2/; (my $y = $b) =~ s/[^\d]*(|\.(\d+))$/\2/; $x <=> $y; } @log_files; EMD_PERL_DEBUG("get_adr_alert_files: log_files=" . join ',', @log_files); return @log_files; } # # subroutine get_first_timestamp # Return the timestamp of the first record in the log file # # $_[0] - log file # sub get_first_timestamp { my ($logFile) = @_; my $timestamp; if (!open(LOG, "< $logFile")) { EMD_PERL_WARN("Cannnot open log file $logFile: $!"); return $timestamp; } my $stackFound = 0; while () { if (/$STACK_BEGIN_PATTERN/) { if ($stackFound) { # second stack found, end search last; } $stackFound = 1; } if ($stackFound && /$STACK_TIME_PATTERN/) { $timestamp = $1; last; } } close LOG; EMD_PERL_DEBUG("get_first_timestamp: timestamp=$timestamp logFile=$logFile"); return $timestamp; } # # subroutine get_timestamp_number # Return a timestamp number for comparison # # note: timezone is ignored # # $_[0] - timestamp # sub get_timestamp_number { my ($timestamp) = @_; my $timestampNumber = 0; if ($timestamp) { $timestamp =~ s/-\d+:\d+$//; ($timestampNumber = $timestamp) =~ s#[^\d]##g; } EMD_PERL_DEBUG("get_first_timestamp: timestamp=$timestamp"); return $timestampNumber; } # # subroutine get_current_alert_logs # Return files after a certain timestamp, sorted by first timestamp # # note: current log files are defined as files with timestamp in the first # error stack equal to or greater than the timestamp in consideration # # $_[0] - ADR home # $_[1] - timestamp # sub get_current_alert_logs { my ($adrHome, $timestamp) = @_; my @currentLogs = (); my %timestampNumbers = (); my @logs = get_adr_alert_logs($adrHome); if (@logs > 0 && $timestamp) { my $timestampNumber = get_timestamp_number($timestamp); foreach my $log (@logs) { my $firstTimestamp = get_first_timestamp($log); if ($firstTimestamp) { my $firstTimestampNumber = get_timestamp_number($firstTimestamp); if ($timestampNumber <= $firstTimestampNumber) { push @currentLogs, $log; $timestampNumbers{$log} = $firstTimestampNumber; } } } } # sort files by first timestamp @currentLogs = sort { $timestampNumbers{$a} <=> $timestampNumbers{$b}; } @currentLogs; EMD_PERL_DEBUG("get_current_alert_files: currentLogs=" . join ',', @currentLogs); return @currentLogs; } # # subroutine get_detail_path # Return value of the detail_path attribute in a log record # # $_[0] - log record # sub get_detail_path { my ($logRecord) = @_; my $detail_path; if ($logRecord =~ /$STACK_DETAIL_PATH_PATTERN/) { $detail_path = $1; } EMD_PERL_DEBUG("get_detail_path: detail_path=$detail_path"); return $detail_path; } # # subroutine get_trace_file # Return the trace file in a log record # # $_[0] - log record # $_[1] - ADR home # sub get_trace_file { my ($logRecord, $adrHome) = @_; my $trace_file = get_detail_path($logRecord); if ($trace_file =~ /$STACK_TRACE_FILE_PATTERN/) { $trace_file =~ s/\?/$adrHome/; } EMD_PERL_DEBUG("get_trace_file: trace_file=$trace_file"); return $trace_file; } # # subroutine get_prob_key # Return value of the prob_key attribute in a log record # # $_[0] - log record # sub get_prob_key { my ($logRecord) = @_; my $prob_key; if ($logRecord =~ /$STACK_PROB_KEY_PATTERN/) { $prob_key = $1; } EMD_PERL_DEBUG("get_prob_key: prob_key=$prob_key"); return $prob_key; } # # subroutine get_errid # Return value of the errid attribute in a log record # # $_[0] - log record # sub get_errid { my ($logRecord) = @_; my $errid; if ($logRecord =~ /$STACK_ERRID_PATTERN/) { $errid = $1; } EMD_PERL_DEBUG("get_errid: errid=$errid"); return $errid; } # # subroutine get_number_of_failures # Return value of the number of failures in the message text # # $_[0] - message text # sub get_number_of_failures { my ($messageText) = @_; my $numberOfFailures; if ($messageText =~ /$STACK_NUMBER_OF_FAILURES_PATTERN/) { $numberOfFailures = $1; } EMD_PERL_DEBUG("get_number_of_failures: numberOfFailures=$numberOfFailures"); return $numberOfFailures; } # # subroutine uncdata # Return value without CDATA # # $_[0] - text # sub uncdata { my ($text) = @_; $text =~ s# * *##; EMD_PERL_DEBUG("uncdata: text=$text"); return $text; } # # subroutine to_ctime # Convert timestamp from ISO 8061 format to ctime # # $_[0] - timestamp # sub to_ctime { my ($timestamp) = @_; my $convertedTime; if ($timestamp =~ /$TIMESTAMP_PATTERN/) { $convertedTime = ctime(timelocal($6, $5, $4, $3, $2 - 1, $1)); } EMD_PERL_DEBUG("to_ctime: convertedTime=$convertedTime"); return $convertedTime; } 1;