We have around 22 logs , each has different entries. I have to automate this using shell script. The ideas which am sharing is given below
1) We use only TAIL -100 <location and name of the log> Command to check the logs.
2) We want to check whether the log was updated before 24 hours or current time stamp, if found it should send a mail the log looks good.
3) We want to check whether there is an ERROR message found on the log (only ERROR, not error,Error) , if found it should send a mail like Error message was found or else exit without sending a mail.
Suggestion needed is how to gather all 22 logs in one single mail , if it has updated before 24 hours. and how to gather the ERROR message if it is presented in the log and mail us seperately with the log name . Could any1 help me with this thread and idea?
post examples of your log files, expected output and what you expect to have in the email ... it would also help if you post what you have done with your script so far ...
Then in my script I'd do this (hasn't been tested, but you can tweak it a little in order to suit your needs):
#!/bin/bash
mailcontents=mailbody
while read line
do
last_mod_time=$(stat -c '%Y' $line) # this line checks the log's last modification time and converts it to Unix's epoch
last_24_hours=$(date +%s -d "24 hours ago") # this line returns the epoch for the current timestamp minus 24 hours
if [ $last_mod_time -lt $last_24_hours ]; then
echo "Log $line has NOT been updated in the last 24 hours" >> $mailcontents
echo "============" >> $mailcontents
else
echo "Log $line was updated during the last 24 hours" >> $mailcontents
echo "============" >> $mailcontents
fi
tail -100 $line > checklog
error=$(cat checklog | grep ERROR | wc -l)
if [ $error -gt 0 ]; then
echo "ERROR found in log $line" >> $mailcontents
fi
done < mylogs
if [ -s $mailcontents ]; then
mail -s "Log errors and last modification times" youremail@yourdomain.com < $mailcontents
fi
rm $mailcontents checklog
No worries. I'm more than glad to be able to help.
Let me refer to the script itself to answer your questions:
Note that you don't need the .txt extension. You can leave it there if you want, though. Just a thing here, I assume you meant "Logcheck.txt" - without the uppercase "O". This kind of typo can cause your script to run with issues or not run at all.
You don't need to add the cd command - just the absolute path to the log. The loop
while read line
do
[...bunch of commands here :) ...]
done < Logcheck.txt
does this:
It reads the Logcheck.txt file (that's what the "<" does - it tells the while loop to use the file as input) line by line, one at a time, and during every run it assigns the value of each line to the line variable. Picture this scenario. Let's say the Logcheck.txt file looks exactly as I mentioned in my first post. During the first loop, the line variable (referenced in the rest of the loop as $line) will take the value /var/log/mail.log, and that value will be used until the loop ends and starts again, this time with the line variable taking the value of the 2nd line in your Logcheck.txt file.
That line saves the last 100 lines of each log (refer to the first answer - $line here will be replaced by the absolute path to each script during each loop) to the checklog file. (Note that I didn't use the extension here).
So during the first loop this will actually be:
tail -100 /var/log/mail.log > checklog
"checklog" is an auxiliary file where we're redirecting the output of each log and that's where we'll search for errors later.
That line will delete your auxiliary files mailbody (see the top of the script) and checklog once the loop has ended and you don't need them anymore. You can comment out that line if you want to keep those files.
Let me know if you need further help ;).
---------- Post updated at 09:38 PM ---------- Previous update was at 09:09 PM ----------
Updated version, tested :). Works like a charm.
1) I created the file named mylogs.
2) Updated script:
#!/bin/bash
mailcontents=mailbody
while read line
do
if [ ! -f $line ]; then
echo "The file $line doesn't exist. Continuing with the next file..." >> $mailcontents
echo "============" >> $mailcontents
continue
else
last_mod_time=$(stat -c '%Y' $line) # this line checks the log's last modification time and converts it to Unix's epoch
last_24_hours=$(date +%s -d "24 hours ago") # this line returns the epoch for the current timestamp minus 24 hours
if [ $last_mod_time -lt $last_24_hours ]; then
echo "Log $line has NOT been updated in the last 24 hours" >> $mailcontents
else
echo "Log $line was updated during the last 24 hours" >> $mailcontents
fi
tail -100 $line > checklog
error=$(grep ERROR checklog | wc -l) # We look for the lines containing the word "ERROR" in the checklog file.
# Then we redirect the output to the wc -l command that will count the number
# of lines where the word ERROR appears.
if [ $error -gt 0 ]; then # If this condition is satisfied, that means the word ERROR appeared at least once in
# the log that's being examined in the current loop.
echo "ERROR found in log $line" >> $mailcontents
else
echo "No errors found in $line" >> $mailcontents
fi
fi
echo "============" >> $mailcontents
done < mylogs
if [ -s $mailcontents ]; then
mail -s "Log errors and last modification times - $(date +'%A %B %d, %Y')" myemail@gmail.com < $mailcontents
fi
rm $mailcontents checklog # Delete auxiliary files when we're done.
The results:
---------- Post updated at 10:21 PM ---------- Previous update was at 09:38 PM ----------
Added file test.log with the word ERROR in 2 lines, and included it in the mylogs file (where the list of the logs is stored):
The results in the email: (note that the email includes the lines with the errors). You need to add the following line
You're welcome :).
Here's an improved, fully commented version of the script:
#!/bin/bash
################################################################################
# AUTHOR: Gabriel A. C�nepa / Twitter: @gacanepa
# CREATION DATE: July 11, 2013
# LICENSE: GPL v3 or later. See http://www.gnu.org/licenses/gpl.html
# USAGE:
# - Create a plain text file (THE FILE) with a list of files to be examined.
# For example:
# ls -ld /var/log/* | grep '^-' | grep 'log$' | awk '{print $9}' > mylogs
# [List all regular files (grep '^-' looks for a hyphen at the beginning
# of each line resulting from the output of the ls command) that end in
# .log, then prints the 9th field, which is the absolute pathname of each
# file (see the -d option of the ls command)]
# - Chmod it to 700 (or give it adequate permissions)
# - This script will:
# * search the word ERROR in the last 100 lines of those files.
# * if any of those files doesn't exist, or is not a regular file,
# the script will skip it and continue with the next file.
# * detect whether each file has been updated during the last 24 hours.
# * send the results via email.
# * See example: http://i40.tinypic.com/2e5pnjd.png
# MODIFICATION HISTORY:
# - July 12, 2013:
# * Added email header with host information and job date
# * Added email footer: user executing the script
# * Replaced THE FILE's relative pathname (mylogs) for its absolute
# pathname (/home/gacanepa/stuff/scripts/mylogs), stored in the
# loglist variable, to be able to run the script through cron as well.
################################################################################
mailcontents=mailbody # Auxiliary file that is used to store the contents of the email's body
loglist=/home/gacanepa/stuff/scripts/mylogs # Absolute path to the file that contains the
# list of files to be examined. This way, the script
# can be run through cron as well.
# Email header
echo "*****************************************************************" > $mailcontents
echo "* LOG CHECK - HOST: $HOSTNAME - DATE: $(date +'%A %B %d, %Y') *" >> $mailcontents
echo "*****************************************************************" >> $mailcontents
echo "" >> $mailcontents
# End email header
while read line
do
if [ ! -f $line ]; then
echo "$line doesn't exist or is not a regular file. Continuing with the next file in the list..." >> $mailcontents
echo "============" >> $mailcontents
continue
else
last_mod_time=$(stat -c '%Y' $line) # Check the log's last modification time and converts it to Unix epoch
last_24_hours=$(date +%s -d "24 hours ago") # Return the epoch of (the current timestamp minus 24 hours)
if [ $last_mod_time -lt $last_24_hours ]; then
echo "$line has NOT been updated in the last 24 hours" >> $mailcontents
else
echo "$line was updated during the last 24 hours" >> $mailcontents
fi
tail -100 $line > checklog
error=$(grep ERROR checklog | wc -l) # We look for the lines containing the word "ERROR" in the checklog file.
# Then we redirect the output to the wc -l command to count the number
# of lines where the word ERROR appears.
if [ $error -gt 0 ]; then # If this condition is satisfied, that means the word ERROR appeared at least once in
# the log that's being examined in the current loop.
echo "ERROR found in $line" >> $mailcontents
echo -e "\t" $(grep ERROR checklog) >> $mailcontents
else
echo "No errors found in $line" >> $mailcontents
fi
fi
echo "============" >> $mailcontents
done < $loglist
# Email footer
echo "" >> $mailcontents
echo "This script was executed by $USER on $(date +'%A %B %d, %Y') at $(date +'%H:%M:%S')" >> $mailcontents
# End email footer
if [ -s $mailcontents ]; then
mail -s "Errors and last modification times - $(date +'%A %B %d, %Y')" myemail@mydomain.com < $mailcontents
fi
rm $mailcontents checklog # Delete auxiliary files when we're done.
If you consider that your question has been answered, please mark this thread as SOLVED for the future reference of other users (Go to "Thread tools" and click on "Mark this thread as solved"), and please click on the "Thanks" link in the bottom right corner of this post.
I have created a text file by adding the logs and saved it as mylog.txt
#!/bin/sh
mailcontents=mailbody
while read line
do
if [ ! -f $line ]; then
echo "The file $line doesn't exist. Continuing with the next file..." >> $mailcontents
echo "============" >> $mailcontents
continue
else
last_mod_time=$(stat -c '%Y' $line) # this line checks the log's last modification time and converts it to Unix's epoch
last_24_hours=$(date +%s -d "24 hours ago") # this line returns the epoch for the current timestamp minus 24 hours
if [ $last_mod_time -lt $last_24_hours ]; then
echo "Log $line has NOT been updated in the last 24 hours" >> $mailcontents
else
echo "Log $line was updated during the last 24 hours" >> $mailcontents
fi
tail -100 $line > mylog.txt
error=$(grep ERROR mylog.txt | wc -l) # We look for the lines containing the word "ERROR" in the mylog.txt file.
# Then we redirect the output to the wc -l command that will count the number
# of lines where the word ERROR appears.
if [ $error -gt 0 ]; then # If this condition is satisfied, that means the word ERROR appeared at least once in
# the log that's being examined in the current loop.
echo "ERROR found in log $line" >> $mailcontents
else
echo "No errors found in $line" >> $mailcontents
fi
fi
echo "============" >> $mailcontents
done < mylogs.txt
if [ -s $mailcontents ]; then
mail -s "Log errors and last modification times - $(date +'%A %B %d, %Y')" myemail@gmail.com < $mailcontents
fi
rm $mailcontents mylog.txt # Delete auxiliary files when we're done.
This is the script i written to execute the shell to retrieve the logs from mylog.txt
The issues which i faced is
1) Am using AIX terminal for running the script.
2) Am facing issues in date convertion steps
The stat -c is not recognized as well as date -d is not recognized on the AIX terminal. Its sending a result like " The logs were not Updated for 24 hours for all the logs as it couldnt recognize/read the dates on the logs.
The only problem is date conversion is there any solution for this to run the shell script (not bash) .. Could you please help me out by modifying the date conversion which would be in a readable format for AIX terminal. Thanks for your patience and thanks in advance
Hi Hari,
When you post code, you should use code tags :).
You can do this by writing the word "CODE" inside square brackets at the beginning of the code, and at the end "/CODE", also inside square brackets and without quotes.
I didn't know you were running AIX, but it's OK. Unfortunately, I don't have an AIX box to test an equivalent command :(. But take a look at this post or this post and see if it helps. It looks like in AIX there is an istat command. Alternatively you can google something like "Linux stat equivalent in AIX" or the like.
As far as the date format is concerned, you can examine date's man page by typing in your terminal "man date" (without quotes) and choose the format that best suits your needs.
Let me explain further:
date +%s -d "24 hours ago"
When you run the date command (without options) you get something like:
gacanepa@Gabriel-PC ~ $ date
Sat Jul 13 21:52:20 WARST 2013
In date's man page for AIX you should find a list of format modifiers. For example, the
+%s
modifier tells date to convert its output (shown above) to the number of seconds ellapsed since January 1, 1970 (known as Unix epoch).
As to the -d option:
-d, --date=STRING
display time described by STRING, not `now'
So what this does is:
Display Unix epoch for the current timestamp minus 24 hours.
I'm pretty sure that you can find an equivalent for AIX. The best of luck!
Thanks for the post. I tried by editing the code like
last_mod_time=$(date +%s $line) # this line checks the log's last modification time and converts it to Unix's epoch
last_24_hours=$(date "+%Y %m %d_%H %M %S" "24 hours ago") # this line returns the epoch for the current timestamp minus 24 hours
I dont know whether i have did correctly but i think its giving me a wrong update , actually the log was updated in 24 hours gap but am getting mail like the log was not updated. Could you please modify this alone. IF possible and make it run in AIX terminal. Sorry for bothering you again and again
Unfortunately I don't have an AIX terminal to try :(. What I can tell by looking at your script is that you're trying to perform a date conversion using wrong parameters.
Something that just came to my mind is which shells you have installed in your system.
Please post the output of the following commands:
1) echo $SHELL
2) chsh -l
3) cat /etc/shells
Another thing. Did you leave the first line of my script intact? ( #!/bin/bash )
---------- Post updated at 04:29 PM ---------- Previous update was at 03:35 PM ----------
i think your idea worked but am not 100% sure about . When i ran the above perl idea added with the bash script , it din showed me any errors or warnings. Just entered the next line. then i ran sh samp.bash it displayed the below output in my mail
I added a log of mine added with ERROR. Thanks for the script .
The file /var/opt/effi/cron.log doesn't exist. Continuing with the next file...
============
The file /var/opt/effi/Doc_cron.log doesn't exist. Continuing with the next file...
============
The file /var/opt/effi/Call_cron.log doesn't exist. Continuing with the next file...
============
The file /var/opt/effi/RSA_cron.log doesn't exist. Continuing with the next file...
============
The file /var/opt/effi/IAS_cron.log doesn't exist. Continuing with the next file...
============
Log /var/opt/hari.log has NOT been updated in the last 24 hours ERROR found in log /var/opt/hari.log============ The file /opt/IBM/FileNet/AE/Router/ConsumerUnderwriting/CUE_cron.log /opt/IBM/FileNet/AE/Router/ConsumerUnderwriting/BuildDoc/CUBuilDoc_cron.log doesn't exist. Continuing with the next file...
============
The file /var/opt/SSPCall_cron.log doesn't exist. Continuing with the next file...
============
The file /var/opt/RSA_cron.log doesn't exist. Continuing with the next file...
============
The file /var/opt/IAS_cron.log doesn't exist. Continuing with the next file...
============
The file /var/opt/Complete_cron.log doesn't exist. Continuing with the next file...
============
The file /var/opt/Extract_cron.log doesn't exist. Continuing with the next file...
============
The file /var/opt/ExtractContentQ_cron.log doesn't exist. Continuing with the next file...
============
Log /var/opt/hari.log has NOT been updated in the last 24 hours ERROR found in log /var/opt/hari.log
============
The file 1 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 3 doesn't exist. Continuing with the next file...
============
The file 43 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 55 doesn't exist. Continuing with the next file...
============
The file 5 doesn't exist. Continuing with the next file...
============
The file ERROR doesn't exist. Continuing with the next file...
============
The file Error doesn't exist. Continuing with the next file...
============
The file ERROR:Filename doesn't exist. Continuing with the next file...
============
The file error doesn't exist. Continuing with the next file...
============
The file ERROR: I gotcha!! doesn't exist. Continuing with the next file...
============
The file 1 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 3 doesn't exist. Continuing with the next file...
============
The file 43 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 55 doesn't exist. Continuing with the next file...
============
The file 5 doesn't exist. Continuing with the next file...
============
The file ERROR doesn't exist. Continuing with the next file...
============
The file Error doesn't exist. Continuing with the next file...
============
The file ERROR:Filename doesn't exist. Continuing with the next file...
============
The file error doesn't exist. Continuing with the next file...
============
The file ERROR: I gotcha!! doesn't exist. Continuing with the next file...
============
The file 1 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 3 doesn't exist. Continuing with the next file...
============
The file 43 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 55 doesn't exist. Continuing with the next file...
============
The file 5 doesn't exist. Continuing with the next file...
============
The file ERROR doesn't exist. Continuing with the next file...
============
The file Error doesn't exist. Continuing with the next file...
============
The file ERROR:Filename doesn't exist. Continuing with the next file...
============
The file error doesn't exist. Continuing with the next file...
============
The file ERROR: I gotcha!! doesn't exist. Continuing with the next file...
============
I have some thing which needs to be cleared in the above output. I don't want to see these lines.
The file 1 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 3 doesn't exist. Continuing with the next file...
============
The file 43 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 55 doesn't exist. Continuing with the next file...
============
The file 5 doesn't exist. Continuing with the next file...
============
The file ERROR doesn't exist. Continuing with the next file...
============
The file Error doesn't exist. Continuing with the next file...
============
The file ERROR:Filename doesn't exist. Continuing with the next file...
============
The file error doesn't exist. Continuing with the next file...
============
The file ERROR: I gotcha!! doesn't exist. Continuing with the next file...
============
The file 1 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 3 doesn't exist. Continuing with the next file...
============
The file 43 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 55 doesn't exist. Continuing with the next file...
============
The file 5 doesn't exist. Continuing with the next file...
============
The file ERROR doesn't exist. Continuing with the next file...
============
The file Error doesn't exist. Continuing with the next file...
============
The file ERROR:Filename doesn't exist. Continuing with the next file...
============
The file error doesn't exist. Continuing with the next file...
============
The file ERROR: I gotcha!! doesn't exist. Continuing with the next file...
============
The file 1 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 2 doesn't exist. Continuing with the next file...
============
The file 3 doesn't exist. Continuing with the next file...
============
The file 43 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 4 doesn't exist. Continuing with the next file...
============
The file 55 doesn't exist. Continuing with the next file...
============
The file 5 doesn't exist. Continuing with the next file...
============
The file ERROR doesn't exist. Continuing with the next file...
============
The file Error doesn't exist. Continuing with the next file...
============
The file ERROR:Filename doesn't exist. Continuing with the next file...
============
The file error doesn't exist. Continuing with the next file...
============
The file ERROR: I gotcha!! doesn't exist. Continuing with the next file...
============
How to make this cleared to get a perfect output like your sample output :
Subject: Log errors and last modification times - Thursday July 11, 2013
To Gabriel Canepa (Gmail)
Log /var/log/alternatives.log was updated during the last 24 hours
No errors found in /var/log/alternatives.log
==============
The file /my/name/is/slim/shady doesn't exist. Continuing with the next file...
==============
Log /var/log/faillog has NOT been updated in the last 24 hours
No errors found in /var/log/faillog
I dont want to see the lines in my log to be presented in the mail as my output resulted.
You get all those "File x doesn't exist" messages because you have added all those files in the log list. Other than that, I don't see much of a difference between the results that you got and mine.
Make sure you list only existing logs, and maybe one or two that don't exist. Then examine the output. If it still doesn't look like you wanted, please send me via email your version of the script and the file that you're using to list all the logs.