Skip to content

Instantly share code, notes, and snippets.

@haballan
Last active July 31, 2023 08:44
Show Gist options
  • Save haballan/78329ca717605d84a083 to your computer and use it in GitHub Desktop.
Save haballan/78329ca717605d84a083 to your computer and use it in GitHub Desktop.
Oracle Database Monitoring Script (Monitors the alertlog, listener logs, CPU, FILESYSTEM, TABLESPACES, ASM, long running queries, locks, alter system/database commands, export/import operations, startup/shutdown activities) http://dba-tips.blogspot.com/2014/02/database-monitoring-script-for-ora-and.html
#!/bin/bash
# ##################################################################################################################################################################
# Database Server Monitoring Script [dbalarm].
VER="[8.0]"
SCRIPT_NAME="dbalarm${VER}"
# Features:
# Report ERRORS in DB, ASM Instance, GRID INFRASTRUCTURE, GOLDENGATE and LISTENERS ALERTLOG plus dmesg DEVICE DRIVER OS log.
# Report TABLESPACES, ASM DISKGROUPS and FRA when reach %USED THRESHOLD.
# Report OFFLINE databases.
# Report CPU, FILESYSTEM, TABLESPACES When hit the THRESHOLD.
# Report LONG RUNNING operations/Active SESSIONS on DB when the CPU hits the THRESHOLD.
# Report BLOCKING SESSIONS in the database.
# Report Failed RMAN Backup Jobs.
# Report User Defined DATABASE SERVICES when they go OFFLINE.
# Notes:
# Most of THRESHOLD and CONTROLS in this script located under THRESHOLDS section. Please adjust them to meet your needs.
# ##################################################################################################################################################################
# # # #
# Author: Mahmmoud ADEL # # # # ###
# Created: 22-12-13 # # # # #
#
# Modified: 23-12-13 Handled non exist logs 1run
# 14-05-14 Handled non existance of LOG_DIR directory.
# 18-05-14 Add Filsystem monitoring.
# 19-05-14 Add CPU monitoring.
# 03-12-14 Add Tablespaces monitoring
# 08-09-15 mpstat output change in Linux 6
# 02-04-16 Using dba_tablespace_usage_metrics To calculate MAXSIZE (11g onwards) Recommended by Satyajit Mohapatra.
# 10-04-16 Add Flash Recovery Area monitoring.
# 10-04-16 Add ASM Disk Groups monitoring.
# 15-09-16 Add "DIG MORE" feature to report.long running operations, queries
# and active sessions on DB side when CPU hits the pre-defined threshold.
# 29-12-16 Enhanced ORACLE_HOME search criteria.
# 02-01-17 Added EXL_DB parameter to allow the user to exclude DBs from having dbalarm script run against.
# 04-05-17 Added the ability to disable Database Down Alert through CHKOFFLINEDB variable.
# 11-05-17 Added the option to exclude tablespace/ASM Diskgroup from monitoring.
# 11-05-17 Tuned the method of reporting OFFLINE databases & checking listener log.
# 20-07-17 Modified COLUMNS env variable to fully display top command output.
# Neutralize login.sql if found in Oracle user home directory due to bugs.
# 19-10-17 Added the function of checking goldengate logfile.
# 11-04-18 Added the feature of monitoring the availability of specific service.
# 28-04-18 Added the function of printing the script progress.
# 30-04-18 Added Paranoid mode, to report EXPORT/IMPORT, ALTER SYSTEM, ALTER DATABASE
# instance STARTUP/SHUTDOWN, other DB Major activities.
# 05-09-18 Modified the wait in seconds column (Blocking Sessions section) for 11gr2 compatibility,
# Added WAIT_FOR_LOCK_THRES threshold to control reporting of sessions blocked for more than N mintes.
# 09-10-18 Enclosing OS Network Failure Statistics (Dropped Packets) whenever TIMOUT error get reported by DB or Listener.
# 15-10-18 Added RMAN Backup Failure Check. [Recommended by: Rahul Malode]
# 22-10-18 Added the Checking of Running RMAN Backup when CPU hit the threshold.
# 01-11-18 Fixing a bug in Monitored Services section.
# 08-11-18 Show the exist restore points if FRA hits the threshold.
# 27-12-18 Checking if another session is running dbalarm script [to avoid performance degradation].
# 14-01-19 Avoid Monitoring the Services if more than one DB instance is running.
# 15-01-19 Added the feature of monitoring the ASM instance ALERTLOG.
# 15-01-18 Added the feature of monitoring the GRID INFRASTRUCTURE ALERTLOG.
# 16-01-19 Added the feature of monitoring Device Driver OS log "dmesg".
# 04-02-19 Added HTML feature to send the alert in HTML format [If sendmail installed, otherwise will use TEXT format automatically].
# 24-03-19 Enhanced the DB Service Monitoring Feature to monitor service availability on RAC setup Locally wise.
# 26-03-19 Listing the Master Blocking Sessions When a Blocking Lock get detected.
# 27-03-19 Used RULE Based Optimizer against all "checking locks" queries for a better performance on RAC instances.
# 15-05-19 Replacement of "bc" function for CPU utilization calculation with "awk".
# 20-05-19 When "unable to extend temp segment" error get detected the Email alert will show the top temp space consumers in the DB.
# 09-04-20 Added Monitoring filesystem inodes features.
# 22-08-20 Exclude reporting error "ORA-235 occurred during an un-locked control file" as advised by MOS 2312580.1.
# 21-03-22 Removed IDLE sessions from Locking report and changed the lock wait time from minutes to seconds.
# 03-06-22 Extracting more info related to sessions distribution on the DB when ORA-00020: maximum number of processes () exceeded is detected
# 28-07-22 Enhance the way of finding Goldengate ggserr logfile.
# 29-07-22 Notify the user if WARNING messages detected in the DB ALERTLOG if PARANOID mode is enabled.
# 15-08-22 Modified the Average CPU Check command.
# 07-09-22 Added new feature: Monitor the number of ACTIVE SESSIONS on the DB through ACTIVE_SESSIONS_THRES variable [0 means disable].
# 19-09-22 Workaround Bugs [28821847 & 24445571] which conceal UNDO Tablespace details on dba_tablespace_usage_metrics on 12c+.
# 19-10-22 Fixing the bug of not showing the server name in the Email subject putting a space between [$.
# 28-10-22 Excluded Patch errors description from the reporting when the alertlog create new log segment.
# 02-11-22 Excluded "ORA-16038 log X sequence# X cannot be archived" from getting reported.
# 08-06-23 Added new feature: cleanup Flashback Logs when FRA reach the defined THRESHOLD, to avail it set FLASHBACK_RESET=Y in THRESHOLDS section.
#
#
#
# ##################################################################################################################################################################
EMAIL="youremail@yourcompany.com"
export SRV_NAME="`uname -n`"
# Check if MAIL_LIST parameter is not set notify the user and exit:
case ${EMAIL} in "youremail@yourcompany.com")
echo
echo "******************************************************************"
echo "Buddy! You forgot to edit line# 80 in dbalarm.sh script."
echo "Please replace youremail@yourcompany.com with your E-mail address."
echo "******************************************************************"
echo
echo "Script Terminated !"
echo
exit;;
esac
# Check if there is another session of dbalarm is running: [Avoid performance impact]
DBALARMCNT=`ps -ef|grep -v grep|grep -v vi|grep dbalarm|wc -l`
if [[ ${DBALARMCNT} -gt 2 ]]
then
echo -e "\033[32;5mdbalarm.sh script is currently running by another session.\033[0m"
echo ""
echo "Please make sure the following sessions are completed before running dbalarm script: [ps -ef|grep -v grep|grep -v vi|grep dbalarm]"
ps -ef|grep -v grep|grep -v vi|grep dbalarm.sh
echo "Script Terminated !"
echo
exit
fi
# In case your company Emails go through specific SMTP server. Specify it in the below line and UN-HASH it:
#export smtp="mailrelay.mycompany.com:25" # Set it to the SMTP NAME:PORT your company is using. [If exist]
export MAIL_LIST="${EMAIL}"
#export MAIL_LIST="-r ${SRV_NAME} ${EMAIL}"
echo
echo "[dbalarm Script Started ...]"
# #########################
# THRESHOLDS:
# #########################
# Modify the THRESHOLDS to the value you prefer:
HTMLENABLE=Y # Enable HTML Email Format [DB]
FSTHRESHOLD=95 # THRESHOLD FOR FILESYSTEM %USED [OS]
FSITHRESHOLD=95 # THRESHOLD FOR FILESYSTEM INODES %USED [OS]
CPUTHRESHOLD=95 # THRESHOLD FOR CPU %BUSY [OS]
INTERVAL_SEC=2 # mpstat/iostat command Interval duration in seconds for checking the average CPU utilization [OS]
COUNT=3 # mpstat/iostat command number of Intervals for checking the average CPU utilization [OS]
TBSTHRESHOLD=95 # THRESHOLD FOR TABLESPACE %USED [DB]
FRATHRESHOLD=95 # THRESHOLD FOR FRA %USED [DB]
FLASHBACK_RESET=N # Turn FLASHBACK feature OFF & ON, to DELETE all FLASHBACK logs to free up FRA if FRATHRESHOLD is hit [DB]
ASMTHRESHOLD=95 # THRESHOLD FOR ASM DISK GROUPS %USED [DB]
BLOCKTHRESHOLD=1 # THRESHOLD FOR THE NUMBER OF BLOCKED SESSIONS [DB]
WAIT_FOR_LOCK_THRES=60 # THRESHOLD FOR THE LOCK TIME OF BLOCKED SESSIONS IN SECONDS [DB]
CHKRMANBKP=Y # Enable/Disable Checking of RMAN Backup FAILURE. [Default Enabled] [DB]
LAST_MIN_BKP_CHK=5 # REPORT RMAN Backup FAILURE in the last N MINUTES. Should be same as the interval of dbalarm script execution in crontab. [DB]
CHKLISTENER=Y # Enable/Disable Checking Listeners: [Default Enabled] [DB]
CHKOFFLINEDB=Y # Enable/Disable Database Down Alert: [Default Enabled] [DB]
CHKGOLDENGATE=Y # Enable/Disable Goldengate Alert: [Default Enabled] [GG]
CPUDIGMORE=Y # Break down to DB Active sessions when CPU hit the threshold: [RECOMMENDED TO SET=N on VERY BUSY systems] [Default Enabled] [DB]
TIMEOUTDIGMORE=Y # Enable/Disable the display of Network Errors when TIMEOUT error get detected. [Default Enabled] [OS]
TEMPSPACEDIGMORE=Y # Enable/Disable the display of TOP Temporary space consumers when ORA-1652 get detected. [Default Enabled] [DB]
SERVICEMON="" # Monitor Specific Named DB Services. e.g. SERVICEMON="'ORCL_RO','ERP_SRVC','SAP_SERVICE'" [DB]
PARANOIDMODE=N # Enable/Disable Paranoid mode will report more events like export/import, instance shutdown/startup. [Default Disabled] [DB]
CHKASMALERTLOG=Y # Enable/Disable Monitoring ASM instance ALERTLOG. [Default Enabled] [DB]
CHKCLSALERTLOG=Y # Enable/Disable Monitoring GRID INFRASTRUCTURE ALERTLOG. [Default Enabled] [GI]
DEVICEDRIVERLOG=Y # Enable/Disable Check "dmesg" Device Driver log for errors. [Default Enabled] [OS]
REPORT_MAX_SESSIONS=Y # REPORT SESSIONS distribution connected to the DB when ORA-00020: maximum number of processes () exceeded is detected. [DB]
ACTIVE_SESSIONS_THRES=0 # Monitor ACTIVE SESSIONS NUMBER and send notification when crossed [0 Means don't monitor] [Default Disabled]. [DB]
ACTIVE_TIME=5 # Session Active Time in seconds to be considered as ACTIVE SESSION if ACTIVE_SESSIONS_THRES variable is set. [DB]
REMOVE_JUNK_MSGS=Y # Remove JUNK MESSAGES from the DB ALERT log. i.e. "XDB initialized" message resulted by bug 29845449. [DB]
SQLLINESIZE=200 # The LINE SIZE for SQLPLUS outputs. [DB]
OSLINESIZE=300 # The LINE SIZE for OS Commands outputs. [Default is 167] [OS]
# #######################################
# Excluded INSTANCES:
# #######################################
# Here you can mention the instances dbalarm will IGNORE and will NOT run against:
# Use pipe "|" as a separator between each instance name.
# e.g. Excluding: -MGMTDB, ASM instances:
EXL_DB="\-MGMTDB|ASM|APX" #Excluded INSTANCES [Will not get reported offline].
# #########################
# Excluded TABLESPACES:
# #########################
# Here you can exclude one or more tablespace if you don't want to be alerted when they hit the threshold:
# e.g. to exclude "UNDOTBS1" modify the following variable in this fashion without removing "donotremove" value:
# EXL_TBS="donotremove|UNDOTBS1"
EXL_TBS="donotremove" #Exclude TABLESPACES from being checked.
# #########################
# Excluded ASM Diskgroups:
# #########################
# Here you can exclude one or more ASM Disk Groups if you do NOT want to be alerted when they hit the threshold:
# e.g. to exclude "FRA" DISKGROUP modify the following variable in this fashion without removing "donotremove" value:
# EXL_DISK_GROUP="donotremove|FRA" Please DO NOT REMOVE/REPLACE the value "dontremove". Good boy ;-)
EXL_DISK_GROUP="donotremove" #Exclude ASM DISKGROUPS from being checked.
# #########################
# Excluded ERRORS:
# #########################
# Here you will tell the script to ignore the ERRORS you don't want to be alerted when they come in the logs:
# Use pipe "|" between each error.
EXL_DB_ALERT_ERR="Patch|ORA-2396|ORA-235|ORA-16401|ORA-16038|TNS-00507|TNS-12502|TNS-12560|TNS-12537|TNS-00505" #Excluded ALERTLOG ERRORS [Will not get reported].
EXL_LSNR_ERR="TNS-00507|TNS-12502|TNS-12560|TNS-12537|TNS-00505" #Excluded LISTENER ERRORS [Will not get reported].
EXL_GRID_ALERT_ERR="donotremove" #Excluded GRID INFRA ERRORS [Will not get reported].
EXL_GG_ERR="donotremove" #Excluded GoldenGate ERRORS [Will not get reported].
EXL_DMESG_ERR=="donotremove|scsmd" #Excluded OS DEVICE DRIVERS ERRORS [Will not get reported].
# #################################
# Excluded FILESYSTEM/MOUNT POINTS:
# #################################
# Here you can exclude specific filesystems/mount points from being reported by dbalarm:
# e.g. Excluding: /dev/mapper, /dev/asm mount points: Remember to put a forward Slash / before each Backslash \
EXL_FS="\/dev\/mapper\/|\/dev\/asm\/" #Excluded mount points [Will be skipped during the check].
# ########################################
# The Great Export of the Above Variables:
# ########################################
export HTMLENABLE
export FSTHRESHOLD
export FSITHRESHOLD
export CPUTHRESHOLD
export INTERVAL_SEC
export COUNT
export TBSTHRESHOLD
export FRATHRESHOLD
export ASMTHRESHOLD
export BLOCKTHRESHOLD
export WAIT_FOR_LOCK_THRES
export CHKRMANBKP
export LAST_MIN_BKP_CHK
export CHKLISTENER
export CHKOFFLINEDB
export CHKGOLDENGATE
export CPUDIGMORE
export TIMEOUTDIGMORE
export TEMPSPACEDIGMORE
export SERVICEMON
export PARANOIDMODE
export CHKASMALERTLOG
export CHKCLSALERTLOG
export DEVICEDRIVERLOG
export REPORT_MAX_SESSIONS
export SQLLINESIZE
export OSLINESIZE
export EXL_DB
export EXL_TBS
export EXL_DISK_GROUP
export EXL_DB_ALERT_ERR
export EXL_LSNR_ERR
export EXL_GRID_ALERT_ERR
export EXL_GG_ERR
export EXL_DMESG_ERR
export EXL_FS
# ###########################
# Check the Linux OS version:
# ###########################
export PATH=${PATH}:/usr/local/bin
FILE_NAME=/etc/redhat-release
export FILE_NAME
if [[ -r ${FILE_NAME} ]]
then
LNXVER=`cat /etc/redhat-release | grep -o '[0-9]'|head -1`
export LNXVER
# Workaround df command output bug "`/root/.gvfs': Permission denied"
export DF='df -hPx fuse.gvfs-fuse-daemon'
export DFI='df -iPx fuse.gvfs-fuse-daemon'
else
export DF='df -h'
export DFI='df -o i'
fi
# #########################
# Checking The FILESYSTEM:
# #########################
echo ""
echo "Checking FILESYSTEM Utilization ..."
# Report Partitions that reach the threshold of Used Space:
FSLOG=/tmp/filesystem_DBA_BUNDLE.log
echo "[Reported By ${SCRIPT_NAME} Script]" > ${FSLOG}
echo "" >> ${FSLOG}
${DF} >> ${FSLOG}
${DF} | grep -v "^Filesystem" |awk '{print substr($0, index($0, $2))}'| egrep -v "${EXL_FS}"|awk '{print $(NF-1)" "$NF}'| while read OUTPUT
do
PRCUSED=`echo ${OUTPUT}|awk '{print $1}'|cut -d'%' -f1`
FILESYS=`echo ${OUTPUT}|awk '{print $2}'`
if [[ ${PRCUSED} -ge ${FSTHRESHOLD} ]]
then
echo "Filesystem [ ${FILESYS} ] has reached ${PRCUSED}% of USED space. Reporting the problem."
mail -s "ALARM: Filesystem [ ${FILESYS} ] on Server [ ${SRV_NAME} ] has reached ${PRCUSED}% of USED space" ${MAIL_LIST} < ${FSLOG}
fi
done
echo "Checking FILESYSTEM Inodes Utilization ..."
FSILOG=/tmp/filesystem_inodes_DBA_BUNDLE.log
echo "[Reported By ${SCRIPT_NAME} Script]" > ${FSILOG}
echo "" >> ${FSILOG}
${DFI} >> ${FSILOG}
${DFI} | grep -v "^Filesystem" | grep -v "not applicable"| awk '{print substr($0, index($0, $2))}'| egrep -v "${EXL_FS}"|awk '{print $(NF-1)" "$NF}'| while read OUTPUT
do
PRCUSED=`echo ${OUTPUT}|awk '{print $1}'|cut -d'%' -f1`
FILESYS=`echo ${OUTPUT}|awk '{print $2}'`
if [[ ${PRCUSED} -ge ${FSITHRESHOLD} ]]
then
echo "INODES of Filesystem [ ${FILESYS} ] has reached ${PRCUSED}%. Reporting the problem."
mail -s "ALARM: INODES of Filesystem [ ${FILESYS} ] on Server [ ${SRV_NAME} ] has reached ${PRCUSED}%" ${MAIL_LIST} < ${FSILOG}
fi
done
rm -f ${FSLOG}
rm -f ${FSILOG}
# #############################
# Checking The CPU Utilization:
# #############################
# LOGFILE PATH:
# ############
export PATH=${PATH}:${ORACLE_HOME}/bin
export LOG_DIR=/tmp
export LOGFILE=${LOG_DIR}/dbalarm.part.log
export CPULOG=${LOG_DIR}/CPU_DBA_BUNDLE.log
export MPSTATLOG=${LOG_DIR}/mpstat_DBA_BUNDLE.log
export VMSTATLOG=${LOG_DIR}/vmstat_DBA_BUNDLE.log
export TOPLOG=${LOG_DIR}/top_DBA_BUNDLE.log
export UPTIMELOG=${LOG_DIR}/uptime_DBA_BUNDLE.log
export CPULOGCONV=${LOG_DIR}/top_processes_DBA_BUNDLE_CONV.log
export CPULOGHTML=${LOG_DIR}/top_processes_DBA_BUNDLE_HTML.log
touch ${LOGFILE}
if [[ -r ${CPULOGHTML} ]]
then
rm ${CPULOGHTML}
fi
# #########################
# HTML Preparation:
# #########################
case ${HTMLENABLE} in
y|Y|yes|YES|Yes|ON|On|on)
if [[ -x /usr/sbin/sendmail ]]
then
export SENDMAIL="/usr/sbin/sendmail -t"
export MAILEXEC="echo #"
export HASHHTML=""
export HASHHTMLOS=""
export ENDHASHHTMLOS=""
export HASHNONHTML="--"
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
export SENDMAILARGS
else
export SENDMAIL="echo #"
export MAILEXEC="mail -s"
export HASHHTML="--"
export HASHHTMLOS="echo #"
export ENDHASHHTMLOS=""
export HASHNONHTML=""
fi
;;
*)
export SENDMAIL="echo #"
export HASHHTML="--"
export HASHHTMLOS="echo #"
export ENDHASHHTMLOS=""
export HASHNONHTML=""
export MAILEXEC="mail -s"
;;
esac
# SQLPLUS HTML SETTINGS:
#export HTMLTITLE="SET MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type=\"text/css\"> table { background: #eee; } -th { font:bold 10pt Arial,Helvetica,sans-serif; color:#b7ceec; background:#151b54; padding: 5px; align:center; } td { font:10pt Arial,Helvetica,sans-serif; color:Blue; background:#f7f7e7; padding: 5px; align:center; } </style>' TABLE \"border='3' align='left'\" ENTMAP OFF"
#export HTMLTABLE="SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type=\"text/css\"> table { background: #eee; } -th { font:bold 10pt Arial,Helvetica,sans-serif; color:#b7ceec; background:#151b54; padding: 5px; align:center; } td { font:10pt Arial,Helvetica,sans-serif; color:Blue; background:#f7f7e7; padding: 5px; align:center; } </style>' TABLE \"border='2' align='left'\" ENTMAP OFF"
echo "Checking CPU Utilization ..."
# Report CPU Utilization if reach >= CPUTHRESHOLD:
OS_TYPE=`uname -s`
CPUUTLLOG=/tmp/CPULOG_DBA_BUNDLE.log
# Getting CPU utilization in last 5 seconds:
case `uname` in
Linux )
export PROGRAM=mpstat
if ! command -v ${PROGRAM} &> /dev/null
then
export PROGRAM=iostat
CPU_REPORT_SECTIONS=`${PROGRAM} -c 1 1 | sed -e 's/,/./g' | tr -s ' ' ';' | sed '/^$/d' | tail -1 | grep ';' -o | wc -l`
if [[ ${CPU_REPORT_SECTIONS} -ge 6 ]]
then
CPU_IDLE=`${PROGRAM} -c ${INTERVAL_SEC} ${COUNT} | sed -e 's/,/./g' | tr -s ' ' ';' | sed '/^$/d' | tail -1| cut -d ";" -f 7`
else
CPU_IDLE=`${PROGRAM} -c ${INTERVAL_SEC} ${COUNT} | sed -e 's/,/./g' | tr -s ' ' ';' | sed '/^$/d' | tail -1| cut -d ";" -f 6`
fi
else
CPU_IDLE=`${PROGRAM} ${INTERVAL_SEC} ${COUNT} | grep 'Average:' | awk '{print $NF}'`
fi
#echo program: $PROGRAM
#echo cpu_idle: $CPU_IDLE
;;
AIX ) CPU_IDLE=`iostat -t $INTERVAL_SEC $NUM_REPORT | sed -e 's/,/./g'|tr -s ' ' ';' | tail -1 | cut -d ";" -f 6`
CPU_COUNT=`lsdev -C|grep Process|wc -l`
;;
SunOS ) CPU_IDLE=`iostat -c $INTERVAL_SEC $NUM_REPORT | tail -1 | awk '{ print $4 }'`
CPU_COUNT=`psrinfo -v|grep "Status of processor"|wc -l`
;;
HP-UX) SAR="/usr/bin/sar"
CPU_COUNT=`lsdev -C|grep Process|wc -l`
if [[ ! -x $SAR ]]; then
echo "sar command is not supported on your environment | CPU Check ignored"; CPU_IDLE=99
else
CPU_IDLE=`/usr/bin/sar ${INTERVAL_SEC} ${COUNT} | grep Average | awk '{ print $5 }'`
fi
;;
*) echo "uname command is not supported on this environment | CPU Check ignored"; CPU_IDLE=99
;;
esac
# Getting Utilized CPU (100-%IDLE):
#CPU_UTL_FLOAT=`echo "scale=2; 100-($CPU_IDLE)"|bc`
CPU_UTL_FLOAT=`awk "BEGIN {print 100-($CPU_IDLE)}"`
# Convert the average from float number to integer:
CPU_UTL=${CPU_UTL_FLOAT%.*}
echo "CPU utilizations is: $CPU_UTL"
if [[ -z ${CPU_UTL} ]]
then
CPU_UTL=1
fi
# Compare the current CPU utilization with the Threshold:
if [[ ${CPU_UTL} -ge ${CPUTHRESHOLD} ]]
then
export COLUMNS=${OSLINESIZE} #Increase the COLUMNS width to display the full output [Default is 167]
echo "*******" > ${MPSTATLOG}
echo "mpstat" >> ${MPSTATLOG}
echo "*******" >> ${MPSTATLOG}
mpstat 1 5|tail -7 >> ${MPSTATLOG}
echo "" > ${VMSTATLOG}
echo "******" >> ${VMSTATLOG}
echo "vmstat" >> ${VMSTATLOG}
echo "******" >> ${VMSTATLOG}
#echo "[If_the_runqueue_number_in_the_(r)_column_exceeds_the_number_of_CPUs_[ ${CPU_COUNT} ]_this_indicates_a_CPU_bottleneck_on_the_system]." >> ${VMSTATLOG}
vmstat 2 5 >> ${VMSTATLOG}
echo "" > ${TOPLOG}
echo "****************" >> ${TOPLOG}
echo "Top10Processes" >> ${TOPLOG}
echo "****************" >> ${TOPLOG}
top -c -b -n 1|head -17|tail -11 >> ${TOPLOG}
echo "" > ${UPTIMELOG}
echo "**********" >> ${UPTIMELOG}
echo "Load_Avg" >> ${UPTIMELOG}
echo "**********" >> ${UPTIMELOG}
uptime >> ${UPTIMELOG}
echo "" >> ${UPTIMELOG}
unset COLUMNS #Set COLUMNS width back to the default value
#ps -eo pcpu,pid,user,args | sort -k 1 -r | head -11 >> ${CPULOG}
cat ${MPSTATLOG} > ${LOGFILE}
cat ${VMSTATLOG} >> ${LOGFILE}
cat ${TOPLOG} >> ${LOGFILE}
cat ${UPTIMELOG} >> ${LOGFILE}
# Convert OS commands output into HTML format:
export FONTSIZE=4
export FONT=Arial
export FONTCOLOR=BLUE
#${HASHHTMLOS} awk 'BEGIN { print "<table borader=1>"} {print "<tr>"; for(i=1;i<=NF;i++)print "<td><FONT COLOR=BLACK FACE="Times New Roman" SIZE=${FONTSIZE}>" $i"</FONT></td>"; print "</tr>"} END{print "</table>" }' ${MPSTATLOG} > ${CPULOGCONV} ${ENDHASHHTMLOS}
${HASHHTMLOS} awk 'BEGIN { print "<table borader=1>"} {print "<tr>"; for(i=1;i<=NF;i++)print "<td><FONT COLOR=BROWN FACE="Times New Roman" SIZE=${FONTSIZE}>" $i"</FONT></td>"; print "</tr>"} END{print "</table>" }' ${MPSTATLOG} > ${CPULOGCONV} ${ENDHASHHTMLOS}
${HASHHTMLOS} awk 'BEGIN { print "<table borader=1>"} {print "<tr>"; for(i=1;i<=NF;i++)print "<td><FONT COLOR=BROWN FACE="Times New Roman" SIZE=${FONTSIZE}>" $i"</FONT></td>"; print "</tr>"} END{print "</table>" }' ${VMSTATLOG} >> ${CPULOGCONV} ${ENDHASHHTMLOS}
${HASHHTMLOS} awk 'BEGIN { print "<table borader=1>"} {print "<tr>"; for(i=1;i<=NF;i++)print "<td><FONT COLOR=BROWN FACE="Times New Roman" SIZE=${FONTSIZE}>" $i"</FONT></td>"; print "</tr>"} END{print "</table>" }' ${TOPLOG} >> ${CPULOGCONV} ${ENDHASHHTMLOS}
${HASHHTMLOS} awk 'BEGIN { print "<table borader=1>"} {print "<tr>"; for(i=1;i<=NF;i++)print "<td><FONT COLOR=BROWN FACE="Times New Roman" SIZE=${FONTSIZE}>" $i"</FONT></td>"; print "</tr>"} END{print "</table>" }' ${UPTIMELOG} >> ${CPULOGCONV} ${ENDHASHHTMLOS}
#${HASHHTMLOS} cat /dev/null > ${CPULOGHTML} ${ENDHASHHTMLOS}
${HASHHTMLOS} cp ${CPULOGCONV} ${LOGFILE}
# Check ACTIVE SESSIONS on DB side:
echo "[CPU Utilization Crossed The Threshold [ ${CPU_UTL}% ]. Sending Email Alert ...]"
for ORACLE_SID in $( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $NF}'|sed -e 's/ora_pmon_//g'|grep -v sed|grep -v "s///g" )
do
export ORACLE_SID
# Getting ORACLE_HOME:
# ###################
ORA_USER=`ps -ef|grep ${ORACLE_SID}|grep pmon|grep -v grep|egrep -v ${EXL_DB}|grep -v "\-MGMTDB"|awk '{print $1}'|tail -1`
USR_ORA_HOME=`grep -i "^${ORA_USER}:" /etc/passwd| cut -f6 -d ':'|tail -1`
# SETTING ORATAB:
if [[ -r /etc/oratab ]]
then
ORATAB=/etc/oratab
export ORATAB
## If OS is Solaris:
elif [[ -r /var/opt/oracle/oratab ]]
then
ORATAB=/var/opt/oracle/oratab
export ORATAB
fi
# ATTEMPT1: Get ORACLE_HOME using pwdx command:
export PGREP=`which pgrep`
export PWDX=`which pwdx`
if [[ -x ${PGREP} ]] && [[ -x ${PWDX} ]]
then
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'`
export PMON_PID
ORACLE_HOME=`pwdx ${PMON_PID} 2>/dev/null|awk '{print $NF}'|sed -e 's/\/dbs//g'`
export ORACLE_HOME
fi
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file:
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
## If OS is Linux:
if [[ -r /etc/oratab ]]
then
ORATAB=/etc/oratab
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'`
export ORACLE_HOME
## If OS is Solaris:
elif [[ -r /var/opt/oracle/oratab ]]
then
ORATAB=/var/opt/oracle/oratab
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'`
export ORACLE_HOME
fi
fi
# ATTEMPT3: If ORACLE_HOME is in /etc/oratab, use dbhome command:
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
ORACLE_HOME=`dbhome "${ORACLE_SID}"`
export ORACLE_HOME
fi
# ATTEMPT4: If ORACLE_HOME is still not found, search for the environment variable: [Less accurate]
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
ORACLE_HOME=`env|grep -i ORACLE_HOME|sed -e 's/ORACLE_HOME=//g'`
export ORACLE_HOME
fi
# ATTEMPT5: If ORACLE_HOME is not found in the environment search user's profile: [Less accurate]
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
ORACLE_HOME=`grep -h 'ORACLE_HOME=\/' ${USR_ORA_HOME}/.bash_profile ${USR_ORA_HOME}/.*profile | perl -lpe'$_ = reverse' |cut -f1 -d'=' | perl -lpe'$_ = reverse'|tail -1`
export ORACLE_HOME
fi
# ATTEMPT6: If ORACLE_HOME is still not found, search for orapipe: [Least accurate]
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
if [[ -x /usr/bin/locate ]]
then
ORACLE_HOME=`locate -i orapipe|head -1|sed -e 's/\/bin\/orapipe//g'`
export ORACLE_HOME
fi
fi
# TERMINATE: If all above attempts failed to get ORACLE_HOME location, EXIT the script:
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
echo "Please export ORACLE_HOME variable in your .bash_profile file under oracle user home directory in order to get this script to run properly"
echo "e.g."
echo "export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1"
exit
fi
export LD_LIBRARY_PATH=${ORACLE_HOME}/lib
# Check Long Running Transactions if CPUDIGMORE=Y:
case ${CPUDIGMORE} in
y|Y|yes|YES|Yes|ON|On|on)
DBCPUDIGMORE=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
set linesize ${SQLLINESIZE}
-- Enable HTML color format:
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
SPOOL ${CPULOGHTML} APPEND
prompt
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT SESSIONS STATUS: [Local Instance | ${ORACLE_SID} ]
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
${HASHNONHTML} PROMPT ***************
${HASHNONHTML} PROMPT SESSIONS STATUS: [Local Instance | ${ORACLE_SID} ]
${HASHNONHTML} PROMPT ***************
set pages 0
select 'ACTIVE: '||count(*) from v\$session where USERNAME is not null and status='ACTIVE';
select 'INACTIVE: '||count(*) from v\$session where USERNAME is not null and status='INACTIVE';
select 'BACKGROUND: '||count(*) from v\$session where USERNAME is null;
select 'ALL: '||count(*) from v\$session;
${HASHNONHTML} PROMPT
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} SET PAGES 0
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='25%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT ACTIVE SESSIONS ON INSTANCE: [ ${ORACLE_SID} ]
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='2' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} SET PAGES 1000
--${HASHHTML} PROMPT
${HASHNONHTML} PROMPT ***************************
${HASHNONHTML} PROMPT ACTIVE SESSIONS ON INSTANCE: [ ${ORACLE_SID} ]
${HASHNONHTML} PROMPT ***************************
set feedback off linesize ${SQLLINESIZE} pages 1000
col event for a24
col "STATUS|WAIT_STATE|TIME_WAITED" for a31
col "USER|OSID|SID,SER|MACHN|MODULE" for a65
col "ST|WA_ST|WAITD|ACT_SINC|LOGIN" for a44
col "SQLID | FULL_SQL_TEXT" for a75
col "CURR_SQLID" for a35
col "I|BLKD_BY" for a9
select
substr(s.USERNAME||'| '||p.spid||'|'||s.sid||','||s.serial#||' |'||substr(s.MACHINE,1,22)||'|'||substr(s.MODULE,1,18),1,65)"USER|OSID|SID,SER|MACHN|MODULE"
,substr(s.status||'|'||w.state||'|'||round(w.WAIT_TIME_MICRO/1000000)||'|'||LAST_CALL_ET||'|'||to_char(LOGON_TIME,'ddMon'),1,44) "ST|WA_ST|WAITD|ACT_SINC|LOGIN"
,substr(w.event,1,24) "EVENT"
--,substr(w.event,1,30)"EVENT",s.SQL_ID ||' | '|| Q.SQL_FULLTEXT "SQLID | FULL_SQL_TEXT"
,s.SQL_ID "CURRENT SQLID"
,s.FINAL_BLOCKING_INSTANCE||'|'||s.FINAL_BLOCKING_SESSION "I|BLKD_BY"
from v\$session s, v\$session_wait w, v\$process p
where s.USERNAME is not null
and s.sid=w.sid
and p.addr = s.paddr
and s.STATUS='ACTIVE'
and w.EVENT NOT IN ('SQL*Net message from client','class slave wait','Streams AQ: waiting for messages in the queue','Streams capture: waiting for archive log'
,'Streams AQ: waiting for time management or cleanup tasks','PL/SQL lock timer','rdbms ipc message')
order by "I|BLKD_BY" desc,"CURRENT SQLID",w.event,"USER|OSID|SID,SER|MACHN|MODULE","ST|WA_ST|WAITD|ACT_SINC|LOGIN" desc;
--${HASHHTML} PROMPT <br>
${HASHNONHTML} PROMPT
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='40%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT Long Running Operations On Database: [ ${ORACLE_SID} ]
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='2' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
${HASHNONHTML} PROMPT ***********************************
${HASHNONHTML} PROMPT Long Running Operations On Instance: [ ${ORACLE_SID} ]
${HASHNONHTML} PROMPT ***********************************
set linesize ${SQLLINESIZE} pages 1000
col OPERATION for a21
col "%DONE" for 999.999
col "STARTED|MIN_ELAPSED|REMAIN" for a30
col MESSAGE for a80
col "USERNAME| SID,SERIAL#" for a26
select USERNAME||'| '||SID||','||SERIAL# "USERNAME| SID,SERIAL#",SQL_ID
--,OPNAME OPERATION
,round(SOFAR/TOTALWORK*100,2) "%DONE"
,to_char(START_TIME,'DD-Mon HH24:MI')||'| '||trunc(ELAPSED_SECONDS/60)||'|'||trunc(TIME_REMAINING/60) "STARTED|MIN_ELAPSED|REMAIN" ,MESSAGE
from v\$session_longops
where SOFAR/TOTALWORK*100 <>'100'
and TOTALWORK <> '0'
order by "STARTED|MIN_ELAPSED|REMAIN" desc, "USERNAME| SID,SERIAL#";
PROMPT
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='42%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT Sessions Active Since More Than 1 Hour On Database: [ ${ORACLE_SID} ]
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='2' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
${HASHNONHTML} PROMPT **************************************************
${HASHNONHTML} PROMPT Sessions Active Since More Than 1 Hour On Instance: [ ${ORACLE_SID} ]
${HASHNONHTML} PROMPT **************************************************
set lines ${SQLLINESIZE}
col module for a30
col DURATION_HOURS for 99999.9
col STARTED_AT for a13
col "USERNAME| SID,SERIAL#" for a30
col "SQL_ID | SQL_TEXT" for a120
select username||'| '||sid ||','|| serial# "USERNAME| SID,SERIAL#",substr(MODULE,1,30) "MODULE", to_char(sysdate-last_call_et/24/60/60,'DD-MON HH24:MI') STARTED_AT,
last_call_et/60/60 "DURATION_HOURS"
--,SQL_ID ||' | '|| (select SQL_FULLTEXT from v\$sql where address=sql_address) "SQL_ID | SQL_TEXT"
,SQL_ID
from v\$session where
username is not null
and module is not null
-- 1 is the number of hours
and last_call_et > 60*60*1
and status = 'ACTIVE';
PROMPT
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT RUNNING JOBS On Database: [ ${ORACLE_SID} ]
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='2' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
${HASHNONHTML} PROMPT ************************
${HASHNONHTML} PROMPT RUNNING JOBS On Instance: [ ${ORACLE_SID} ]
${HASHNONHTML} PROMPT ************************
col INS for 999
col "JOB_NAME|OWNER|SPID|SID" for a55
col ELAPSED_TIME for a17
col CPU_USED for a17
col "WAIT_SEC" for 9999999999
col WAIT_CLASS for a15
col "BLKD_BY" for 9999999
col "WAITED|WCLASS|EVENT" for a45
select j.RUNNING_INSTANCE INS,j.JOB_NAME ||' | '|| j.OWNER||' |'||SLAVE_OS_PROCESS_ID||'|'||j.SESSION_ID"JOB_NAME|OWNER|SPID|SID"
,s.FINAL_BLOCKING_SESSION "BLKD_BY",ELAPSED_TIME,CPU_USED
,substr(s.SECONDS_IN_WAIT||'|'||s.WAIT_CLASS||'|'||s.EVENT,1,45) "WAITED|WCLASS|EVENT",S.SQL_ID
from dba_scheduler_running_jobs j, gv\$session s
where j.RUNNING_INSTANCE=S.INST_ID(+)
and j.SESSION_ID=S.SID(+)
order by INS,"JOB_NAME|OWNER|SPID|SID",ELAPSED_TIME;
SPOOL OFF
EOF
)
BACKUPJOBCOUNTRAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off;
prompt
SELECT count(*) FROM v\$rman_backup_job_details WHERE status like 'RUNNING%';
exit;
EOF
)
BACKUPJOBCOUNT=`echo ${BACKUPJOBCOUNTRAW}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
if [[ ${BACKUPJOBCOUNT} -gt 0 ]]
then
BACKUPJOBOUTPUT=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 0 termout off echo off feedback off linesize ${SQLLINESIZE}
col name for A40
EXEC DBMS_SESSION.set_identifier('${SCRIPT_NAME}');
set feedback off
-- Enable HTML color format:
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
SPOOL ${CPULOGHTML} APPEND
prompt
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='20%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT Running Backups: [ ${ORACLE_SID} ]
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='2' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
${HASHNONHTML} prompt ***************
${HASHNONHTML} Prompt Running Backups: [ ${ORACLE_SID} ]
${HASHNONHTML} prompt ***************
set feedback off linesize ${SQLLINESIZE} pages 1000
col START_TIME for a15
col END_TIME for a15
col TIME_TAKEN_DISPLAY for a10
col INPUT_BYTES_DISPLAY heading "DATA SIZE" for a10
col OUTPUT_BYTES_DISPLAY heading "Backup Size" for a11
col OUTPUT_BYTES_PER_SEC_DISPLAY heading "Speed/s" for a10
col output_device_type heading "Device_TYPE" for a11
SELECT to_char (start_time,'DD-MON-YY HH24:MI') START_TIME, to_char(end_time,'DD-MON-YY HH24:MI') END_TIME, time_taken_display, status,
input_type, output_device_type,input_bytes_display, output_bytes_display, output_bytes_per_sec_display,COMPRESSION_RATIO COMPRESS_RATIO
FROM v\$rman_backup_job_details
WHERE status like 'RUNNING%';
SPOOL OFF
exit;
EOF
)
fi
echo ""
;;
esac
done
echo "CPU utilization has hit the threshold. Reporting the problem."
cat ${CPULOGHTML} >> ${LOGFILE}
export SRV_NAME="`uname -n`"
export MSGSUBJECT="ALERT: CPU Utilization on Server [ ${SRV_NAME} ] has reached [ ${CPU_UTL}% ]"
echo ${MSGSUBJECT}
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
fi
rm -f ${CPUUTLLOG}
rm -f ${CPULOG}
echo "CPU CHECK Completed."
# #########################
# Getting ORACLE_SID:
# #########################
# Exit with sending Alert mail if No DBs are running:
INS_COUNT=$( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|wc -l )
if [[ ${INS_COUNT} -eq 0 ]]
then
echo "[Reported By ${SCRIPT_NAME} Script]" > /tmp/oracle_processes_DBA_BUNDLE.log
echo " " >> /tmp/oracle_processes_DBA_BUNDLE.log
echo "Current running INSTANCES on server [ ${SRV_NAME} ]:" >> /tmp/oracle_processes_DBA_BUNDLE.log
echo "***************************************************" >> /tmp/oracle_processes_DBA_BUNDLE.log
ps -ef|grep -v grep|grep pmon >> /tmp/oracle_processes_DBA_BUNDLE.log
echo " " >> /tmp/oracle_processes_DBA_BUNDLE.log
echo "Current running LISTENERS on server [ ${SRV_NAME} ]:" >> /tmp/oracle_processes_DBA_BUNDLE.log
echo "***************************************************" >> /tmp/oracle_processes_DBA_BUNDLE.log
ps -ef|grep -v grep|grep tnslsnr >> /tmp/oracle_processes_DBA_BUNDLE.log
mail -s "ALARM: No Databases Are Running on Server: ${SRV_NAME} !!!" ${MAIL_LIST} < /tmp/oracle_processes_DBA_BUNDLE.log
rm -f /tmp/oracle_processes_DBA_BUNDLE.log
exit
fi
# Avoid Monitoring Running Services if more than one DB instance is running:
if [[ ${INS_COUNT} -gt 1 ]]
then
export SERVICEMON=""
fi
# #########################
# Setting ORACLE_SID:
# #########################
for ORACLE_SID in $( ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $NF}'|sed -e 's/ora_pmon_//g'|grep -v sed|grep -v "s///g" )
do
export ORACLE_SID
echo ""
echo "[Checking ${ORACLE_SID} Database ...]"
# #########################
# Getting ORACLE_HOME
# #########################
ORA_USER=`ps -ef|grep ${ORACLE_SID}|grep pmon|grep -v grep|egrep -v ${EXL_DB}|grep -v "\-MGMTDB"|awk '{print $1}'|tail -1`
USR_ORA_HOME=`grep -i "^${ORA_USER}:" /etc/passwd| cut -f6 -d ':'|tail -1`
# SETTING ORATAB:
if [[ -r /etc/oratab ]]
then
ORATAB=/etc/oratab
export ORATAB
## If OS is Solaris:
elif [[ -r /var/opt/oracle/oratab ]]
then
ORATAB=/var/opt/oracle/oratab
export ORATAB
fi
# ATTEMPT1: Get ORACLE_HOME using pwdx command:
export PGREP=`which pgrep`
export PWDX=`which pwdx`
if [[ -x ${PGREP} ]] && [[ -x ${PWDX} ]]
then
PMON_PID=`pgrep -lf _pmon_${ORACLE_SID}|awk '{print $1}'`
export PMON_PID
ORACLE_HOME=`pwdx ${PMON_PID} 2>/dev/null|awk '{print $NF}'|sed -e 's/\/dbs//g'`
export ORACLE_HOME
fi
# ATTEMPT2: If ORACLE_HOME not found get it from oratab file:
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
## If OS is Linux:
if [[ -r /etc/oratab ]]
then
ORATAB=/etc/oratab
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'`
export ORACLE_HOME
## If OS is Solaris:
elif [[ -r /var/opt/oracle/oratab ]]
then
ORATAB=/var/opt/oracle/oratab
ORACLE_HOME=`grep -v '^\#' ${ORATAB} | grep -v '^$'| grep -i "^${ORACLE_SID}:" | perl -lpe'$_ = reverse' | cut -f3 | perl -lpe'$_ = reverse' |cut -f2 -d':'`
export ORACLE_HOME
fi
fi
# ATTEMPT3: If ORACLE_HOME is in /etc/oratab, use dbhome command:
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
ORACLE_HOME=`dbhome "${ORACLE_SID}"`
export ORACLE_HOME
fi
# ATTEMPT4: If ORACLE_HOME is still not found, search for the environment variable: [Less accurate]
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
ORACLE_HOME=`env|grep -i ORACLE_HOME|sed -e 's/ORACLE_HOME=//g'`
export ORACLE_HOME
fi
# ATTEMPT5: If ORACLE_HOME is not found in the environment search user's profile: [Less accurate]
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
ORACLE_HOME=`grep -h 'ORACLE_HOME=\/' ${USR_ORA_HOME}/.bash_profile ${USR_ORA_HOME}/.*profile | perl -lpe'$_ = reverse' |cut -f1 -d'=' | perl -lpe'$_ = reverse'|tail -1`
export ORACLE_HOME
fi
# ATTEMPT6: If ORACLE_HOME is still not found, search for orapipe: [Least accurate]
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
if [[ -x /usr/bin/locate ]]
then
ORACLE_HOME=`locate -i orapipe|head -1|sed -e 's/\/bin\/orapipe//g'`
export ORACLE_HOME
fi
fi
# TERMINATE: If all above attempts failed to get ORACLE_HOME location, EXIT the script:
if [[ ! -r ${ORACLE_HOME}/bin/sqlplus ]]
then
echo "Please export ORACLE_HOME variable in your .bash_profile file under oracle user home directory in order to get this script to run properly"
echo "e.g."
echo "export ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1"
mail -s "dbalarm script on Server [ ${SRV_NAME} ] failed to locate ORACLE_HOME for SID [ ${ORACLE_SID} ], Please export ORACLE_HOME variable in your .bash_profile file under oracle user home directory" ${MAIL_LIST} < /dev/null
exit
fi
# #############################
# Getting hostname in lowercase:
# #############################
HOSTNAMELOWER=$( echo "`hostname --short`"| tr '[A-Z]' '[a-z]' )
export HOSTNAMELOWER
# ########################
# Getting GRID_HOME:
# ########################
CHECK_OCSSD=`ps -ef|grep 'ocssd.bin'|grep -v grep|wc -l`
CHECK_CRSD=`ps -ef|grep 'crsd.bin'|grep -v grep|wc -l`
if [[ ${CHECK_OCSSD} -gt 0 ]]
then
GRID_HOME=`ps -ef|grep 'ocssd.bin'|grep -v grep|awk '{print $NF}'|sed -e 's/\/bin\/ocssd.bin//g'|grep -v sed|grep -v "//g"|tail -1`
export GRID_HOME
if [[ ! -d ${GRID_HOME} ]]
then
ASM_INSTANCE_NAME=`ps -ef|grep pmon|grep -v grep|grep asm_pmon_|awk '{print $NF}'|sed -e 's/asm_pmon_//g'|grep -v sed|grep -v "s///g"|tail -1`
GRID_HOME=`dbhome ${ASM_INSTANCE_NAME}`
export GRID_HOME
fi
# ########################
# Getting GRID_BASE:
# ########################
# Locating GRID_BASE:
GRID_BASE=`cat ${GRID_HOME}/crs/install/crsconfig_params|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'`
export GRID_BASE
if [[ ! -d ${GRID_BASE} ]]
then
GRID_BASE=`cat ${GRID_HOME}/crs/utl/appvipcfg|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'`
export GRID_BASE
fi
if [[ ! -d ${GRID_BASE} ]]
then
GRID_BASE=`cat ${GRID_HOME}/install/envVars.properties|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'`
export GRID_BASE
fi
fi
# #########################
# Variables:
# #########################
export PATH=${PATH}:${ORACLE_HOME}/bin
export LOG_DIR=${USR_ORA_HOME}/BUNDLE_Logs
mkdir -p ${LOG_DIR}
chown -R ${ORA_USER} ${LOG_DIR}
chmod -R go-rwx ${LOG_DIR}
if [[ ! -w ${LOG_DIR} ]]
then
mkdir -p /tmp/BUNDLE_Logs
export LOG_DIR=/tmp/BUNDLE_Logs
chown -R ${ORA_USER} ${LOG_DIR}
chmod -R go-rwx ${LOG_DIR}
fi
touch ${LOG_DIR}/dbalarm.part.log
export LOGFILE=${LOG_DIR}/dbalarm.part.log
# #########################
# HTML Preparation:
# #########################
case ${HTMLENABLE} in
y|Y|yes|YES|Yes|ON|On|on)
if [[ -x /usr/sbin/sendmail ]]
then
export SENDMAIL="/usr/sbin/sendmail -t"
export MAILEXEC="echo #"
export HASHHTML=""
export HASHNONHTML="--"
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
export SENDMAILARGS
else
export SENDMAIL="echo #"
export MAILEXEC="mail -s"
export HASHHTML="--"
export HASHNONHTML=""
fi
;;
*)
export SENDMAIL="echo #"
export HASHHTML="--"
export HASHNONHTML=""
export MAILEXEC="mail -s"
;;
esac
#export HTMLTITLE="SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type=\"text/css\"> table { background: #eee; } -th { font:bold 10pt Arial,Helvetica,sans-serif; color:#b7ceec; background:#151b54; padding: 5px; align:center; } td { font:10pt Arial,Helvetica,sans-serif; color:Blue; background:#f7f7e7; padding: 5px; align:center; } </style>' TABLE \"border='3' align='left'\" ENTMAP OFF"
#export HTMLTABLE="SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type=\"text/css\"> table { background: #eee; } -th { font:bold 10pt Arial,Helvetica,sans-serif; color:#b7ceec; background:#151b54; padding: 5px; align:center; } td { font:10pt Arial,Helvetica,sans-serif; color:Blue; background:#f7f7e7; padding: 5px; align:center; } </style>' TABLE \"border='2' align='left'\" ENTMAP OFF"
# ##########################
# Neutralize login.sql file: [Bug Fix]
# ##########################
# Existance of login.sql file under Oracle user Linux home directory eliminates many functions during the execution of this script via crontab:
if [[ -r ${USR_ORA_HOME}/login.sql ]]
then
echo "login.sql file found and will be neutralized."
mv ${USR_ORA_HOME}/login.sql ${USR_ORA_HOME}/login.sql_NeutralizedBy${SCRIPT_NAME}
fi
# ########################
# Getting ORACLE_BASE:
# ########################
# Get ORACLE_BASE from user's profile if it EMPTY:
if [[ ! -d "${ORACLE_BASE}" ]]
then
ORACLE_BASE=`cat ${ORACLE_HOME}/install/envVars.properties|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'`
export ORACLE_BASE
fi
if [[ ! -d "${ORACLE_BASE}" ]]
then
ORACLE_BASE=`grep -h 'ORACLE_BASE=\/' ${USR_ORA_HOME}/.bash* ${USR_ORA_HOME}/.*profile | perl -lpe'$_ = reverse' |cut -f1 -d'=' | perl -lpe'$_ = reverse'|tail -1`
export ORACLE_BASE
fi
# #########################
# Getting DB_NAME:
# #########################
DB_NAME_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off lines 1000;
prompt
SELECT name from v\$database;
exit;
EOF
)
# Getting DB_NAME in Uppercase & Lowercase:
DB_NAME_UPPER=`echo ${DB_NAME_RAW}| perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
DB_NAME_LOWER=$( echo "${DB_NAME_UPPER}" | tr -s '[:upper:]' '[:lower:]' )
export DB_NAME_UPPER
export DB_NAME_LOWER
# #########################
# Getting DB_UNQ_NAME:
# #########################
VAL121=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off;
prompt
select value from v\$parameter where name='db_unique_name';
exit;
EOF
)
# Getting DB_NAME in Uppercase & Lowercase:
DB_UNQ_NAME=`echo ${VAL121}| perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
export DB_UNQ_NAME
# In case DB_UNQ_NAME variable is empty then use DB_NAME instead:
case ${DB_UNQ_NAME} in
'') DB_UNQ_NAME=${DB_NAME}; export DB_UNQ_NAME;;
esac
if [[ -d ${ORACLE_BASE}/diag/rdbms/${DB_NAME_UPPER} ]]
then
DB_NAME=${DB_NAME_UPPER}
fi
if [[ -d ${ORACLE_BASE}/diag/rdbms/${DB_NAME_LOWER} ]]
then
DB_NAME=${DB_NAME_LOWER}
fi
if [[ -d ${ORACLE_BASE}/diag/rdbms/${DB_UNQ_NAME} ]]
then
DB_NAME=${DB_UNQ_NAME}
fi
export DB_NAME
# ###################
# Getting DB Version:
# ###################
echo "Checking DB Version"
VAL311=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off lines 1000;
prompt
select version from v\$instance;
exit;
EOF
)
DB_VER=`echo ${VAL311}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
# #####################
# Getting DB Block Size:
# #####################
echo "Checking DB Block Size"
VAL302=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off lines 1000;
prompt
select value from v\$parameter where name='db_block_size';
exit;
EOF
)
blksize=`echo ${VAL302}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
# #####################
# Getting DB ROLE:
# #####################
echo "Checking DB Role"
VAL312=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off lines 1000;
prompt
--Remove all spaces from the output:
select replace(DATABASE_ROLE,' ','') from v\$database;
--select DATABASE_ROLE from v\$database;
exit;
EOF
)
DB_ROLE=`echo ${VAL312}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
case ${DB_ROLE} in
PRIMARY) export DB_ROLE_ID=0 ;;
PHYSICALSTANDBY) export DB_ROLE_ID=1
# Disable the reporting of BLOCKED Sessions if the DB Role is not PRIMARY:
export BLOCKTHRESHOLD=100000
;;
esac
# ######################################
# Check Flash Recovery Area Utilization:
# ######################################
VAL318=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off lines 1000;
prompt
select value from v\$parameter where name='db_recovery_file_dest';
exit;
EOF
)
FRA_LOC=`echo ${VAL318}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
# If FRA is configured, check the its utilization:
if [[ ! -z ${FRA_LOC} ]]
then
FRACHK1=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 0 termout off echo off feedback off linesize ${SQLLINESIZE}
col name for A40
SELECT ROUND((SPACE_USED - SPACE_RECLAIMABLE)/SPACE_LIMIT * 100, 1) FROM V\$RECOVERY_FILE_DEST;
exit;
EOF
)
FRAPRCUSED=`echo ${FRACHK1}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
# Convert FRAPRCUSED from float number to integer:
FRAPRCUSED=${FRAPRCUSED%.*}
if [[ -z ${FRAPRCUSED} ]]
then
FRAPRCUSED=1
fi
# If FRA %USED >= the defined threshold then send an email alert:
INTEG='^[0-9]+$'
# Verify that FRAPRCUSED value is a valid number:
if [[ ${FRAPRCUSED} =~ ${INTEG} ]]
then
echo "Checking FRA For [ ${ORACLE_SID} ] ..."
if [[ ${FRAPRCUSED} -ge ${FRATHRESHOLD} ]]
then
FRA_RPT=${LOG_DIR}/FRA_REPORT.log
FRACHK2=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set linesize ${SQLLINESIZE}
${HASHHTML} set linesize 300
${HASHNONHTML} col name for a100
${HASHNONHTML} col TOTAL_MB for 99999999999999999
${HASHNONHTML} col FREE_MB for 99999999999999999
-- Enable HTML color format:
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
SPOOL ${FRA_RPT}
${HASHHTML} set pages 0
${HASHHTML} select '<b>'||'Reported By ${SCRIPT_NAME} Script'||'</b>' from dual;
${HASHHTML} set pages 1000
${HASHNONHTML} PROMPT [Reported By ${SCRIPT_NAME} Script]
${HASHNONHTML} PROMPT
${HASHNONHTML} PROMPT [FLASH RECOVERY AREA Utilization]
${HASHNONHTML} PROMPT
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <p> <table border='3' bordercolor='#E67E22' width='30%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT FLASH RECOVERY AREA Utilization
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
col NAME for a30
SELECT NAME,SPACE_LIMIT/1024/1024 AS TOTAL_MB,(SPACE_LIMIT - SPACE_USED + SPACE_RECLAIMABLE)/1024/1024 AS FREE_MB,
ROUND((SPACE_USED - SPACE_RECLAIMABLE)/SPACE_LIMIT * 100, 1) AS "%FULL"
FROM V\$RECOVERY_FILE_DEST;
${HASHNONHTML} PROMPT
${HASHNONHTML} PROMPT [FRA COMPONENTS]
${HASHNONHTML} PROMPT
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='22%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT FRA COMPONENTS
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
select * from v\$flash_recovery_area_usage;
${HASHNONHTML} PROMPT
${HASHNONHTML} PROMPT [Exist Restore Points: <You may need to drop>]
${HASHNONHTML} PROMPT
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='22%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT Exist Restore Points
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
col SCN for 999999999999999999
col time for a35
col RESTORE_POINT_TIME for a35
col name for a40
select NAME,SCN,TIME,STORAGE_SIZE/1024/1024 STORAGE_SIZE_MB from v\$restore_point;
spool off
exit;
EOF
)
# Check if FLASHBACK_RESET flag is enabled:
# This logfile will be used for logging the reset of FLASHBACK:
touch ${LOG_DIR}/resetflashback_${ORACLE_SID}.log
export FLBLOG=${LOG_DIR}/resetflashback_${ORACLE_SID}.log
case ${FLASHBACK_RESET} in
Y|y|YES|Yes|yes|ON|On|on)
# Check if FLASHBACK DATABASE feature is turned ON:
FLASHBACK_ON_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off lines 1000;
prompt
select count(*) from v\$database where flashback_on='YES';
exit;
EOF
)
FLASHBACK_ON=`echo ${FLASHBACK_ON_RAW}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
# IF the FLASHBACK feature is enabled then proceed with resetting it:
case ${FLASHBACK_ON} in
1)
# Check if MRP process is running:
MRPSTATUSRAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 0 feedback off echo off;
prompt
select count(*) from GV\$MANAGED_STANDBY where PROCESS='MRP0' and STATUS='APPLYING_LOG';
exit;
EOF
)
MRPSTATUS=`echo ${MRPSTATUSRAW}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
# If the database is PHYSICAL STANDBY and in RECOVERY mode, stop and start the recovery before and after turning FLASHBACK ON"
if [[ "${DB_ROLE_ID}" -eq 1 && "${MRPSTATUS}" -eq 1 ]]
then
export RECOVERY_STOP="RECOVER MANAGED STANDBY DATABASE CANCEL;"
export RECOVERY_START="RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE NODELAY DISCONNECT;"
export STANDBY_TAG=" ON PHYSICAL STANDBY"
else
export RECOVERY_STOP=""
export RECOVERY_START=""
export STANDBY_TAG=""
fi
# TURN FLASHBACK DATABASE OFF & ON:
FLASHBACKRESETRAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
SPOOL ${FLBLOG}
PROMPT TURNING OFF FLASHBACK ${STANDBY_TAG}...
exec dbms_system.ksdwrt(3,'SCRIPT: ${SCRIPT_NAME} EXECUTING: TURNING OFF FLASHBACK TO FREE UP FRA');
ALTER DATABASE FLASHBACK OFF;
PROMPT TURNING ON FLASHBACK ${STANDBY_TAG}...
exec dbms_system.ksdwrt(3,'SCRIPT: ${SCRIPT_NAME} EXECUTING: TURNING ON FLASHBACK');
${RECOVERY_STOP}
ALTER DATABASE FLASHBACK ON;
${RECOVERY_START}
SPOOL OFF
exit;
EOF
)
FLASHBACK_CHK_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off lines 1000;
prompt
select count(*) from v\$database where flashback_on='YES';
exit;
EOF
)
FLASHBACK_CHK=`echo ${FLASHBACK_CHK_RAW}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
if [[ "${FLASHBACK_CHK}" -eq 0 ]]
then
cat ${FLBLOG} > ${LOGFILE}
export MSGSUBJECT="WARNING: FLASHBACK RESET procedure failed to RE-ENABLE FLASHBACK feature on database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]"
echo ${MSGSUBJECT}
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
fi
export FLB_RESET_MSG=" | FLASHBACK RESET PROCEDURE EXECUTED${STANDBY_TAG}"
;;
esac
;;
esac
echo "FRA has reached ${FRAPRCUSED}%${FLB_RESET_MSG}. Reporting the problem."
cat ${FRA_RPT} > ${LOGFILE}
cat ${FLBLOG} >> ${LOGFILE}
export MSGSUBJECT="ALERT: FRA has reached ${FRAPRCUSED}%${FLB_RESET_MSG} on database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]"
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${FRA_RPT}
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
fi
fi
rm -f ${FRAFULL}
rm -f ${FRA_RPT}
fi
# ################################
# Check ASM Diskgroup Utilization:
# ################################
echo "Checking ASM Diskgroup Utilization ..."
VAL314=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off;
prompt
select count(*) from v\$asm_diskgroup;
exit;
EOF
)
ASM_GROUP_COUNT=`echo ${VAL314}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
# If ASM DISKS Are Exist, Check the size utilization:
if [[ ${ASM_GROUP_COUNT} -gt 0 ]]
then
echo "Checking ASM on [ ${ORACLE_SID} ] ..."
ASM_UTL=${LOG_DIR}/ASM_UTILIZATION.log
ASMCHK1=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 0 termout off echo off feedback off linesize ${SQLLINESIZE}
col name for A40
spool ${ASM_UTL}
select name,ROUND((1-(free_mb / total_mb))*100, 2) "%FULL" from v\$asm_diskgroup;
select name,ROUND((1-(free_mb / total_mb))*100, 2) "%FULL" from v\$asm_diskgroup;
spool off
exit;
EOF
)
ASMFULL=${LOG_DIR}/asm_full.log
#cat ${ASM_UTL}|awk '{ print $1" "$NF }'| while read OUTPUT3
cat ${ASM_UTL}|egrep -v ${EXL_DISK_GROUP}|awk '{ print $1" "$NF }'| while read OUTPUT3
do
ASMPRCUSED=`echo ${OUTPUT3}|awk '{print $NF}'`
ASMDGNAME=`echo ${OUTPUT3}|awk '{print $1}'`
echo "[Reported By ${SCRIPT_NAME} Script]" > ${ASMFULL}
echo " " >> ${ASMFULL}
echo "ASM_DISK_GROUP %USED" >> ${ASMFULL}
echo "---------------------- --------------" >> ${ASMFULL}
echo "${ASMDGNAME} ${ASMPRCUSED}%" >> ${ASMFULL}
# Convert ASMPRCUSED from float number to integer:
ASMPRCUSED=${ASMPRCUSED%.*}
if [[ -z ${ASMPRCUSED} ]]
then
ASMPRCUSED=1
fi
# If ASM %USED >= the defined threshold send an email for each DISKGROUP:
if [[ ${ASMPRCUSED} -ge ${ASMTHRESHOLD} ]]
then
ASM_RPT=${LOG_DIR}/ASM_REPORT.log
ASMCHK2=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set linesize ${SQLLINESIZE} pages 1000
col name for a35
-- Enable HTML color format:
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
SPOOL ${ASM_RPT}
${HASHHTML} set pages 0
${HASHHTML} select '<b>'||'Reported By ${SCRIPT_NAME} Script'||'</b>' from dual;
${HASHHTML} set pages 1000
${HASHNONHTML} PROMPT [Reported By ${SCRIPT_NAME} Script]
${HASHNONHTML} PROMPT
${HASHNONHTML} prompt ASM DISK GROUPS:
${HASHNONHTML} PROMPT ***************
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <p> <table border='3' bordercolor='#E67E22' color='#FFFFFF' width='25%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT ASM DISK GROUPS
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
select name,total_mb,free_mb,ROUND((1-(free_mb / total_mb))*100, 2) "%FULL" from v\$asm_diskgroup where name='${ASMDGNAME}';
spool off
exit;
EOF
)
echo "ASM DISK GROUP [ ${ASMDGNAME} ] has reached ${ASMPRCUSED}%. Reporting the problem."
export MSGSUBJECT="ALERT: ASM DISK GROUP [ ${ASMDGNAME} ] has reached ${ASMPRCUSED}% on database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]"
cat ${ASM_RPT} > ${LOGFILE}
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
fi
done
rm -f ${ASMFULL}
rm -f ${ASM_RPT}
fi
# #########################
# Tablespaces Size Check:
# #########################
# Workaround Bugs [28821847 & 24445571] which conceal UNDO Tablespace details on dba_tablespace_usage_metrics on 12c+:
case ${DB_VER} in
12|18|19) export BUG24445571="";;
*) export BUG24445571="--";;
esac
echo "Checking TABLESPACES on [ ${ORACLE_SID} ] ..."
if [[ ${DB_VER} -gt 10 ]]
then
# If The Database Version is 11g Onwards:
TBSCHK=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 0 termout off echo off feedback off
col tablespace_name for A25
col y for 999999999 heading 'Total_MB'
col z for 999999999 heading 'Used_MB'
col bused for 999.99 heading '%Used'
spool ${LOG_DIR}/tablespaces_DBA_BUNDLE.log
select tablespace_name,
(used_space*$blksize)/(1024*1024) Used_MB,
(tablespace_size*$blksize)/(1024*1024) Total_MB,
used_percent "%Used"
from dba_tablespace_usage_metrics
${BUG24445571} where tablespace_name not like '%UNDO%' union all SELECT /*+ RULE */ a.tablespace_name,Used_MB,Total_MB,round ((Used_MB*100)/Total_MB,2) "%Used" FROM ( SELECT SUM (maxbytes) / 1024 / 1024 Total_MB, b.tablespace_name FROM dba_data_files a, dba_tablespaces b WHERE a.tablespace_name = b.tablespace_name AND b.contents like 'UNDO' GROUP BY b.tablespace_name) a, ( SELECT c.tablespace_name, SUM (bytes) / 1024 / 1024 Used_MB FROM DBA_UNDO_EXTENTS c WHERE status <> 'EXPIRED' GROUP BY c.tablespace_name) b WHERE a.tablespace_name = b.tablespace_name
/
spool off
exit;
EOF
)
else
# If The Database Version is 10g Backwards:
# Check if AUTOEXTEND OFF (MAXSIZE=0) is set for any of the datafiles divide by ALLOCATED size else divide by MAXSIZE:
VAL33=$(${ORACLE_HOME}/bin/sqlplus -S '/ as sysdba' << EOF
set pages 0 feedback off;
SELECT COUNT(*) FROM DBA_DATA_FILES WHERE MAXBYTES=0;
exit;
EOF
)
VAL44=`echo ${VAL33}| awk '{print $NF}'`
case ${VAL44} in
"0") CALCPERCENTAGE1="((sbytes - fbytes)*100 / MAXSIZE) bused " ;;
*) CALCPERCENTAGE1="round(((sbytes - fbytes) / sbytes) * 100,2) bused " ;;
esac
VAL55=$(${ORACLE_HOME}/bin/sqlplus -S '/ as sysdba' << EOF
set pages 0 feedback off;
SELECT COUNT(*) FROM DBA_TEMP_FILES WHERE MAXBYTES=0;
exit;
EOF
)
VAL66=`echo ${VAL55}| awk '{print $NF}'`
case ${VAL66} in
"0") CALCPERCENTAGE2="((sbytes - fbytes)*100 / MAXSIZE) bused " ;;
*) CALCPERCENTAGE2="round(((sbytes - fbytes) / sbytes) * 100,2) bused " ;;
esac
TBSCHK=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 0 termout off echo off feedback off
col tablespace for A25
col "MAXSIZE MB" format 9999999
col x for 999999999 heading 'Allocated MB'
col y for 999999999 heading 'Free MB'
col z for 999999999 heading 'Used MB'
col bused for 999.99 heading '%Used'
--bre on report
spool ${LOG_DIR}/tablespaces_DBA_BUNDLE.log
select a.tablespace_name tablespace,bb.MAXSIZE/1024/1024 "MAXSIZE MB",sbytes/1024/1024 x,fbytes/1024/1024 y,
(sbytes - fbytes)/1024/1024 z,
$CALCPERCENTAGE1
--round(((sbytes - fbytes) / sbytes) * 100,2) bused
--((sbytes - fbytes)*100 / MAXSIZE) bused
from (select tablespace_name,sum(bytes) sbytes from dba_data_files group by tablespace_name ) a,
(select tablespace_name,sum(bytes) fbytes,count(*) ext from dba_free_space group by tablespace_name) b,
(select tablespace_name,sum(MAXBYTES) MAXSIZE from dba_data_files group by tablespace_name) bb
--where a.tablespace_name in (select tablespace_name from dba_tablespaces)
where a.tablespace_name = b.tablespace_name (+)
and a.tablespace_name = bb.tablespace_name
and round(((sbytes - fbytes) / sbytes) * 100,2) > 0
UNION ALL
select c.tablespace_name tablespace,dd.MAXSIZE/1024/1024 MAXSIZE_GB,sbytes/1024/1024 x,fbytes/1024/1024 y,
(sbytes - fbytes)/1024/1024 obytes,
$CALCPERCENTAGE2
from (select tablespace_name,sum(bytes) sbytes
from dba_temp_files group by tablespace_name having tablespace_name in (select tablespace_name from dba_tablespaces)) c,
(select tablespace_name,sum(bytes_free) fbytes,count(*) ext from v\$temp_space_header group by tablespace_name) d,
(select tablespace_name,sum(MAXBYTES) MAXSIZE from dba_temp_files group by tablespace_name) dd
--where c.tablespace_name in (select tablespace_name from dba_tablespaces)
where c.tablespace_name = d.tablespace_name (+)
and c.tablespace_name = dd.tablespace_name
order by tablespace;
select tablespace_name,null,null,null,null,null||'100.00' from dba_data_files minus select tablespace_name,null,null,null,null,null||'100.00' from dba_free_space;
spool off
exit;
EOF
)
fi
TBSLOG=${LOG_DIR}/tablespaces_DBA_BUNDLE.log
TBSFULL=${LOG_DIR}/full_tbs.log
#cat ${TBSLOG}|awk '{ print $1" "$NF }'| while read OUTPUT2
cat ${TBSLOG}|egrep -v ${EXL_TBS} |awk '{ print $1" "$NF }'| while read OUTPUT2
do
PRCUSED=`echo ${OUTPUT2}|awk '{print $NF}'`
TBSNAME=`echo ${OUTPUT2}|awk '{print $1}'`
echo "[Reported By ${SCRIPT_NAME} Script]" > ${TBSFULL}
echo " " >> ${TBSFULL}
echo "Tablespace_name %USED" >> ${TBSFULL}
echo "---------------------- --------------" >> ${TBSFULL}
# echo ${OUTPUT2}|awk '{print $1" "$NF}' >> ${TBSFULL}
echo "${TBSNAME} ${PRCUSED}%" >> ${TBSFULL}
# Convert PRCUSED from float number to integer:
PRCUSED=${PRCUSED%.*}
if [[ -z ${PRCUSED} ]]
then
PRCUSED=1
fi
# If the tablespace %USED >= the defined threshold send an email for each tablespace:
if [[ ${PRCUSED} -ge ${TBSTHRESHOLD} ]]
then
echo "TABLESPACE [ ${TBSNAME} ] reached ${PRCUSED}%. Reporting the problem."
mail -s "ALERT: TABLESPACE [ ${TBSNAME} ] reached ${PRCUSED}% on database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${TBSFULL}
fi
done
rm -f ${LOG_DIR}/tablespaces_DBA_BUNDLE.log
rm -f ${LOG_DIR}/full_tbs.log
# ############################################
# Checking Monitored Services:
# ############################################
#case ${DB_NAME} in
#ORCL)
if [[ -x ${SERVICEMON} ]]
then
echo "Checking Monitored Services on [ ${ORACLE_SID} ] ..."
VAL_SRVMON_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 0 feedback off;
prompt
select count(*) from V\$ACTIVE_SERVICES where lower(NAME) in (${SERVICEMON}) or upper(NAME) in (${SERVICEMON});
exit;
EOF
)
ONLINE_SERVICES_COUNT=`echo ${VAL_SRVMON_RAW}| awk '{print $NF}'`
#echo "Number of ONLINE Services is: $ONLINE_SERVICES_COUNT"
MONITORED_SERVICES_COUNT=`echo "${SERVICEMON}" | awk -F "," '{print NF}'`
#echo "Number of MONITORED Services is: $MONITORED_SERVICES_COUNT"
DOWN_SERVICES_COUNT=`expr ${MONITORED_SERVICES_COUNT} - ${ONLINE_SERVICES_COUNT}`
#echo "Number of OFFLINE Services is: $DOWN_SERVICES_COUNT"
if [[ ${DOWN_SERVICES_COUNT} -gt 0 ]]
then
VAL_SRVNAME_RAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 0 feedback off;
prompt
select name from dba_services minus select name from v\$ACTIVE_SERVICES;
exit;
EOF
)
OFFLINE_SRVNAME=`echo ${VAL_SRVNAME_RAW}| awk '{print $NF}'`
VAL_SRVMON_EMAIL=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set linesize 160 pages 1000 echo off feedback off
-- Enable HTML color format:
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
spool ${LOG_DIR}/current_running_services.log
${HASHHTML} set pages 0
${HASHHTML} select '<b>'||'Reported By ${SCRIPT_NAME} Script'||'</b>' from dual;
${HASHHTML} set pages 1000
${HASHNONHTML} PROMPT [Reported By ${SCRIPT_NAME} Script]
${HASHNONHTML} PROMPT
${HASHNONHTML} PROMPT
${HASHNONHTML} PROMPT SERVICE [ ${OFFLINE_SRVNAME} ] REPORTED OFFLINE.
${HASHNONHTML} PROMPT
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <p> <table border='3' width='30%' bordercolor='#E67E22' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT SERVICE [ ${OFFLINE_SRVNAME} ] REPORTED OFFLINE
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
select name OFFLINE_SERVICES from dba_services minus select name from v\$active_services;
${HASHHTML} PROMPT <br>
select INST_ID,NAME ONLINE_SERVICE_NAME from GV\$ACTIVE_SERVICES where NAME not in ('SYS\$BACKGROUND','SYS\$USERS') order by ONLINE_SERVICE_NAME;
spool off
exit;
EOF
)
echo "Service Down detected [ ${OFFLINE_SRVNAME} ]. Reporting the problem."
export MSGSUBJECT="ALERT: SERVICE [ ${OFFLINE_SRVNAME} ] Detected OFFLINE on Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]"
cat ${LOG_DIR}/current_running_services.log > ${LOGFILE}
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOG_DIR}/current_running_services.log
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
rm -f ${LOG_DIR}/current_running_services.log
fi
fi
#;;
#esac
# ######################################
# Checking RMAN In-Complete Backup Jobs:
# ######################################
case ${CHKRMANBKP} in
y|Y|yes|YES|Yes|ON|On|on)
echo "Checking FAILED RMAN Backup Jobs In The Last ${LAST_MIN_BKP_CHK} Minutes ..."
RMANBKPCNTRAW=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off;
prompt
select count(*) from v\$rman_backup_job_details where end_time > sysdate - (${LAST_MIN_BKP_CHK}/1440) and status in ('FAILED','COMPLETED WITH ERRORS');
exit;
EOF
)
RMANBKPCNT=`echo ${RMANBKPCNTRAW}|perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|cut -f1 -d '.'`
if [[ ${RMANBKPCNT} -gt 0 ]]
then
echo "FAILED RMAN Backup Jobs Detected."
RMANBKPFAILLOG=${LOG_DIR}/RMANBKPFAILREPORT.log
RMANBKPCHK=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 1000 termout off echo off feedback off linesize ${SQLLINESIZE}
-- Enable HTML color format:
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
spool ${RMANBKPFAILLOG}
${HASHNONHTML} PROMPT [FAILED BACKUP REPORT IN THE LAST ${LAST_MIN_BKP_CHK} Minutes]
${HASHNONHTML} PROMPT
${HASHHTML} set pages 0
${HASHHTML} select '<b>'||'Reported By ${SCRIPT_NAME} Script'||'</b>' from dual;
${HASHHTML} set pages 1000
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <p> <table border='3' bordercolor='#E67E22' width='35%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT FAILED BACKUP REPORT IN THE LAST ${LAST_MIN_BKP_CHK} Minutes
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
col START_TIME for a15
col END_TIME for a15
col TIME_TAKEN_DISPLAY for a10
col INPUT_BYTES_DISPLAY heading "DATA SIZE" for a10
col OUTPUT_BYTES_DISPLAY heading "Backup Size" for a11
col OUTPUT_BYTES_PER_SEC_DISPLAY heading "Speed/s" for a10
col output_device_type heading "Device_TYPE" for a11
SELECT to_char (start_time,'DD-MON-YY HH24:MI') START_TIME, to_char(end_time,'DD-MON-YY HH24:MI') END_TIME, time_taken_display, status,
input_type, output_device_type,input_bytes_display, output_bytes_display, output_bytes_per_sec_display,COMPRESSION_RATIO COMPRESS_RATIO
FROM v\$rman_backup_job_details
WHERE end_time > sysdate - (${LAST_MIN_BKP_CHK}/1440)
and status in ('FAILED','COMPLETED WITH ERRORS');
spool off
exit;
EOF
)
echo "FAILED RMAN Backup Detected. Reporting the problem."
cat ${RMANBKPFAILLOG} > ${LOGFILE}
export MSGSUBJECT="Info: FAILED RMAN Backup Detected on Database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]"
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${RMANBKPFAILLOG}
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
fi
esac
# ###############################################
# Checking ACTIVE SESSIONS COUNT ON THE DATABASE:
# ###############################################
# Verify if ACTIVE_SESSIONS_THRES is set to a number:
INTEG='^[0-9]+$'
if [[ ${ACTIVE_SESSIONS_THRES} =~ ${INTEG} ]]
then
# Verify if ACTIVE_SESSIONS_THRES is set to value > 0:
if [[ ${ACTIVE_SESSIONS_THRES} -gt 0 ]]
then
echo "Checking The Number of ACTIVE SESSIONS ..."
ACTVSESSCOUNTRAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
select count(*) from v\$session where status='ACTIVE' and wait_class <>'Idle' and last_call_et > ${ACTIVE_TIME};
exit;
EOF
)
ACTVSESSCOUNT=`echo ${ACTVSESSCOUNTRAW} | awk '{print $NF}'`
echo ACTVSESSCOUNT is: $ACTVSESSCOUNT
if [[ ${ACTVSESSCOUNT} -ge ${ACTIVE_SESSIONS_THRES} ]]
then
ACTVSESSRAW=$(${ORACLE_HOME}/bin/sqlplus -s '/ as sysdba' << EOF
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='ACTIVE SESSIONS:'> <tr> <th scope="col">
${HASHHTML} PROMPT ACTIVE SESSIONS on Instance [ ${ORACLE_SID} ]:
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000 lines 300
${HASHNONHTML} set linesize ${SQLLINESIZE} pages 1000
${HASHNONHTML} col "ST|WAITD|ACT_SINC|LOGIN" for a35
${HASHNONHTML} col "USER|SID,SER|MACHIN|MODUL" for a64
${HASHNONHTML} col "EVENT" for a24
${HASHNONHTML} col "I|BLK_BY" for a9
${HASHNONHTML} col "CURRENT SQL" for a14
${HASHNONHTML} PROMPT
${HASHNONHTML} PROMPT *************************************
${HASHNONHTML} PROMPT ACTIVE SESSIONS ON INSTANCE [ ${ORACLE_SID} ]:
${HASHNONHTML} PROMPT *************************************
spool ${LOG_DIR}/Active_Sessions.log
select
substr(s.USERNAME||'| '||s.sid||','||s.serial#||' |'||substr(s.MACHINE,1,20)||'|'||substr(s.MODULE,1,18),1,64)"USER|SID,SER|MACHIN|MODUL"
,substr(s.status||'|'||round(w.WAIT_TIME_MICRO/1000000)||'|'||LAST_CALL_ET||'|'||to_char(LOGON_TIME,'ddMon HH24:MI'),1,40) "ST|WAITD|ACT_SINC|LOGIN"
,substr(w.event,1,24) "EVENT"
,s.SQL_ID "CURRENT SQL"
,s.FINAL_BLOCKING_INSTANCE||'|'||s.FINAL_BLOCKING_SESSION "I|BLK_BY"
from v\$session s, v\$session_wait w
where s.USERNAME is not null
and s.sid=w.sid
and s.STATUS='ACTIVE'
AND s.WAIT_CLASS <> 'Idle'
AND s.last_call_et > ${ACTIVE_TIME}
--AND MODULE NOT IN ( ${EXCLUDED_MODULES} )
order by "CURRENT SQL","I|BLK_BY" desc,w.event,"USER|SID,SER|MACHIN|MODUL","ST|WAITD|ACT_SINC|LOGIN" desc;
exit;
EOF
)
echo "ACTIVE SESSIONS has crossed the defined threshold. Current count is: ${ACTVSESSCOUNT}"
cat ${LOG_DIR}/Active_Sessions.log > ${LOGFILE}
export MSGSUBJECT="INFO: ACTIVE SESSIONS COUNT is [ ${ACTVSESSCOUNT} ] on Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]"
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
rm -f ${LOGFILE}
fi
fi
fi
# ############################################
# Checking BLOCKING SESSIONS ON THE DATABASE:
# ############################################
echo "Checking Blocking Sessions on [ ${ORACLE_SID} ] With Wait > ${WAIT_FOR_LOCK_THRES} seconds..."
if [[ ${DB_VER} -gt 10 ]]
then
export WAIT_COL="s2.WAIT_TIME_MICRO"
export WAIT_DISPLAY="round(${WAIT_COL}/1000000,0)"
export KILLARG="DISCONNECT"
else
export WAIT_COL="s2.SECONDS_IN_WAIT"
export WAIT_DISPLAY="round(${WAIT_COL})"
export KILLARG="KILL"
fi
VAL77=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set pages 0 feedback off;
select count(*) from gv\$LOCK l1, gv\$SESSION s1, gv\$LOCK l2, gv\$SESSION s2
where s2.wait_class<>'Idle'
and s1.sid=l1.sid
and s2.sid=l2.sid
and l1.BLOCK=1
and l2.request > 0
and l1.id1=l2.id1
and l2.id2=l2.id2
and ${WAIT_DISPLAY} > ${WAIT_FOR_LOCK_THRES};
exit;
EOF
)
VAL88=`echo ${VAL77}| awk '{print $NF}'`
if [[ ${VAL88} -ge ${BLOCKTHRESHOLD} ]]
then
echo "BLOCKING SESSIONS detected. Reporting the problem."
VAL99=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" << EOF
set linesize ${SQLLINESIZE} pages 1000 echo off feedback off
col BLOCKING_STATUS for a90
-- Enable HTML color format:
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; font-size: 80%; } th { background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
spool ${LOG_DIR}/blocking_sessions.log
${HASHHTML} set pages 0
${HASHHTML} select '<b>'||'Reported By ${SCRIPT_NAME} Script'||'</b>' from dual;
${HASHHTML} set pages 1000
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT MASTER BLOCKING SESSIONS ON DATABASE [ ${ORACLE_SID} ]
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
${HASHNONHTML} prompt ************************************
${HASHNONHTML} PROMPT MASTER BLOCKING SESSIONS ON DATABASE: [ ${ORACLE_SID} ]
${HASHNONHTML} PROMPT ************************************
set feedback off linesize ${SQLLINESIZE} pages 1000
col "I|OS/DB USER|SID,SER|MACHN|MOD" for a75
col "PREV|CURRENT_SQL|REMAIN_SEC" for a30
col "ST|WAITD|ACT_SINC|LOGIN" for a34
col event for a24
select /*+RULE*/
substr(s.INST_ID||'|'||s.OSUSER||'/'||s.USERNAME||'| '||s.sid||','||s.serial#||' |'||substr(s.MACHINE,1,22)||'|'||substr(s.MODULE,1,18),1,75)"I|OS/DB USER|SID,SER|MACHN|MOD"
,substr(s.status||'|'||round(w.WAIT_TIME_MICRO/1000000)||'|'||LAST_CALL_ET||'|'||to_char(LOGON_TIME,'ddMon HH24:MI'),1,34) "ST|WAITD|ACT_SINC|LOGIN"
,substr(w.event,1,24) "EVENT"
,s.PREV_SQL_ID||'|'||s.SQL_ID||'|'||round(w.TIME_REMAINING_MICRO/1000000) "PREV|CURRENT_SQL|REMAIN_SEC"
from gv\$session s, gv\$session_wait w, (select distinct s2.FINAL_BLOCKING_SESSION blocking_sid,s2.blocking_instance blocking_inst_id from gv\$session s2 where s2.FINAL_BLOCKING_SESSION is not null) blk_sess
where s.sid =blk_sess.blocking_sid
and s.inst_id=blk_Sess.blocking_inst_id
and s.USERNAME is not null
and s.sid=w.sid
and s.inst_id=w.inst_id
and s.FINAL_BLOCKING_SESSION is null;
col "KILL MASTER BLOCKING SESSION" for a75
select /*+RULE*/ 'ALTER SYSTEM ${KILLARG} SESSION '''||s.sid||','||s.serial#||',@'||s.inst_id||''' IMMEDIATE;' "KILL MASTER BLOCKING SESSION"
from gv\$session s
where s.sid in (select distinct FINAL_BLOCKING_SESSION from gv\$session where FINAL_BLOCKING_SESSION is not null)
and s.USERNAME is not null
and s.FINAL_BLOCKING_SESSION is null
/
${HASHNONHTML} prompt
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT List of BLOCKED SESSIONS
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
${HASHNONHTML} prompt
${HASHNONHTML} prompt *******************************
${HASHNONHTML} prompt [List of Victim BLOCKED SESSIONS]
${HASHNONHTML} prompt *******************************
set linesize ${SQLLINESIZE} pages 1000 echo off feedback off
col module for a27
col event for a24
col MACHINE for a27
col "WA_ST|WAITD|ACT_SINC|LOG_T" for a38
col "INST|USER|SID,SERIAL#" for a30
col "INS|USER|SID,SER|MACHIN|MODUL" for a65
col "PREV|CURR SQLID" for a27
col "I|BLKD_BY" for a12
col "${WAIT_DISPLAY}" for 99999999.9
select /*+RULE*/
substr(s.INST_ID||'|'||s.USERNAME||'| '||s.sid||','||s.serial#||' |'||substr(s.MACHINE,1,22)||'|'||substr(s.MODULE,1,18),1,65)"INS|USER|SID,SER|MACHIN|MODUL"
,substr(w.state||'|'||round(w.WAIT_TIME_MICRO/1000000)||'|'||LAST_CALL_ET||'|'||to_char(LOGON_TIME,'ddMon'),1,38) "WA_ST|WAITD|ACT_SINC|LOG_T"
,substr(w.event,1,24) "EVENT"
,s.FINAL_BLOCKING_INSTANCE||'|'||s.FINAL_BLOCKING_SESSION "I|BLKD_BY"
from gv\$session s, gv\$session_wait w
where s.USERNAME is not null
and s.FINAL_BLOCKING_SESSION is not null
and s.sid=w.sid
and s.STATUS='ACTIVE'
and s.wait_class<>'Idle'
order by "I|BLKD_BY" desc,w.event,"INS|USER|SID,SER|MACHIN|MODUL","WA_ST|WAITD|ACT_SINC|LOG_T" desc;
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT Blocking Locks On Objects Level
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
${HASHNONHTML} prompt
${HASHNONHTML} prompt ****************************
${HASHNONHTML} Prompt [Blocking Locks On Objects Level]
${HASHNONHTML} prompt ****************************
--${HASHNONHTML} PROMPT
${HASHHTML} set linesize ${SQLLINESIZE} pages 1000 echo off feedback off
${HASHNONHTML} set linesize ${SQLLINESIZE} pages 100 echo on feedback on
column OS_PID format A15 Heading "OS_PID"
column ORACLE_USER format A15 Heading "ORACLE_USER"
column LOCK_TYPE format A15 Heading "LOCK_TYPE"
column LOCK_HELD format A11 Heading "LOCK_HELD"
column LOCK_REQUESTED format A11 Heading "LOCK_REQUESTED"
column STATUS format A13 Heading "STATUS"
column OWNER format A15 Heading "OWNER"
column OBJECT_NAME format A35 Heading "OBJECT_NAME"
select /*+RULE*/ l.sid,
ORACLE_USERNAME oracle_user,
decode(TYPE,
'MR', 'Media Recovery',
'RT', 'Redo Thread',
'UN', 'User Name',
'TX', 'Transaction',
'TM', 'DML',
'UL', 'PL/SQL User Lock',
'DX', 'Distributed Xaction',
'CF', 'Control File',
'IS', 'Instance State',
'FS', 'File Set',
'IR', 'Instance Recovery',
'ST', 'Disk Space Transaction',
'TS', 'Temp Segment',
'IV', 'Library Cache Invalidation',
'LS', 'Log Start or Switch',
'RW', 'Row Wait',
'SQ', 'Sequence Number',
'TE', 'Extend Table',
'TT', 'Temp Table', type) lock_type,
decode(LMODE,
0, 'None',
1, 'Null',
2, 'Row-S (SS)',
3, 'Row-X (SX)',
4, 'Share',
5, 'S/Row-X (SSX)',
6, 'Exclusive', lmode) lock_held,
decode(REQUEST,
0, 'None',
1, 'Null',
2, 'Row-S (SS)',
3, 'Row-X (SX)',
4, 'Share',
5, 'S/Row-X (SSX)',
6, 'Exclusive', request) lock_requested,
decode(BLOCK,
0, 'Not Blocking',
1, 'Blocking',
2, 'Global', block) status,
OWNER,
OBJECT_NAME
from v\$locked_object lo,
dba_objects do,
v\$lock l
where lo.OBJECT_ID = do.OBJECT_ID
AND l.SID = lo.SESSION_ID
AND l.BLOCK='1';
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='35%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT Long Running Operations On DATABASE [ ${ORACLE_SID} ]
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 1000
${HASHNONHTML} prompt
${HASHNONHTML} prompt ******************************************
${HASHNONHTML} Prompt [Long Running Operations On DATABASE $ORACLE_SID]
${HASHNONHTML} prompt ******************************************
set linesize ${SQLLINESIZE} pages 1000
col "USERNAME| SID,SERIAL#" for a40
col MESSAGE for a80
col "%COMPLETE" for 999.999
col "SID|SERIAL#" for a12
col "STARTED|MIN_ELAPSED|REMAIN" for a30
select USERNAME||'| '||SID||','||SERIAL# "USERNAME| SID,SERIAL#",SQL_ID
--,OPNAME OPERATION
,round(SOFAR/TOTALWORK*100,2) "%DONE"
,to_char(START_TIME,'DD-Mon HH24:MI')||'| '||trunc(ELAPSED_SECONDS/60)||'|'||trunc(TIME_REMAINING/60) "STARTED|MIN_ELAPSED|REMAIN" ,MESSAGE
from v\$session_longops
where SOFAR/TOTALWORK*100 <>'100'
and TOTALWORK <> '0'
order by "STARTED|MIN_ELAPSED|REMAIN" desc, "USERNAME| SID,SERIAL#";
${HASHHTML} SET PAGES 0
${HASHHTML} SET MARKUP HTML OFF SPOOL OFF
${HASHHTML} PROMPT <br> <p> <table border='3' bordercolor='#E67E22' width='27%' align='left' summary='Script output'> <tr> <th scope="col">
${HASHHTML} PROMPT LOCKING ANALYSIS
${HASHHTML} PROMPT </td> </tr> </table> <p> <br>
${HASHHTML} SET WRAP OFF ECHO OFF FEEDBACK OFF MARKUP HTML ON SPOOL ON HEAD '<title></title> <style type="text/css"> table { background: #E67E22; bordercolor: #E67E22; font-size: 80%; } th { color: #FFFFFF; background: #AF601A; } td { background: #E67E22; padding: 0px; } </style>' TABLE "border='1' bordercolor='#E67E22'" ENTMAP OFF
${HASHHTML} set pages 0 lines 300
${HASHHTML} col blocking_status for a300
${HASHNONHTML} set linesize ${SQLLINESIZE} pages 0
${HASHNONHTML} PROMPT
${HASHNONHTML} PROMPT ******************
${HASHNONHTML} PROMPT [LOCKING ANALYSIS]
${HASHNONHTML} PROMPT ******************
select /*+RULE*/ 'User: '||s1.username || '@' || s1.machine || '(SID=' || s1.sid ||' ) running SQL_ID:'||s1.sql_id||' is blocking
User: '|| s2.username || '@' || s2.machine || '(SID=' || s2.sid || ') running SQL_ID:'||s2.sql_id||' For '||${WAIT_DISPLAY}||' Seconds
[Inform user '||s1.username||' Or Kill his session using:]
ALTER SYSTEM ${KILLARG} SESSION '''||s1.sid||','||s1.serial#||',@'||s1.inst_id||''' immediate;' AS blocking_status
from gv\$LOCK l1, gv\$SESSION s1, gv\$LOCK l2, gv\$SESSION s2
where s1.sid=l1.sid
and s2.sid=l2.sid
and l1.BLOCK=1
and l2.request > 0
and l1.id1 = l2.id1
and l2.id2 = l2.id2
order by ${WAIT_COL} desc
/
spool off
exit;
EOF
)
cat ${LOG_DIR}/blocking_sessions.log > ${LOGFILE}
export MSGSUBJECT="ALERT: BLOCKING SESSIONS detected on database [ ${DB_NAME_UPPER} ] on Server [ ${SRV_NAME} ]"
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOG_DIR}/blocking_sessions.log
echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
rm -f ${LOG_DIR}/blocking_sessions.log
fi
# #########################
# Locating DB ALERTLOG path:
# #########################
echo "Locating DB Instance ALERTLOG ..."
# First Attempt:
DUMP=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off lines 30000;
prompt
SELECT VALUE from V\$DIAG_INFO where name='Diag Trace';
exit;
EOF
)
ALERTZ=`echo ${DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
ALERTDB=${ALERTZ}/alert_${ORACLE_SID}.log
export ALERTDB
# Second Attempt:
if [[ ! -r ${ALERTDB} ]]
then
DUMP=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off lines 30000;
prompt
SELECT value from v\$parameter where NAME='background_dump_dest';
exit;
EOF
)
ALERTZ=`echo ${DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'`
ALERTDB=${ALERTZ}/alert_${ORACLE_SID}.log
export ALERTDB
fi
# Third Attempt:
if [[ ! -r ${ALERTDB} ]]
then
DUMP=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 0 feedback off lines 30000;
prompt
SELECT value from v\$parameter where NAME='core_dump_dest';
exit;
EOF
)
ALERTZ=`echo ${DUMP} | perl -lpe'$_ = reverse' |awk '{print $1}'|perl -lpe'$_ = reverse'|sed -e 's/\/cdump/\/trace/g'`
ALERTDB=${ALERTZ}/alert_${ORACLE_SID}.log
export ALERTDB
fi
# Forth Attempt:
if [[ ! -r ${ALERTDB} ]]
then
ALERTDB=${ORACLE_BASE}/diag/rdbms/${DB_NAME}/${ORACLE_SID}/trace/alert_${ORACLE_SID}.log
export ALERTDB
fi
# Fifth Attempt: [Expensive search with locate command]
if [[ ! -r ${ALERTDB} ]]
then
if [[ -x /usr/bin/locate ]]
then
ALERTDB=`ls -rtl \`locate alert_${ORACLE_SID}\`|tail -1|awk '{print $NF}'`
export ALERTDB
fi
fi
# ###########################
# Checking Database Errors:
# ###########################
# ALERTLOG errors to be send in text format:
export MAILEXEC="mail -s"
# Final check of ALERTLOG path:
if [[ -r ${ALERTDB} ]]
then
ALERTLOG=${ALERTDB}
elif [[ -r ${ORACLE_BASE}/admin/${ORACLE_SID}/bdump/alert_${ORACLE_SID}.log ]]
then
ALERTLOG=${ORACLE_BASE}/admin/${ORACLE_SID}/bdump/alert_${ORACLE_SID}.log
elif [[ -r ${ORACLE_HOME}/diagnostics/${DB_NAME}/diag/rdbms/${DB_NAME}/${ORACLE_SID}/trace/alert_${ORACLE_SID}.log ]]
then
ALERTLOG=${ORACLE_HOME}/diagnostics/${DB_NAME}/diag/rdbms/${DB_NAME}/${ORACLE_SID}/trace/alert_${ORACLE_SID}.log
else
ALERTLOG=`/usr/bin/find ${ORACLE_BASE} -iname alert_${ORACLE_SID}.log -print 2>/dev/null|sort|tail -1`
fi
# If HTML OPTION Enabled:
#case ${SENDMAIL} in
#'/usr/sbin/sendmail -t')
#if [ -f ${ALERTLOG} ]
#then
#ALERTXML=`echo ${ALERTLOG} |awk '{print $NF}'|sed -e 's/\/trace\/alert.*/\/alert\/log.xml/g'`
#echo ALERTXML is: $ALERTXML
# if [ -f ${ALERTXML} ]
# then
# export ALERTLOG=${ALERTXML}
# fi
#export ALERTLOG
#echo ALERTLOG is: $ALERTLOG
#fi
#;;
#esac
if [[ -r ${ALERTLOG} ]]
then
echo "Checking DB ALERTLOG ..."
# Rename the old log generated by the script (if exists):
if [[ -r ${LOG_DIR}/alert_${ORACLE_SID}_new.log ]]
then
mv ${LOG_DIR}/alert_${ORACLE_SID}_new.log ${LOG_DIR}/alert_${ORACLE_SID}_old.log
# Create new log:
tail -1000 ${ALERTLOG} > ${LOG_DIR}/alert_${ORACLE_SID}_new.log
# Extract new entries by comparing old & new logs:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_${ORACLE_SID}.log
echo " " >> ${LOG_DIR}/diff_${ORACLE_SID}.log
diff ${LOG_DIR}/alert_${ORACLE_SID}_old.log ${LOG_DIR}/alert_${ORACLE_SID}_new.log |grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_${ORACLE_SID}.log
# Search for errors:
ERRORS=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'ORA-\|TNS-' |egrep -v ${EXL_DB_ALERT_ERR}| tail -1`
EXPFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'DM00 ' | tail -1`
ALTERSFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'ALTER SYSTEM ' | tail -1`
ALTERDFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'Completed: ' | tail -1`
STARTUPFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'Starting ORACLE instance' | tail -1`
SHUTDOWNFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'Instance shutdown complete' | tail -1`
WARNINGFLAG=`cat ${LOG_DIR}/diff_${ORACLE_SID}.log | grep 'WARNING: ' | tail -1`
FILE_ATTACH=${LOG_DIR}/diff_${ORACLE_SID}.log
else
# Create new log:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/alert_${ORACLE_SID}_new.log
echo " " >> ${LOG_DIR}/alert_${ORACLE_SID}_new.log
tail -1000 ${ALERTLOG} >> ${LOG_DIR}/alert_${ORACLE_SID}_new.log
# Search for errors:
ERRORS=`cat ${LOG_DIR}/alert_${ORACLE_SID}_new.log | grep 'ORA-\|TNS-' |egrep -v ${EXL_DB_ALERT_ERR}| tail -1`
FILE_ATTACH=${LOG_DIR}/alert_${ORACLE_SID}_new.log
fi
# Send mail in case error exist:
case "${ERRORS}" in
*ORA-*|*TNS-*)
# In case time out errors reported enclose the Network Failure Staticits in the same E-mail:
case ${TIMEOUTDIGMORE} in
y|Y|yes|YES|Yes|true|TRUE|True|on|ON|On)
case "${ERRORS}" in
*'timed out'*)
case `uname` in
Linux )
if [[ -x /usr/bin/sar ]]
then
echo "Alertlog TIMEOUT errors reported, Checking OS Network Failure Statistics for the last 15 minutes ..."
echo -e "Netowrk Statistics are shown at the bottom of this E-mail\n$(cat ${FILE_ATTACH})" > ${FILE_ATTACH}
echo "" >> ${FILE_ATTACH}
echo "Following up on the detected TIMEOUT error [ ${ERRORS} ]" >> ${FILE_ATTACH}
echo "" >> ${FILE_ATTACH}
echo "NIC Statistics in the last 15 minutes:" >> ${FILE_ATTACH}
echo "*************************************" >> ${FILE_ATTACH}
echo "sar -n EDEV -s `date "+%H:%M:%S" -d "20 min ago"` | grep -Ev lo" >> ${FILE_ATTACH}
sar -n EDEV -s `date "+%H:%M:%S" -d "20 min ago"` | grep -Ev lo >> ${FILE_ATTACH}
fi
esac
esac
esac
case ${TEMPSPACEDIGMORE} in
y|Y|yes|YES|Yes|true|TRUE|True|on|ON|On)
case "${ERRORS}" in
*'ORA-1652'*|*'ORA-01652'*)
echo -e "TOP TEMP SPACE CONSUMERS are shown at the bottom of this E-mail\n$(cat ${FILE_ATTACH})" > ${FILE_ATTACH}
TOP_TEMP_CONSUMERS=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 1000 feedback off lines ${SQLLINESIZE}
SPOOL ${FILE_ATTACH} APPEND
col "USER|SID,SER|MACHIN|MODUL" for a65
COL TABLESPACE FOR A15
PROMPT
PROMPT Following up on the detected error [ ${ERRORS} ] ...
PROMPT
PROMPT TOP TEMP SPACE CONSUMERS:
PROMPT *************************
select substr(s.USERNAME||'|'||s.sid||','||s.serial#||'|'||substr(s.MACHINE,1,20)||'|'||substr(s.MODULE,1,20),1,65)"USER|SID,SER|MACHINE|MODULE"
,SUM (O.BLOCKS) * T.BLOCK_SIZE/1024/1024 USED_MB ,COUNT(*) SORTS#, S.SQL_ID,O.TABLESPACE
FROM V\$SORT_USAGE O, V\$SESSION S, DBA_TABLESPACES T
WHERE O.SESSION_ADDR = S.SADDR AND O.TABLESPACE = T.TABLESPACE_NAME
GROUP BY S.SID, S.SERIAL#, S.USERNAME, S.OSUSER, S.MODULE,S.MACHINE, T.BLOCK_SIZE,S.SQL_ID, O.TABLESPACE
ORDER BY USED_MB desc,S.USERNAME;
spool off
exit;
EOF
)
esac
esac
case ${REPORT_MAX_SESSIONS} in
y|Y|yes|YES|Yes|true|TRUE|True|on|ON|On)
case "${ERRORS}" in
*ORA-00020*)
echo "Alertlog ORA-00020 detected, checking connected sessions distribution ..."
echo -e "ORA-00020 detected, Please also check the Sessions Distribution at the bottom of this E-mail\n$(cat ${FILE_ATTACH})" >${FILE_ATTACH}
SESSIONS_DISTRIBUTION=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set feedback off echo off linesize ${SQLLINESIZE} pages 1000
col inst for 9999
col module for a70
col event for a28
col MACHINE for a70
col USERNAME for a40
SPO ${FILE_ATTACH} APP
PROMPT
PROMPT Following up on the detected error [ ${ERRORS} ] ...
PROMPT
PROMPT SESSIONS Distribution: [By USERNAME]
PROMPT ********************* ************
select USERNAME,count(*) "TOTAL_SESSIONS" from v\$session group by USERNAME order by count(*) desc, USERNAME;
PROMPT
PROMPT SESSIONS Distribution: [By MODULE]
PROMPT ********************* *********
select MODULE,count(*) "TOTAL_SESSIONS" from v\$session group by module order by count(*) desc,MODULE;
PROMPT
PROMPT SESSIONS Distribution: [By MACHINE]
PROMPT ********************* **********
select MACHINE,count(*) "TOTAL_SESSIONS" from v\$session group by MACHINE order by count(*) desc,MACHINE;
PROMPT
set pages 0
select 'ACTIVE SESSIONS: '||count(*) from v\$session where USERNAME is not null and status='ACTIVE';
select 'INACTIVE SESSIONS: '||count(*) from v\$session where USERNAME is not null and status='INACTIVE';
select 'BACKGROUND SESSIONS: '||count(*) from v\$session where USERNAME is null;
PROMPT -------------------- ------
select 'TOTAL SESSIONS: '||count(*) from v\$session;
PROMPT
select 'PARAMETER: PROCESSES | VALUE: '||INITIAL_ALLOCATION||' | CURRENT_UTILIZATION: '||CURRENT_UTILIZATION||' | MAX_UTILIZATION: '||MAX_UTILIZATION from v\$resource_limit where RESOURCE_NAME ='processes';
select 'PARAMETER: SESSIONS | VALUE: '||INITIAL_ALLOCATION||' | CURRENT_UTILIZATION: '||CURRENT_UTILIZATION||' | MAX_UTILIZATION: '||MAX_UTILIZATION from v\$resource_limit where RESOURCE_NAME ='sessions';
/*
set pages 1000
col PARAMETER for a15
col VALUE for 999999999999
col CURRENT_CONNECTED_SESSIONS for 99999999999999999999999999
col MAX_CONNECTED_SESSIONS for 9999999999999999999999
select RESOURCE_NAME PARAMETER,INITIAL_ALLOCATION VALUE,CURRENT_UTILIZATION CURRENT_CONNECTED_SESSIONS,MAX_UTILIZATION MAX_CONNECTED_SESSIONS from v\$resource_limit where RESOURCE_NAME in ('processes','sessions');
*/
spool off
exit;
EOF
)
esac
esac
cat ${FILE_ATTACH} > ${LOGFILE}
export MSGSUBJECT="ALERT: Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}"
echo ${MSGSUBJECT}
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
;;
esac
case ${PARANOIDMODE} in
y|Y|yes|YES|Yes|true|TRUE|True|on|ON|On)
case "${EXPFLAG}" in
*'DM00'*)
cat ${FILE_ATTACH} > ${LOGFILE}
export MSGSUBJECT="INFO: EXPORT/IMPORT Operation Initiated on Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]"
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
;;
esac
case "${ALTERSFLAG}" in
*'ALTER SYSTEM'*)
cat ${FILE_ATTACH} > ${LOGFILE}
export MSGSUBJECT="INFO: ALTER SYSTEM Command Executed Against Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]"
echo ${MSGSUBJECT}
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
;;
esac
case "${ALTERDFLAG}" in
*'Completed:'*)
cat ${FILE_ATTACH} > ${LOGFILE}
export MSGSUBJECT="INFO: MAJOR DB ACTIVITY Completed on Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]"
echo ${MSGSUBJECT}
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
;;
esac
case "${STARTUPFLAG}" in
*'Starting ORACLE instance'*)
cat ${FILE_ATTACH} > ${LOGFILE}
export MSGSUBJECT="ALERT: Startup Event of Instance [ ${ORACLE_SID} ] Triggered on Server [ ${SRV_NAME} ]"
echo ${MSGSUBJECT}
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
;;
esac
case "${SHUTDOWNFLAG}" in
*'Instance shutdown complete'*)
cat ${FILE_ATTACH} > ${LOGFILE}
export MSGSUBJECT="ALARM: Shutdown Event of Instance [ ${ORACLE_SID} ] Triggered on Server [ ${SRV_NAME} ]"
echo ${MSGSUBJECT}
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
#echo ${SENDMAILARGS} | tr \; '\n' |awk 'length == 1 || NR == 1 {print $0} length && NR > 1 { print substr($0,2) }'| ${SENDMAIL}
;;
esac
case "${WARNINGFLAG}" in
*'WARNING: '*)
cat ${FILE_ATTACH} > ${LOGFILE}
export MSGSUBJECT="INFO: WARNING Message Detected on Instance [ ${ORACLE_SID} ] on Server [ ${SRV_NAME} ]"
echo ${MSGSUBJECT}
SENDMAILARGS=$(
echo "To: ${EMAIL};"
echo "Subject: ${MSGSUBJECT} ;"
echo "Content-Type: text/html;"
echo "MIME-Version: 1.0;"
cat ${LOGFILE}
)
${MAILEXEC} "${MSGSUBJECT}" ${MAIL_LIST} < ${LOGFILE}
;;
esac
;;
esac
fi
# ################################################
# Removal of JUNK MESSAGES inside the DB ALERTLOG:
# ################################################
case ${REMOVE_JUNK_MSGS} in
y|Y|yes|Yes|YES|ON|on)
if [[ -r ${ALERTLOG} ]]
then
# Remove "XDB initialized" message caused by Bug 29845449 from the alertlog and 2 lines above it; which covers the message timestamp:
vim -e - ${ALERTLOG} << EOF
g/XDB initialized/.-2,.d
wq
EOF
fi
;;
esac
# #####################
# Reporting Offline DBs:
# #####################
# Populate ${LOG_DIR}/alldb_DBA_BUNDLE.log from ORATAB:
# put all running instances in one variable:
ALL_RUNNING_INSTANCES=`ps -ef|grep pmon|grep -v grep|egrep -v ${EXL_DB}|awk '{print $NF}'|sed -e 's/ora_pmon_//g'|grep -v sed|grep -v "s///g"`
# Exclude all running instances/DB names from getting checked when reading ORATAB file:
grep -v '^\#' ${ORATAB} |egrep -v "${EXL_DB}"|egrep -v "${ALL_RUNNING_INSTANCES}"|grep -v "${DB_NAME_LOWER}:"| grep -v "${DB_NAME_UPPER}:"| grep -v '^$' | grep "^" | cut -f1 -d':' > ${LOG_DIR}/alldb_DBA_BUNDLE.log
# Populate ${LOG_DIR}/updb_DBA_BUNDLE.log:
echo ${ORACLE_SID} >> ${LOG_DIR}/updb_DBA_BUNDLE.log
echo ${DB_NAME} >> ${LOG_DIR}/updb_DBA_BUNDLE.log
# End looping for databases:
echo ""
done
# Continue Reporting Offline DBs...
case ${CHKOFFLINEDB} in
y|Y|yes|YES|Yes|ON|On|on)
echo "Checking Offline Databases ..."
# Sort the lines alphabetically with removing duplicates:
sort ${LOG_DIR}/updb_DBA_BUNDLE.log | uniq -d > ${LOG_DIR}/updb_DBA_BUNDLE.log.sort
sort ${LOG_DIR}/alldb_DBA_BUNDLE.log > ${LOG_DIR}/alldb_DBA_BUNDLE.log.sort
diff ${LOG_DIR}/alldb_DBA_BUNDLE.log.sort ${LOG_DIR}/updb_DBA_BUNDLE.log.sort > ${LOG_DIR}/diff_DBA_BUNDLE.sort
echo "The Following Instances are POSSIBLY Down/Hung on [ ${SRV_NAME} ]:" > ${LOG_DIR}/offdb_DBA_BUNDLE.log
echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" >> ${LOG_DIR}/offdb_DBA_BUNDLE.log
grep "^< " ${LOG_DIR}/diff_DBA_BUNDLE.sort | cut -f2 -d'<' >> ${LOG_DIR}/offdb_DBA_BUNDLE.log
echo " " >> ${LOG_DIR}/offdb_DBA_BUNDLE.log
echo "If above instances are permanently offline, please add their names to 'EXL_DB' parameter at line# 90 or hash their entries in ${ORATAB} to let the script ignore them in the next run." >> ${LOG_DIR}/offdb_DBA_BUNDLE.log
OFFLINE_DBS_NUM=`cat ${LOG_DIR}/offdb_DBA_BUNDLE.log| wc -l`
# If OFFLINE_DBS is not null:
if [[ ${OFFLINE_DBS_NUM} -gt 4 ]]
then
echo "" >> ${LOG_DIR}/offdb_DBA_BUNDLE.log
echo "Current Running Instances:" >> ${LOG_DIR}/offdb_DBA_BUNDLE.log
echo "************************" >> ${LOG_DIR}/offdb_DBA_BUNDLE.log
ps -ef|grep pmon|grep -v grep >> ${LOG_DIR}/offdb_DBA_BUNDLE.log
echo "" >> ${LOG_DIR}/offdb_DBA_BUNDLE.log
VALX1=$(${ORACLE_HOME}/bin/sqlplus -S "/ as sysdba" <<EOF
set pages 100;
spool ${LOG_DIR}/running_instances.log
set linesize ${SQLLINESIZE}
col BLOCKED for a7
col STARTUP_TIME for a19
select instance_name INS_NAME,STATUS,DATABASE_STATUS DB_STATUS,LOGINS,BLOCKED,to_char(STARTUP_TIME,'DD-MON-YY HH24:MI:SS') STARTUP_TIME from v\$instance;
spool off
exit;
EOF
)
cat ${LOG_DIR}/running_instances.log >> ${LOG_DIR}/offdb_DBA_BUNDLE.log
echo "Offline Database Detected. Reporting the problem."
mail -s "ALARM: Database Inaccessible on Server: [ ${SRV_NAME} ]" ${MAIL_LIST} < ${LOG_DIR}/offdb_DBA_BUNDLE.log
fi
# Wiping Logs:
#cat /dev/null > ${LOG_DIR}/updb_DBA_BUNDLE.log
#cat /dev/null > ${LOG_DIR}/alldb_DBA_BUNDLE.log
#cat /dev/null > ${LOG_DIR}/updb_DBA_BUNDLE.log.sort
#cat /dev/null > ${LOG_DIR}/alldb_DBA_BUNDLE.log.sort
#cat /dev/null > ${LOG_DIR}/diff_DBA_BUNDLE.sort
rm -f ${LOG_DIR}/updb_DBA_BUNDLE.log
rm -f ${LOG_DIR}/alldb_DBA_BUNDLE.log
rm -f ${LOG_DIR}/updb_DBA_BUNDLE.log.sort
rm -f ${LOG_DIR}/alldb_DBA_BUNDLE.log.sort
rm -f ${LOG_DIR}/diff_DBA_BUNDLE.sort
;;
esac
# ###########################
# Checking Listeners log:
# ###########################
# Check if the LISTENER CHECK flag is Y:
case ${CHKLISTENER} in
y|Y|yes|YES|Yes|ON|On|on)
echo "Checking Listener Log ..."
# In case there is NO Listeners are running send an (Alarm):
LSN_COUNT=$( ps -ef|grep -v grep|grep tnslsnr|wc -l )
if [[ ${LSN_COUNT} -eq 0 ]]
then
echo "The following are the LISTENERS running by user ${ORA_USER} on server ${SRV_NAME}:" > ${LOG_DIR}/listener_processes.log
echo "************************************************************************************" >> ${LOG_DIR}/listener_processes.log
ps -ef|grep -v grep|grep tnslsnr >> ${LOG_DIR}/listener_processes.log
mail -s "ALARM: No Listeners Are Running on Server: ${SRV_NAME} !!!" ${MAIL_LIST} < ${LOG_DIR}/listener_processes.log
# In case there is listener running analyze its log:
else
# for LISTENER_NAME in $( ps -ef|grep -v grep|grep tnslsnr|awk '{print $(NF-1)}' )
for LISTENER_NAME in $( ps -ef|grep -v grep|grep tnslsnr|awk '{print $(9)}' )
do
# LISTENER_HOME=`ps -ef|grep -v grep|grep tnslsnr|grep "${LISTENER_NAME} "|awk '{print $(NF-2)}' |sed -e 's/\/bin\/tnslsnr//g'|grep -v sed|grep -v "s///g"`
LISTENER_HOME=`ps -ef|grep -v grep|grep tnslsnr|grep "${LISTENER_NAME} "|awk '{print $(8)}' |sed -e 's/\/bin\/tnslsnr//g'|grep -v sed|grep -v "s///g"|head -1`
export LISTENER_HOME
TNS_ADMIN=${LISTENER_HOME}/network/admin
export TNS_ADMIN
LISTENER_LOGDIR=`${LISTENER_HOME}/bin/lsnrctl status ${LISTENER_NAME} |grep "Listener Log File"| awk '{print $NF}'| sed -e 's/\/alert\/log.xml//g'`
export LISTENER_LOGDIR
LISTENER_LOG=${LISTENER_LOGDIR}/trace/${LISTENER_NAME}.log
export LISTENER_LOG
# Determine if the listener name is in Upper/Lower case:
if [[ ! -r ${LISTENER_LOG} ]]
then
# Listner_name is Uppercase:
LISTENER_NAME=$( echo ${LISTENER_NAME} | awk '{print toupper($0)}' )
export LISTENER_NAME
LISTENER_LOG=${LISTENER_LOGDIR}/trace/${LISTENER_NAME}.log
export LISTENER_LOG
fi
if [[ ! -r ${LISTENER_LOG} ]]
then
# Listener_name is Lowercase:
LISTENER_NAME=$( echo "${LISTENER_NAME}" | awk '{print tolower($0)}' )
export LISTENER_NAME
LISTENER_LOG=${LISTENER_LOGDIR}/trace/${LISTENER_NAME}.log
export LISTENER_LOG
fi
if [[ -r ${LISTENER_LOG} ]]
then
# Rename the old log (If exists):
if [[ -r ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log ]]
then
mv ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log ${LOG_DIR}/alert_lis_${LISTENER_NAME}_old.log
# Create a new log:
tail -1000 ${LISTENER_LOG} > ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log
# Get the new entries:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log
echo " " >> ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log
diff ${LOG_DIR}/alert_lis_${LISTENER_NAME}_old.log ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log | grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log
# Search for errors:
#ERRORS=`cat ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log|grep "TNS-"|egrep -v "${EXL_LSNR_ERR}"|tail -1`
ERRORS=`cat ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log|grep "TNS-"|egrep -v "${EXL_LSNR_ERR}"|tail -1`
SRVC_REG=`cat ${LOG_DIR}/diff_lis_${LISTENER_NAME}.log| grep "service_register" `
FILE_ATTACH=${LOG_DIR}/diff_lis_${LISTENER_NAME}.log
# If no old logs exist:
else
# Just create a new log without doing any comparison:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log
echo " " >> ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log
tail -1000 ${LISTENER_LOG} >> ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log
# Search for errors:
#ERRORS=`cat ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log|grep "TNS-"|egrep -v "${EXL_LSNR_ERR}"|tail -1`
ERRORS=`cat ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log | grep "TNS-"|egrep -v "${EXL_LSNR_ERR}"|tail -1`
SRVC_REG=`cat ${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log | grep "service_register" `
FILE_ATTACH=${LOG_DIR}/alert_lis_${LISTENER_NAME}_new.log
fi
# Report TNS Errors (Alert)
case "${ERRORS}" in
*TNS-*)
# In case timeout errors reported enclose the Network Failure Staticits in the same E-mail:
case ${TIMEOUTDIGMORE} in
y|Y|yes|YES|Yes|true|TRUE|True|on|ON|On)
case "${ERRORS}" in
*timeout*)
case `uname` in
Linux )
echo "Listener TIMEOUT errors reported, Checking OS Network Failure Statistics for the last 15 minutes ..."
echo -e "Network Statistics are shown at the bottom of this E-mail\n$(cat ${FILE_ATTACH})" > ${FILE_ATTACH}
echo "" >> ${FILE_ATTACH}
echo "" >> ${FILE_ATTACH}
echo "NIC Statistics in the last 15 minutes:" >> ${FILE_ATTACH}
echo "*************************************" >> ${FILE_ATTACH}
echo "sar -n EDEV -s `date "+%H:%M:%S" -d "20 min ago"` | grep -Ev lo" >> ${FILE_ATTACH}
sar -n EDEV -s `date "+%H:%M:%S" -d "20 min ago"` | grep -Ev lo >> ${FILE_ATTACH}
esac
esac
esac
mail -s "ALERT: Listener [ ${LISTENER_NAME} ] on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}" ${MAIL_LIST} < ${FILE_ATTACH}
esac
# Report Registered Services to the listener (Info)
case "${SRVC_REG}" in
*service_register*)
mail -s "INFO: Service Registered on Listener [ ${LISTENER_NAME} ] on Server [ ${SRV_NAME} ] | TNS poisoning possibility" ${MAIL_LIST} < ${FILE_ATTACH}
esac
else
echo "Cannot find the listener log: <${LISTENER_LOG}> for listener ${LISTENER_NAME} !"
fi
done
fi
esac
# ###############################
# Checking ASM Instance ALERTLOG:
# ###############################
# Manually Specify ASM Instance alertlog file location: [In case the script failed to find its location]
ASMALERT=
export ASMALERT
# Check if the CHKASMALERTLOG is enabled:
case ${CHKASMALERTLOG} in
y|Y|yes|YES|Yes|ON|On|on)
ASMCOUNT=`ps -ef|grep -v grep|grep asm_pmon_|wc -l`
if [[ ${ASMCOUNT} -gt 0 ]]
then
echo "[ASM Instance Found] Locating ASM Instance ALERTLOG ..."
# Fetching ASM Instance name:
ASM_INSTANCE_NAME=`ps -ef|grep pmon|grep -v grep|grep asm_pmon_|awk '{print $NF}'|sed -e 's/asm_pmon_//g'|grep -v sed|grep -v "s///g"|tail -1`
export ASM_INSTANCE_NAME
# Locating GRID_HOME:
GRID_HOME=`ps -ef|grep ocssd|grep -v grep|awk '{print $NF}'|sed -e 's/\/bin\/ocssd.bin//g'|grep -v "ocssd.bin"|tail -1`
export GRID_HOME
if [[ ! -d ${GRID_HOME} ]]
then
GRID_HOME=`dbhome ${ASM_INSTANCE_NAME}`
export GRID_HOME
fi
# Locating GRID_BASE:
GRID_BASE=`cat ${GRID_HOME}/crs/install/crsconfig_params|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'`
export GRID_BASE
if [[ ! -d ${GRID_BASE} ]]
then
GRID_BASE=`cat ${GRID_HOME}/crs/utl/appvipcfg|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'`
export GRID_BASE
fi
if [[ ! -d ${GRID_BASE} ]]
then
GRID_BASE=`cat ${GRID_HOME}/install/envVars.properties|grep ^ORACLE_BASE|tail -1|awk '{print $NF}'|sed -e 's/ORACLE_BASE=//g'`
export GRID_BASE
fi
# Locating ASM ALERTLOG:
ASMALERT=`ls -rtl ${GRID_BASE}/diag/asm/+asm/${ASM_INSTANCE_NAME}/trace/alert_+ASM*.log|tail -1|awk '{print $NF}'`
export ASMALERT
if [[ ! -r ${ASMALERT} ]]
then
if [[ -x /usr/bin/locate ]]
then
ASMALERT=`ls -rtl \`/usr/bin/locate alert_+ASM\`|tail -1|awk '{print $NF}'`
export ASMALERT
fi
fi
if [[ ! -d ${GRID_BASE} ]]
then
if [[ -r ${ASMALERT} ]]
then
GRID_BASE=`grep 'ORACLE_BASE from environment' ${ASMALERT} | awk '{print $(5)}'|tail -1`
export GRID_BASE
fi
fi
if [[ -r ${ASMALERT} ]]
then
# ASM ALERTLOG Inspection:
echo "Checking ASM ALERTLOG ..."
if [[ -r ${LOG_DIR}/alertASM_new.log ]]
then
mv ${LOG_DIR}/alertASM_new.log ${LOG_DIR}/alertASM_old.log
# Create new log:
tail -1000 ${ASMALERT} > ${LOG_DIR}/alertASM_new.log
# Extract new entries by comparing old & new logs:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_ASMALERT.log
echo " " >> ${LOG_DIR}/diff_ASMALERT.log
diff ${LOG_DIR}/alertASM_old.log ${LOG_DIR}/alertASM_new.log |grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_ASMALERT.log
# Search for errors:
ERRORS=`cat ${LOG_DIR}/diff_ASMALERT.log | grep 'ORA-\|TNS-' |egrep -v ${EXL_DB_ALERT_ERR}| tail -1`
STARTUPFLAG=`cat ${LOG_DIR}/diff_ASMALERT.log | grep 'Starting ORACLE instance' | tail -1`
SHUTDOWNFLAG=`cat ${LOG_DIR}/diff_ASMALERT.log | grep 'Instance shutdown complete' | tail -1`
FILE_ATTACH=${LOG_DIR}/diff_ASMALERT.log
else
# If dbalarm is running for the first time against ASM ALERTLOG, Create a new staging log:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/alertASM_new.log
echo " " >> ${LOG_DIR}/alertASM_new.log
tail -1000 ${ASMALERT} >> ${LOG_DIR}/alertASM_new.log
# Search for errors:
ERRORS=`cat ${LOG_DIR}/alertASM_new.log | grep 'ORA-\|TNS-' |egrep -v ${EXL_DB_ALERT_ERR}| tail -1`
FILE_ATTACH=${LOG_DIR}/alertASM_new.log
fi
# Send E-mail alert in case any of the following errors detected:
case "${ERRORS}" in
*ORA-*|*TNS-*)
mail -s "ALERT: ASM Instance on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALERT: ASM Instance on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}"
esac
case "${STARTUPFLAG}" in
*'Starting ORACLE instance'*)
mail -s "ALERT: Startup Event of ASM Instance Triggered on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALERT: Startup Event of ASM Instance Triggered on Server [ ${SRV_NAME} ]"
esac
case "${SHUTDOWNFLAG}" in
*'Instance shutdown complete'*)
mail -s "ALARM: Shutdown Event of ASM Instance Triggered on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALARM: Shutdown Event of ASM Instance Triggered on Server [ ${SRV_NAME} ]"
esac
else
echo "Cannot find ASM ALERTLOG, locate utility is not installed on this system."
echo "Please manually export the ASM ALERTLOG full path inside dbalarm.sh: e.g. ASMALERT=/u01/app/grid/diag/asm/+asm/+ASM/trace/alert_+ASM.log"
fi
fi
esac
# ######################################
# Checking GRID INFRASTRUCTURE ALERTLOG:
# ######################################
# Manually Specify GRID INFRASTRUCTURE alertlog file location: [In case the script failed to find its location]
GRIDLOGFILE=
export GRIDLOGFILE
# Check if the CHKCLSALERTLOG flag is enabled:
case ${CHKCLSALERTLOG} in
y|Y|yes|YES|Yes|ON|On|on)
# Locate ADR BASE:
VAL_ADR_BASE=$(${ORACLE_HOME}/bin/adrci <<EOF
exit;
EOF
)
ADR_BASE=`echo ${VAL_ADR_BASE}|awk '{print $(NF-1)}'|sed -e 's/"//g'`
export ADR_BASE
# Check for ocssd process:
CHECK_OCSSD=`ps -ef|grep 'ocssd.bin'|grep -v grep|wc -l`
if [[ ${CHECK_OCSSD} -gt 0 ]]
then
echo "[Grid Infrastructure Setup Detected] Locating Grid Infrastructure ALERTLOG ..."
# Hashed the following line to avoid slowing down the script execution:
#GRIDLOGFILE=`locate -i crs/${HOSTNAMELOWER}/crs/trace/alert.log`
# Locate Clusterware log location:
GRIDLOGFILE="${GRID_BASE}/diag/crs/${HOSTNAMELOWER}/crs/trace/alert.log"
if [[ ! -r ${GRIDLOGFILE} ]]
then
GRIDLOGFILE="${GRID_BASE}/diag/crs/${HOSTNAMELOWER}/crs/trace/alert${HOSTNAMELOWER}.log"
fi
if [[ ! -r ${GRIDLOGFILE} ]]
then
GRIDLOGFILE="${GRID_HOME}/log/${HOSTNAMELOWER}/alert${HOSTNAMELOWER}.log"
fi
if [[ ! -r ${GRIDLOGFILE} ]]
then
GRIDLOGFILE="${GRID_HOME}/log/${HOSTNAMELOWER}/alert.log"
fi
if [[ ! -r ${GRIDLOGFILE} ]]
then
GRIDLOGFILE="${ADR_BASE}/diag/crs/${HOSTNAMELOWER}/crs/trace/alert.log"
fi
if [[ ! -r ${GRIDLOGFILE} ]]
then
GRIDLOGFILE="${ADR_BASE}/diag/crs/${HOSTNAMELOWER}/crs/trace/alert${HOSTNAMELOWER}.log"
fi
export GRIDLOGFILE
if [[ -r ${GRIDLOGFILE} ]]
then
# CLUSTERWARE ALERTLOG Inspection:
echo "Checking GRID INFRASTRUCTURE ALERTLOG ..."
if [[ -r ${LOG_DIR}/alertGRID_new.log ]]
then
mv ${LOG_DIR}/alertGRID_new.log ${LOG_DIR}/alertGRID_old.log
# Create new logfile:
tail -1000 ${GRIDLOGFILE} > ${LOG_DIR}/alertGRID_new.log
# Extract the new entries by comparing old & new logs:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_GRIDALERT.log
echo " " >> ${LOG_DIR}/diff_GRIDALERT.log
diff ${LOG_DIR}/alertGRID_old.log ${LOG_DIR}/alertGRID_new.log |grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_GRIDALERT.log
# Search for errors:
ERRORS=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'ORA-\|TNS-\| error \|error:\|errors with\|Errors\|failed\|fatal error\|Unable to failover\|disconnected from server\|Maximum restart attempts' |egrep -v ${EXL_GRID_ALERT_ERR}| tail -1`
STARTUPFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'is starting' | tail -1`
SHUTDOWNFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'is exiting' | tail -1`
NODEEVECTFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'Node down event' | tail -1`
IPCONFLICTFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'is already in use in the network' | tail -1`
HEARTBEATFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'not scheduled for' | tail -1`
SERVICEFAILFLAG=`cat ${LOG_DIR}/diff_GRIDALERT.log | grep 'has been removed from pool' | tail -1`
FILE_ATTACH=${LOG_DIR}/diff_GRIDALERT.log
else
# If dbalarm is running for the first time against GRID ALERTLOG, Create a new staging log:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/alertGRID_new.log
echo " " >> ${LOG_DIR}/alertGRID_new.log
tail -1000 ${GRIDALERT} >> ${LOG_DIR}/alertGRID_new.log
# Search for errors:
ERRORS=`cat ${LOG_DIR}/alertGRID_new.log | grep 'ORA-\|TNS-' |egrep -v ${EXL_DB_ALERT_ERR}| tail -1`
FILE_ATTACH=${LOG_DIR}/alertGRID_new.log
fi
# Send E-mail alert in case any of the following errors detected:
case "${ERRORS}" in
*'ORA-'*|*'TNS-'*|*' error '*|*'error:'*|*'errors with'*|*'Errors'*|*'failed'*|*'fatal error'*|*'Unable to failover'*|*'disconnected from server'*|*'Maximum restart attempts'*)
mail -s "ALERT: GRID on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALERT: GRID on Server [ ${SRV_NAME} ] reporting errors: ${ERRORS}"
esac
case "${STARTUPFLAG}" in
*'is starting'*)
mail -s "ALARM: GRID Startup Event Detected on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALARM: GRID Startup Event Detected."
esac
case "${SHUTDOWNFLAG}" in
*'is exiting'*)
mail -s "ALARM: GRID SHUTDOWN Event Detected on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALARM: GRID SHUTDOWN Event Detected."
esac
case "${NODEEVECTFLAG}" in
*'Node down event'*)
mail -s "ALARM: GRID Node Eviction Event Detected on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALARM: GRID Node Eviction Event Detected."
esac
case "${IPCONFLICTFLAG}" in
*'is already in use in the network'*)
mail -s "ALARM: IP CONFLICT Detected In The Network Impacting The GRID On Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALARM: IP CONFLICT Detected In The Network Impacting The GRID."
esac
case "${HEARTBEATFLAG}" in
*'not scheduled for'*)
mail -s "ALARM: GRID HEARTBEAT Failure Detected on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALARM: GRID HEARTBEAT Failure Detected."
esac
case "${SERVICEFAILFLAG}" in
*'has been removed from pool'*)
mail -s "ALARM: GRID SERVICE Down Event Detected on Server [ ${SRV_NAME} ]" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALARM: GRID SERVICE Down Event Detected."
esac
else
echo "Unable to locate the GRID INFRASTRUCTURE ALERTLOG."
echo "Please export it manually inside dbalarm script. e.g. GRIDLOGFILE=/u01/app/grid/diag/crs/databasemachinename/crs/trace/alert.log"
fi
fi
esac
# ###########################
# Checking Goldengate Errors:
# ###########################
# Manually Specify goldengate logfile location: [In case the script failed to find its location]
ALERTGGPATH=
export ALERTGGPATH
# Check if the Goldengate CHECK flag is Y:
case ${CHKGOLDENGATE} in
y|Y|yes|YES|Yes|ON|On|on)
echo "Checking GoldenGate log ..."
# Determine goldengate log path:
if [[ ! -z ${ALERTGGPATH} ]]
then
GGLOG=${ALERTGGPATH}
export GGLOG
else
GGLOG=`/bin/ps -ef|grep ggserr.log|grep -v grep|tail -1|awk '{print $NF}'`
export GGLOG
fi
# Second Attempt:
if [[ ! -r ${GGLOG} ]]
then
GGLOG=`/bin/ps -ef|grep 'PROCESSID MGR'| grep -v grep| awk '{print $10}'|sed -e 's/dirprm\/mgr.prm/ggserr.log/g'`
export GGLOG
fi
# Third Attempt: [Expensive search with locate command]
if [[ ! -r ${GGLOG} ]]
then
if [[ -x /usr/bin/locate ]]
then
GGLOG=`ls -rtl \`/usr/bin/locate ggserr.log\`|tail -1|awk '{print $NF}'`
export GGLOG
fi
fi
if [[ -r ${GGLOG} ]]
then
# Rename the old log generated by the script (if exists):
if [[ -r ${LOG_DIR}/ggserr_new.log ]]
then
mv ${LOG_DIR}/ggserr_new.log ${LOG_DIR}/ggserr_old.log
# Create new staging log in case it's the first run of dbalarm.sh:
tail -1000 ${GGLOG} > ${LOG_DIR}/ggserr_new.log
# Extract new entries by comparing old & new logs:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_ggserr.log
echo " " >> ${LOG_DIR}/diff_ggserr.log
diff ${LOG_DIR}/ggserr_old.log ${LOG_DIR}/ggserr_new.log |grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_ggserr.log
# Search for errors:
#ERRORS=`cat ${LOG_DIR}/diff_ggserr.log | grep 'ERROR' |egrep -v ${EXL_GG_ERR}| tail -1`
ERRORS=`cat ${LOG_DIR}/diff_ggserr.log | grep 'ERROR' | tail -1`
FILE_ATTACH=${LOG_DIR}/diff_ggserr.log
else
# Create new log:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/ggserr_new.log
echo " " >> ${LOG_DIR}/ggserr_new.log
tail -1000 ${GGLOG} >> ${LOG_DIR}/ggserr_new.log
# Search for errors:
#ERRORS=`cat ${LOG_DIR}/ggserr_new.log | grep 'ERROR' |egrep -v ${EXL_GG_ERR}| tail -1`
ERRORS=`cat ${LOG_DIR}/ggserr_new.log | grep 'ERROR' | tail -1`
FILE_ATTACH=${LOG_DIR}/ggserr_new.log
fi
# Send mail in case error exist:
case ${ERRORS} in
*' ERROR '*)
echo "Goldengate Error Detected. Reporting the problem."
mail -s "Goldengate Error on Server [ ${SRV_NAME} ]: ${ERRORS}" ${MAIL_LIST} < ${FILE_ATTACH}
esac
fi
esac
# #############################
# Check Device Driver Messages: [dmesg]
# #############################
case ${DEVICEDRIVERLOG} in
y|Y|yes|YES|Yes|ON|On|on)
echo "Checking Device Driver [dmesg] ..."
if [[ -r ${LOG_DIR}/dmesg_new.log ]]
then
mv ${LOG_DIR}/dmesg_new.log ${LOG_DIR}/dmesg_old.log
# Generate a new log to compare the old with:
dmesg > ${LOG_DIR}/dmesg_new.log
# Extract new entries by comparing old & new logs:
echo "[Reported By ${SCRIPT_NAME} Script]" > ${LOG_DIR}/diff_dmesg.log
echo " " >> ${LOG_DIR}/diff_dmesg.log
diff ${LOG_DIR}/dmesg_old.log ${LOG_DIR}/dmesg_new.log |grep ">" | cut -f2 -d'>' >> ${LOG_DIR}/diff_dmesg.log
# Search for Errors:
ERRORS=`cat ${LOG_DIR}/diff_dmesg.log | grep 'error' |egrep -v ${EXL_DMESG_ERR}| tail -1`
FILE_ATTACH=${LOG_DIR}/diff_dmesg.log
else
# If dbalarm is running for the first time against dmesg log, create a new staging log and use it for the next execution:
dmesg > ${LOG_DIR}/dmesg_new.log
fi
case "${ERRORS}" in
*error*)
mail -s "ALERT: OS DEVICE DRIVER Error Detected on Server [ ${SRV_NAME} ] | ${ERRORS}" ${MAIL_LIST} < ${FILE_ATTACH}
echo "ALERT: OS DEVICE DRIVER Error Detected | ${ERRORS}"
esac
esac
# ###############################
# De-Neutralize login.sql file:
# ###############################
# If login.sql was renamed during the execution of the script revert it back to its original name:
if [[ -r ${USR_ORA_HOME}/login.sql_NeutralizedBy${SCRIPT_NAME} ]]
then
mv ${USR_ORA_HOME}/login.sql_NeutralizedBy${SCRIPT_NAME} ${USR_ORA_HOME}/login.sql
fi
echo ""
echo "[dbalarm Script Completed]"
echo ""
# #############
# END OF SCRIPT
# #############
# REPORT BUGS to: mahmmoudadel@hotmail.com
# DOWNLOAD THE LATEST VERSION OF DATABASE ADMINISTRATION BUNDLE FROM:
# http://dba-tips.blogspot.com/2014/02/oracle-database-administration-scripts.html
# DISCLAIMER: THIS SCRIPT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment