search in log from last hour

Posted on

Problem :

I need bash script to search in the log words Failed and failure. But only from last hour

cut -c 5- /var/log/mail.log | awk '($0 >= from)' from="$(LC_TIME=C date +'%_d %H:%M:%S' -d -1hour)" |grep -i 'Failed:|failure'

Example log file

Nov  1 01:00:00 localhost pushmail[55555]: 666666666666: Failed 
Nov  2 15:00:00 localhost pushmail[55556]: 666666666666: Failed 
Nov  3 11:00:00 localhost pushmail[55557]: 666666666666: Failed 
Nov  3 12:00:00 localhost pushmail[55558]: 666666666666: Failed 
Nov  3 13:30:00 localhost pushmail[55559]: 666666666666: Failed 
Nov  3 13:40:00 localhost pushmail[55560]: 666666666666: Failed 
Nov  3 14:00:00 localhost pushmail[55561]: 666666666666: Failed 
Nov  3 15:00:00 localhost pushmail[55562]: 666666666666: Failed 
Nov 14 15:00:00 localhost pushmail[55563]: 666666666666: Failed 

I use cut to remove local month name. But when I have in log entry form two day ago i have it in results.

Solution :

The most reliable solution I could find is:

while read -r rec
do   age=$(($(date +%s)-$(date -d "${rec:0:16}" +%s)))
     [ $age -ge 0 -a $age -le 3600 ] && 
     grep -Eiq 'failed|failure' <<< "$rec" && echo "$rec"
done </var/log/mail.log

This uses date to convert logged times into seconds since the start of 1970 and then compares these with the seconds value for the current time. This will work in all cases, including the hour after midnight, except the first hour of a new year, because date -d defaults to the current year when none is specified. I assume you will have better things to do than run this script at the dawn of a new year.

The check for the record age being non-negative eliminates future records, as I found in the Nov 14 record when testing on 3rd November. I simulated calling at different times by adding a -d parameter to the first date call, which in the answer gets the current time reference.

The problem is that "14">" 3" because 1>” “. You need to use leading zeroes in your dates. For example, you can put all the commands into one awk:

awk '{ date = sprintf("%02d %s",$2,$3) }
     date>from && /Failed|failure/ { print }
' from="$(LC_TIME=C date +'%d %H:%M:%S' -d -1hour)"

I changed the %_d to %d to get leading zeroes from date. In the awk the sprintf uses %02d to put a leading zero to field 2, the date.

awk ‘($0 >= from)’ from=”$(LC_ALL=C date +’%b %_d %H:%M:%S’ -d -1hour)” ~/mail.log |grep -i ‘Failed|failure’

Hi! Thanks everyone for help!
In my case this script work. if you want to change range of time from 1 hour you can do this chcenaging value example -d -60minutes or -d -2days

Leave a Reply

Your email address will not be published.