I have to write a shell/perl script to scan a log file for last 30 mins worth Data. The requirement is to schedule this script in Cron to run every 30 minutes and look for a error string.
OS: Solaris
Shell:Bash
I have tried below script, but it has become too long and clumsy, do we have other way to make it a bit shorter?
blogs=/opt/docs/datapower/prod/business.log
slogs=/opt/docs/datapower/prod/system.log
starttime=$(date +'%H')
currmin=$(date +'%M')
curdate=`date|cut -d' ' -f5`
echo $(date)
if [ $currmin -le 29 ] && [ $starttime -ne 00 ] ; then
starttime1=`echo "$(date +'%H') - 1" | bc`
logtime="$starttime1"
logtime="$logtime:[3-5][0-9]"
echo $logtime
elif [ $currmin -le 29 ] && [ $starttime -eq 00 ] ; then
logtime="23:[3-5][0-9]"
echo $logtime
else
logtime="$starttime"
logtime="$logtime:[0-2][0-9]"
echo $logtime
fi
if ( grep "$logtime" $slogs | egrep "AAA Authentication Failure|AAA Authorization Failure") > dptest 2>&1;then
Do something
fi
UPDATE: Adding example log statement.
Below is the example of log statement:
Nov 20 06:06:58 business-log-sta [DP-Domain-STAGING][0x80000001][business-log][info] mpgw(GenServiceMPG): trans(31513092)[request]: AAA Authentication failure/>
I think you're doing it a little backwards - building an RE to grep a date out of a log file.
Approaching this in perl I'd be looking to read the whole log file, tokenise it - to extract the time stamp - and then alert based on message content.
Perl has a nice module for the first part -
Time::Piece
. It goes a bit like this:Followup Q:
"Could you please explain what this statement does,
my ( $timestamp, $message ) = (m/\A(\w+\s+\d+\s+\d+:\d+:\d+) (.*)/);
"This does two things:
\A(\w+\s+\d+\s+\d+:\d+:\d+)
- will match from the start of line:\d+:\d+:\d+
will capture a time. (Any 3 colon separated numbers).The other part, of course, captures 'the rest'.
$timestamp
and$message
).Net result is - given the line:
Our regular expression returns the two 'chunks' separately, and then we put them into the two variables.