A more efficient way would be to tail and follow the log with "tail -f", store the last 50 lines and email those lines when the failure word occurs. This can be done in either shell, awk or perl easily. An untested gawk version:
tail -f log-file |gawk '
BEGIN { email_cmd = "mail -s failure emails_addrs" }
{
line[NR%50] = $0
}
/failure word/ {
for (i = NR-49; i <= NR; i++)
print line[i%50] | email_cmd
close(email_cmd)
}'
I was going to suggest binlib's solution, above, although the standard "tail -f" command might not work after a log rotation. The tail from GNU's coreutils will follow the file opened, not the name of the file, unless you do:
tail --follow=filename
But given that you want the most recent occurrence of a pattern before a second pattern occurs, try this (again, gawk or nawk or mawk):
Thanks for ur suggestions.Sorry for late reply
I followed otheus suggestion and put the code, but it going to infinite loop and not getting any output. I am new to UNIX, so i may be wrong in some pattern.
Code i am using
I have questions on this, as i mentioned if i get error at 2:30 PM, my script will execute and send a report to users.It should also save a text file with that 50 lines for reference.
Then if it runs again on 2:45 it will again send the same error message and it will continue to send the error until log was corrected.
tail -f EssbaseLog.txt
will run forever and will present lines as they are added to the file. Thus your script will run forever too. You run your script once and let it find errors as they occur.
You didn't use --follow=log-file but you may need it. Post the output from:
uname -a
so folks know what version of unix you have.
ReadLines=0
while [ true ]
do
TMPVAR=$(date +%s)
Totallines=$(wc -l /var/log/YOU.log )
Totallines=$((Totallines-ReadLines))
tail -n $Totallines /var/log/YOU.log | grep -A 50 'PATTERN' > /tmp/$TMPVAR.tmpfile
if grep 'username' /tmp/$TMPVAR.tmpfile ;
then
mail -s failure xxxxx@yyy.com < /tmp/$TMPVAR.tmpfile
fi
rm -rf /tmp/$TMPVAR.tmpfile
sleep 900
done
Some concept .. You need to just check with syntax to suit your system.
Basically what I am trying
While [ true ] ---> infinate loop
TMPVAR ... just to create tmp file...
Checking number of lines now and subtracting from what we have previously read. So that we dont want to send error which we have seen already ..
Tail -n ... read only last lines ... what we have not read from previous run .. And check patten and get lines matching above matching pattern.
Then again grep in the 50 lines from PATTERN which are in tmp file .. to see if username is available or not ..
if Available then mail .. else ... Nothing ..
Cleanup: remove all tmp file etc .. and sleep for 900 sec 15 mins ..
Better place to put this check is in cron:
Incase you decide to put in cron removing while do ... then push this number to some tmp file .. Like records read and etc ..
Also make note of more details in the same tmp where number of records are saved.. details like log file creation date etc to reset ReadLines variables incase the log gets rotated .. truncated etc ...
When you change PATTERN and username for your system .. Please add proper escape character wherever applicable