Monitor log and send Alert mail using shell script in Linux - linux

I created .sh file to grep specific words in log and will send a mail to particular emailID (Set Cronjob to run this script every 1hour). Its working as expected, But the Problem is if there is no error also I am getting Empty Mail.
Needs to get Mail, if we caught error and DBError file has content. Kindly please help me on this to resolve this issue.
#!/bin/bash
if [ ! -e DBErrors ] ; then
grep "sqlException" /opt/apps/cms/logs/cms-runtime.log > DBErrors
mail -s "ALERT: sqlException" Jayaram.Ponnusamy#gmail.com < DBErrors
else
comm -23 <(grep "sqlException" /opt/apps/cms/logs/cms-runtime.log) DBErrors | mail -s "ALERT: sqlException" Jayaram.Ponnusamy#gmail.com
grep "sqlException" /opt/apps/cms/logs/cms-runtime.log > DBErrors
fi
Thanks
Jayaram

Could you try this;
#!/bin/bash
dbErrors="/tmp/DBErrors"
if [ ! -e "$dbErrors" ]; then
grep "sqlException" /opt/apps/cms/logs/cms-runtime.log > $dbErrors
mailbody=$(grep "sqlException" /opt/apps/cms/logs/cms-runtime.log); [[ -n "$mailbody" ]] && mail -s "ALERT: sqlException" Jayaram.Ponnusamy#gmail.com
else
mailbody=$(comm -23 <(grep "sqlException" /opt/apps/cms/logs/cms-runtime.log| sort -n) <(sort -n "$dbErrors")); [[ -n "$mailbody" ]] && mail -s "ALERT: sqlException" Jayaram.Ponnusamy#gmail.com
grep "sqlException" /opt/apps/cms/logs/cms-runtime.log > $dbErrors
fi

Related

How Do I not send file if data is not available via linux

I have the following code
for f in *#gmail.com*
do
tmp=$( echo $f | awk -F'[_]' '{print $1}')
tmp1=$( echo $f | awk -F'[_]' '{print $2 ,$3, $4,$5,$6}')
newname1=${tmp1}
newname=${tmp}
echo $newname
echo $newname1
mv "$f" "${newname1}.csv"
mail -a "${newname1}.csv" -s "working" $newname </dev/null
mv "${newname1}.csv" $f
rm -f "$f" "${newname1}.csv"
done
echo "mail -a "$newname1" "working" $newname </dev/null "
This script works even if the CSV file contains no data. But no mail should be send, if that CSV file is empty.
You simply send mail only, if the CSV file has more than one line:
if (( $(wc -l <YOUR_FILE.csv) > 1 ))
then
mail ....
fi
Check if file size is Not zero then send mail
if [ -s ${newname1}.csv ]
then
mail -a "${newname1}.csv" -s "working" $newname </dev/null
fi
If File size is not empty and have some header then you can use this code to calculate no. of rows from file and check if no. of lines greater then one(header)
row=`cat ${newname1}.csv|wc -l`
if [ $row -gt 1 ]
then
mail -a "${newname1}.csv" -s "working" $newname </dev/null
fi

How to replace value of place holder

I am new to shell programming. I have two files:
eg.txt
file.sh
The eg.txt file has some HTML content and file.sh cotains a shell script.
In the script a value is assigned to the temp variable, and that value should be injected into the HTML file.
eg.txt
<html>
Hi MGM ,<br/>
One alert has been received !!<br/>
Here is the event Data.<br/><br/>
<font size=‘1’>{temp}</font>
<br/><br/>
Regards,
WDTS Supports.
</html>
file.sh
echo $1
temp=56
(
echo "To:"$1
echo "Subject: Alert Updates !! "
echo "Content-Type: text/html"
echo cat eg.txt
) | /usr/sbin/sendmail -t
echo "Mail sent !!"
With sed :
sed "s/{temp}/$temp/" eg.txt | /usr/sbin/sendmail -t
You can also use printf to inject variables in your template :
file.sh
temp=56
tpl=$(cat "eg.txt")
printf "$tpl" "$1" "$temp" | /usr/sbin/sendmail -t
eg.txt
To:%s
Subject: Alert Updates !!
Content-Type: text/html
<html>
Hi MGM ,<br/>
One alert has been received !!<br/>
Here is the event Data.<br/><br/>
<font size=‘1’>%s</font>
<br/><br/>
Regards,
WDTS Supports.
</html>
Update:
If multiple variables, just write multiple substitute commands (and update placeholders in eg.txt):
sed "s/{temp1}/$temp1/;s/{temp2}/$temp2/" eg.txt | /usr/sbin/sendmail -t
I have introduced some error checking to your code :
#!/bin/bash
temp=56
if [ -z "$1" ]
then
echo "Usage : ./file.sh user_name_to_mail to"
exit -1
else
if id "$1" >/dev/null 2>&1 #Check if user exists, suppress stdout, stderr
then
mail_header=$(echo -e "To: $1\nSubject: Alert Updates"'!!'"\nContent-Type: text/html\n")
mail_body=$(awk -v var="$temp" '{print gensub(/{temp}/,var,"g"$0)}' eg.txt)
echo -e "$mail_header\n$mail_body" | sendmail -t
else
echo -e "Sorry! Invalid User\n"
exit -1 # The error code is set to detect failure
fi
fi
To prevent the mails going to spam you need to have a valid SPF record for domain from which you're sending email. Check [ this ] for a starting point.
Note:
! is a special character to bash, it is used to refer to previous command. To work around this problem I have used ..Updates"'!!'"\nContent-Type...
Inside the single quotes the ! loses its special meaning.
Interesting reads :
What is an [ SPF ] record?
Open SPF [ documentation ] .
echo $1
temp=56
(
echo "To:"$1
echo "Subject: Alert Updates !! "
echo "Content-Type: text/html"
awk -F "" -v var=$temp '{gsub(/{temp}/,var,$0); print}' < eg.txt
) | /usr/sbin/sendmail -t
echo "Mail sent !!"
added awk to '|' where the temp is stored in awk variable : var which is later replaced
awk -F "" -v var=$temp '{gsub(/{temp}/,var,$0); print}'

Oracle Database Alert log script error

i wrote alert log script and some how this is not working and not throwing any error when i execute the script
i am suspecting sed part is not working properly. could you please advice where i am doing wrong?
here is the piece of code
#!/bin/sh
## Heading #########################################################################################
#---------------------------------------------------------------------------------------#
# script usage #
#---------------------------------------------------------------------------------------#
_usage() {
echo "Usage: $0 ORACLE_SID "
} # _usage
ORACLE_SID="$1"
setenv ()
{
eval "$1=$2"
export "$1"
} # setenv
unsetenv ()
{
while [ $# -gt 0 ]
do
unset "$1"
shift
done
} # unsetenv
if [ $# -ne 1 ]; then
_usage
exit 1
fi
Env=/u01/app/oracle/config
HN=`uname -n`
ERROR_FILE=/tmp/${ORACLE_SID}_error.log
HN=`hostname`
DBA_MAIL="oracle.mail#company"
DBA_PAGE=""
#+--------------------------------------------------------------------------------------+
#| get oracle environment variables from our common env dir |
#+--------------------------------------------------------------------------------------+
if [ -r $Env/${ORACLE_SID}.env ]
then
. $Env/${ORACLE_SID}.env
else
ORACLE_SID=""
fi
#+--------------------------------------------------------------------------------------+
#| just checking for Oracle Env variables for connecting database |
#+--------------------------------------------------------------------------------------+
if [ "$ORACLE_SID" = "" ]
then
echo "ORACLE_SID is invalid"
exit 1
fi
if [ "$ORACLE_HOME" = "" ]
then
echo "The environment variable ORACLE_HOME must be set"
exit 1
fi
if [ "$ORACLE_BASE" = "" ]
then
echo "The environment variable ORACLE_BASE must be set"
exit 1
fi
_AlertLogLoc ()
{
ALERTLOG=`$ORACLE_HOME/bin/sqlplus -s "/as sysdba" << EOF
set head off pause off term on feed off timing off
select value from v\\$parameter where name like 'background_dump_dest';
exit;
EOF`
}
_AlertLogLoc
echo $ALERTLOG
export ALERTLOG
if [ -f $ALERTLOG/alert_${ORACLE_SID}.log ]; then
echo "Found Database Alert log"
else
echo "Alert log not found .. exit from script"
fi
if [ -f $ALERTLOG/alert_${ORACLE_SID}.skip ]; then
echo " ORACLE_SID skip error file found"
SKIP_ERR=`cat $ALERTLOG/alert_$ORACLE_SID.skip|xargs|sed -e 's/ /|/g'`
echo $SKIP_ERR
else
echo "No errors will be excluded"
fi
REC_CUR_ALSIZE=/oraworkspace/OSE/logs/alert_${ORACLE_SID}.size # file to record current alert log lines
#---------------------------------------------------------------------------------------------------------#
# let Capture ORA- error from the alert log #
#---------------------------------------------------------------------------------------------------------#
if [ -f $REC_CUR_ALSIZE ]; then
ALSIZE=`cat $REC_CUR_ALSIZE|sed -e 's/^[ \t]*//'`
ALSIZE=`expr $ALSIZE + 1`
else
ALSIZE=0
fi
if [ $ALSIZE -eq 0 ]; then
echo "PROBABLY RUNNUNG THE SCRIPT FIRST TIME"
sed -n $ALSIZE',$p' $ALERTLOG/alert_${ORACLE_SID}.log |egrep -v "$SKIP_ERR"|grep -i 'ORA-' > /tmp/${ORACLE_SID}_error.log
#`wc -l $ALERTLOG/alert_${ORACLE_SID}.log > $REC_CUR_ALSIZE
cat $ALERTLOG/alert_${ORACLE_SID}.log|wc -l > /oraworkspace/OSE/logs/alert_${ORACLE_SID}.size
#ALSIZE=`cat $ALERTLOG/alert_${ORACLE_SID}.log |wc -l`
else
sed -n ${ALSIZE}',$p' $ALERTLOG/alert_${ORACLE_SID}.log |egrep -v "$SKIP_ERR"|grep -i 'ORA-' > /tmp/${ORACLE_SID}_error.log
#wc -l $ALERTLOG/alert_${ORACLE_SID}.log >> $REC_CUR_ALSIZE
cat $ALERTLOG/alert_${ORACLE_SID}.log |wc -l > /oraworkspace/OSE/logs/alert_${ORACLE_SID}.size
fi
#---------------------------------------------------------------------------------------------------------#
# Notify if any errors are found #
#---------------------------------------------------------------------------------------------------------#
ERR_CNT=`cat /tmp/${ORACLE_SID}_error.log |wc -l`
if [ $ERR_CNT -ne 0 ]; then
echo "Errors found in the alert log. send email notification"
mailx -s "${HN}:${ORACLE_SID} ORA error Found in the alert log" ${DBA_MAIL} < $ERROR_FILE
#mailx -s "${HN}:${ORACLE_SID} ORA error Found in the alert log" ${DBA_MAIL} < $ERROR_FILE
else
echo " No errors found in the alert log"
fi
If $ALERTLOG/alert_$ORACLE_SID.skip doesn't exist or is empty (around line 94), the egrep -v "$SKIP_ERR" will exclude all lines from the sed output, so it will not have a chance to see any remaining ORA- errors.
ALSIZE=1
SKIP_ERR=""
sed -n $ALSIZE',$p' $ALERTLOG/alert_${ORACLE_SID}.log |\
egrep -v "$SKIP_ERR"|wc -l
0
SKIP_ERR="dummy"
sed -n $ALSIZE',$p' $ALERTLOG/alert_${ORACLE_SID}.log |\
egrep -v "$SKIP_ERR"|wc -l
15165
So you need to set your SKIP_ERR to something when it's not set or empty (if your skip file is empty). You haven't said if that is the case or shown the script output, but it seems to work apart from that.
Also not that if ALSIZE is zero sed isn't happy, at least in RHEL 5:
ALSIZE=0
SKIP_ERR="dummy"
sed -n $ALSIZE',$p' $ALERTLOG/alert_${ORACLE_SID}.log |\
egrep -v "$SKIP_ERR"|wc -l
sed: -e expression #1, char 4: invalid usage of line address 0
0
And when you test that the file exists at line 91, you show a message stating that and suggesting you'll stop there, but there is no exit after line 94; doesn't seem to be relevant here but seems like an oversight?

need to know the status of rsync on linux machine

I am syncing my backup server from production server through rsync but now i want to implement the failure notification. When i trying to get status of rsync command it does not give me status =0 on success. please let me know how i will implement this functionality.
failureMailFlag=0
rsync --timeout=600 -e ssh -avzr --delete $sourcePath/weblayout/ $destination:$destinationPath/weblayout/ --stats -i > $fileCreationPath/$tempfile 2>&1
rStatus=$?
if [ $rStatus == "0" ]
then
echo -e "$startdate\t\tweblayout\t\t$starttime\t\t$(date +"%m-%d-%Y %r")\t\tSuccess\t\t" >> $fileCreationPath/RsyncLog.txt
else
echo -e "$startdate\t\tweblayout\t\t$starttime\t\t$(date +"%m-%d-%Y %r")\t\tError\t\t">> $fileCreationPath/RsyncLog.txt
failureMailFlag="1"
cat $failureMail $tempfile >> $fileCreationPath/finalFailureMail.mai
wablayout=weblayout
varFailureMail=${varFailureMail}${wablayout}
fi
if [ $failureMailFlag == "1" ]
then
cat $fileCreationPath/*.mail finalFailureMail.mai $fileCreationPath/$varFailureMail $fileCreationPath/$tempfile | mailx -s "Failure Mail notification for RSYNC" $EmailSent
else
echo "successfully run"
fi
Try:
if [ $rStatus -eq "0" ]
== is for strings not ints I think
Use ; instead of 2>&1 like below
rsync --timeout=600 -e ssh -avzr --delete $sourcePath/weblayout/ $destination:$destinationPath/weblayout/ --stats -i > $fileCreationPath/$tempfile ; rStatus=$?

Unexpected end of file in BASH

Writing a simple bash script to do some checks for me in the morning:
One part is pulling down some html files and making sure that they exist.
The other part is ensuring some local files are present, and emailing if they are not.
The problem I am facing is that I am receiving a "syntax error: unexpected end of file" and I can't really understand why it i occuring.
Here is a simplified version of the code:
for myHost in $HOSTS
do
result=$(wget -T $TIMEOUT -t 1 $myHost -O /dev/null -o /dev/stdout)
result2=$(echo $result | grep "awaiting response")
connected=$(echo $result | grep "404");
if [ "$connected" != "" ]; then
for myEMAIL in $EMAIL
do
echo -e "$(date) - $myHost is down! \n This is an automated message." | mailx -r "box.email.com" -s "$SUBJECT" $myEMAIL
done
fi
done
numoffiles=`find . -maxdepth 1 -mtime -1 | grep -i .html | wc -l`
if [ "$numoffiles" -ne 5 ]; then
FILE=$(find . -maxdepth 1 -mtime -1 -print| grep -i .html)
mailx -r "box.email.com" -s "FILE MISSIN" "$EMAIL" << EOF
EOF
fi
from using sh -x I can see that it gets to assigning the number of reports to the var "numoffiles", but then it just believes that is the end of the file. has anyone got any suggestions?
There should not be any space before the end of heredoc label:
EOF
^^^
Change it to
EOF

Resources