#!/bin/bash # # dodger@ciberterminal.net # 06/05/2013: Complete rewrite of this f*****shit # # This Nagios plugin was created to check Oracle status on a remote site through SSH # # GRANTS for nagios user # CREATE USER NAGIOS IDENTIFIED BY SOMEPASSWORD; # GRANT CONNECT, RESOURCE TO NAGIOS ; # GRANT SELECT ON V_$ARCHIVED_LOG to nagios ; # GRANT SELECT ON V_$ASM_DISKGROUP to nagios ; # GRANT SELECT ON V_$DATAGUARD_STATS to nagios ; # GRANT SELECT ON V_$LOCK to nagios ; # GRANT SELECT ON V_$LOG_HISTORY to nagios ; # GRANT SELECT ON V_$PROCESS to nagios ; # GRANT SELECT ON V_$SESSION to nagios ; # GRANT SELECT ON V_$SESSION_WAIT to nagios ; # GRANT SELECT ON V_$SQLAREA to nagios ; # GRANT SELECT ON V_$SYSSTAT to nagios ; # GRANT SELECT ON V_$controlfile to nagios ; # GRANT SELECT ON V_$librarycache to nagios ; # GRANT SELECT ON V_$lock to nagios ; # GRANT SELECT ON V_$log to nagios ; # GRANT SELECT ON V_$log_history to nagios ; # GRANT SELECT ON V_$parameter to nagios ; # GRANT SELECT ON V_$recovery_file_dest to nagios ; # GRANT SELECT ON V_$session to nagios ; # GRANT SELECT ON V_$sysstat to nagios ; # GRANT SELECT ON DBA_DATA_FILES TO NAGIOS ; # GRANT SELECT ON DBA_EXTENTS TO NAGIOS ; # GRANT SELECT ON DBA_UNDO_EXTENTS TO NAGIOS ; # GRANT SELECT ON dba_data_files TO NAGIOS ; # GRANT SELECT ON dba_free_space TO NAGIOS ; # GRANT SELECT ON dba_objects TO NAGIOS ; # GRANT SELECT ON dba_source TO NAGIOS ; # GRANT SELECT ON dba_temp_files TO NAGIOS ; ######################################################################## # # CONSTANTS # ######################################################################## # EXIT STATUS STATE_OK=0 STATE_WARNING=1 STATE_CRITICAL=2 STATE_UNKNOWN=3 STATE_DEPENDENT=4 # /EXIT STATUS REVISION="6.6.6" # colors BOLD="\e[1m" GREEN="\e[32m" LIGHTGREEN="${BOLD}${GREEN}" RED="\033[1;31m" LIGHTRED="\033[1;31m" BLUE="\e[34m" LIGHTBLUE="${BOLD}${BLUE}" YELLOW="\e[33m" LIGHTYELLOW="${BOLD}${YELLOW}" WHITE="\033[0;37m" RESET="\033[0;00m" DEBUG=0 DEBUG=1 NOHEAD="SET HEAD OFF SET PAGES 0 SET FEED OFF SET TIMING OFF" ######################################################################## # # / CONSTANTS # ######################################################################## ######################################################################## # # FUNCTIONS # ######################################################################## # printf "%s${LIGHTRED}USAGE:${RESET} # $0 ORACLE_SID BACKUP_METHOD # # Where ORACLE_SID allowed: ${LIGHTGREEN}${KNOWNSIDS[*]}${RESET} # And BACKUP_METHOD allowed: ${LIGHTGREEN}${KNOWNTYPE[*]}${RESET}\n" # # VERY INITIAL CHECKS # H host # U oracle user # S sid # W warning # C critical # t tns # d db # l login # o ospassword <- NOT NECESSARY # s sessions # c cache # p parsing # b tablespace # u undo # g diskgroup # f FRA # r redogen # k locks # a dgstats # o totalspace usage() { echo -e "${LIGHTBLUE}USAGE${RESET} Mandatory options: -H destination_hostname -U oracle_linux_user -S ORACLE_SID Optional arguments (required for some checks): -W warning -C critical Checks: -t Check remote TNS server -d Check remote database (search /bin/ps for PMON process) -s Check remote database concurrent active sessions -l Attempt a dummy login and alert if not ORA-01017: invalid username/password -c Check remote database for library and buffer cache hit ratios -p Check remote database for Soft/Hard parse ratios -b Check remote database for ALL tablespaces capacity -u Check remote database for UNDO tablespace capacity -f Check remote database for FLASH_RECOVERY_AREA capacity -d Check remote database for diskgroup capacity in ORACLE_ASM_SID (Tipically +ASM1/2...) -a Dataguard statistics (Apply & Transport Lag). This check is done ON THE STANDBY (the master does not have information on V\$DATAGUARD_STATS. So ORACLE_SID and HOSTNAME must be the STANDBY ones. -r Daily check for yesterday's redo generation -k Watch for session locks (any lock with return CRITICAL) -o Total Space taken by the database Excluding sytem tablespaces. " exit 0 } oraerror_check() { local CHECKTHIS="$*" if [[ "${CHECKTHIS}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting sessions: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi return ${STATE_OK} } return_values() { local VALUE=$1 if [[ ${VALUE} -gt ${CRITICAL} ]] ; then MSG="CRITICAL" RETURNCODE=${STATE_CRITICAL} elif [[ ${VALUE} -gt ${WARNING} ]] ; then MSG="WARNING" RETURNCODE=${STATE_WARNING} elif [[ ${VALUE} -le ${WARNING} ]] ; then MSG="OK" RETURNCODE=${STATE_OK} else MSG="UNKNOWN" RETURNCODE=${STATE_UNKNOWN} fi echo ${MSG} return ${RETURNCODE} } reverse_return_values() { local VALUE=$1 if [[ ${VALUE} -lt ${CRITICAL} ]] ; then MSG="CRITICAL" RETURNCODE=${STATE_CRITICAL} elif [[ ${VALUE} -lt ${WARNING} ]] ; then MSG="WARNING" RETURNCODE=${STATE_WARNING} elif [[ ${VALUE} -ge ${WARNING} ]] ; then MSG="OK" RETURNCODE=${STATE_OK} else MSG="UNKNOWN" RETURNCODE=${STATE_UNKNOWN} fi echo ${MSG} return ${RETURNCODE} } # get_remote_oraclehome look for ORACLE_SID on oratab # so if you don't have ORACLE_SID in the oratab file, it will avoid # you can add a pseudo dummy line there... get_remote_oraclehome() { #set -x # Hunt down a reasonable ORACLE_HOME ORATABLIST="$(${SSH} "locate oratab" | grep -E "/oratab$" | tr '\n' ' ')" for ORATAB in ${ORATABLIST} ; do ORACLE_HOME=$(${SSH} "cat ${ORATAB}" | grep -E "^(${ORACLE_SID}|\*):" | awk -F: '{print $2}') if [[ "${ORACLE_HOME}" ]] && [ "$($SSH "ls -d ${ORACLE_HOME}" |wc -l)" -eq 1 ] ; then return 0 fi done return 1 } check_tns() { local AUX="${ORAENV} tnsping ${ORACLE_SID}" local TNSCHECK TNSCHECK="$(${SSH} "${AUX}")" # echo ${TNSCHECK} if [[ "${TNSCHECK}" =~ .*OK.*\(([0-9]{1,})\ .* ]] ; then return ${STATE_OK} else return ${STATE_CRITICAL} fi } check_db() { local PMONCHECK PMONCHECK="$(${SSH} "ps -ef" | grep -Ev grep | grep -c "ora_pmon_${ORACLE_SID}")" if [[ ${PMONCHECK} -ge 1 ]] ; then # echo "${ORACLE_SID} OK - ${PMONCHECK} PMON process(es) running" return ${STATE_OK} else # echo "${ORACLE_SID} Database is DOWN" return ${STATE_CRITICAL} fi } check_login() { local AUX="${ORAENV} echo 'select 1+1 from dual ;' | ${SQLPLUS}" local LOGINCHECK="$(${SSH} ${AUX} | egrep -c '^[[:space:]]{0,}2$')" if [ ${LOGINCHECK} -ge 1 ] ; then # echo "${ORACLE_SID} OK - dummy login connected" return ${STATE_OK} else # echo "${ORACLE_SID} - dummy login fail" return ${STATE_CRITICAL} fi } check_total_sessions() { local RETURNCODE=${STATE_UNKNOWN} local TOTALSESSIONS=0 local QUERY="${NOHEAD} set numf 99999 SELECT count(*) FROM V\\\$SESSION where username is not null and not username in ('SYS', 'PUBLIC', 'NAGIOS' ) / " local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}")" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting sessions: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi TOTALSESSIONS=$( echo ${RESSULT} | awk '{print $1}') MSG="$(return_values ${TOTALSESSIONS})" RETURNCODE=$? echo "${MSG} - ${ORACLE_SID} Total Sessions Count: ${TOTALSESSIONS} | Sessions=${TOTALSESSIONS};${WARNING};${CRITICAL}" return ${RETURNCODE} } check_asessions_v3() { local RETURNCODE=${STATE_UNKNOWN} local MAXINDEX=0 local i=0 local x=0 local TOTALSESSIONS=0 declare -a RESSULTARRAY declare -a RESSULTUSERS local QUERY="${NOHEAD} set numf 99999 SELECT username || ';' || count(username) FROM V\\\$SESSION where username is not null and not username in ('SYS', 'PUBLIC', 'NAGIOS') group by username order by 1 / " local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}")" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting sessions: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi for i in ${RESSULT} ; do RESSULTARRAY[$x]=$(echo ${i} | awk -F\; '{print $2}') RESSULTUSERS[$x]=$(echo ${i} | awk -F\; '{print $1}') [[ ${RESSULTARRAY[$x]} -gt ${RESSULTARRAY[$MAXINDEX]} ]] && MAXINDEX=$x let x++ done MSG="$(return_values ${RESSULTARRAY[$MAXINDEX]})" RETURNCODE=$? #echo "${MSG} - ${ORACLE_SID} All Oracle Opened Sessions Count: ${TOTALSESSIONS} | Sessions=${TOTALSESSIONS} $(for ((x=0; x<${#RESSULTARRAY[@]}; x++)) ; do printf "%s${RESSULTUSERS[${x}]}=${RESSULTARRAY[${x}]} " ; done)" if [[ ${RETURNCODE} -eq ${STATE_CRITICAL} || ${RETURNCODE} -eq ${STATE_WARNING} ]] ; then RETURNMSG="All Oracle Opened Sessions, User ${RESSULTUSERS[${MAXINDEX}]} has ${RESSULTARRAY[${MAXINDEX}]} Sessions" else RETURNMSG="All Oracle Opened Sessions" fi echo "${MSG} - ${ORACLE_SID} ${RETURNMSG} | $(for ((x=0; x<${#RESSULTARRAY[@]}; x++)) ; do printf "%s${RESSULTUSERS[${x}]}=${RESSULTARRAY[${x}]} " ; done)" return ${RETURNCODE} } check_sharedpool() { local RETURNCODE=${STATE_UNKNOWN} local SHAREDFREE=0 local SHAREDTOTAL=0 local SHAREDPERCENT=100 local QUERY="${NOHEAD} SELECT 'shared_pool_total=' || ROUND(SUM(BYTES)/1024/1024) FROM sys.V_\\\$SGASTAT WHERE POOL='shared pool' GROUP BY POOL; SELECT CONCAT(REPLACE(POOL,' ','_'),'_free') || '=' || ROUND(BYTES/1024/1024) FROM SYS.V_\\\$SGASTAT WHERE NAME LIKE 'free memory' ; " local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting sessions: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi SHAREDFREE=$(echo -e "${RESSULT}" | egrep "shared_pool_free" | awk -F\= '{print $2}') SHAREDTOTAL=$(echo -e "${RESSULT}" | egrep "shared_pool_total" | awk -F\= '{print $2}') SHAREDPERCENT=$(echo "100-${SHAREDFREE}*100/${SHAREDTOTAL}" | bc) MSG="$(return_values ${SHAREDPERCENT})" RETURNCODE=$? echo "${MSG} - ${ORACLE_SID} Shared Pool Percent ${SHAREDPERCENT}%|$(for i in ${RESSULT}; do printf "%s${i} "; done)" exit ${RETURNCODE} } check_developers() { local RESSULT="" local RETURNTHIS="" local QUERY="" WHERESTATEMENT="UPPER(program) IN('WEBDEV.WEBSERVER40.EXE','TOAD.EXE','SQL DEVELOPER','SQLPLUS.EXE')" RESSULTMSG=" Developers Opened Sessions Count" QUERY="${NOHEAD} set numf 999999 SELECT COUNT(*) FROM V\\\$SESSION WHERE ${WHERESTATEMENT} ; " # local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" # ${SSH} "${AUX}" # read local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" oraerror_check "${RESSULT}" RES=$? [ ${RES} -ne ${STATE_OK} ] && return ${RES} MSG="$(return_values ${RESSULT})" RETURNCODE=$? echo "${MSG} - ${ORACLE_SID} Total developer sessions : ${RESSULT}| Developers=${RESSULT}" return ${RETURNCODE} } # Included SYSTEM in the query's exclusion pattern to avoid reporting backup sessions. check_sessions() { local RETURNCODE=${STATE_UNKNOWN} local QUERY="${NOHEAD} set numf 99 select count(SES.SID) from V\\\$SESSION SES, V\\\$SQLAREA SQL, V\\\$SESSION_WAIT WA, V\\\$PROCESS P where SES.STATUS='ACTIVE' AND SES.SQL_ID=SQL.SQL_ID AND SES.SID=WA.SID and SES.paddr=p.addr and UPPER(SES.USERNAME) not in ( 'SYS','SYSMAN','MDSYS','SYSTEM','NAGIOS', 'DBSNMP' ) /" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting sessions: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi MSG="$(return_values ${RESSULT})" RETURNCODE=$? echo "${MSG} - ${ORACLE_SID} Concurrent Active Sessions Count: ${RESSULT} |Sessions=${RESSULT};${WARNING};${CRITICAL};0;20" return ${RETURNCODE} } # Included SYSTEM in the query's exclusion pattern to avoid reporting backup sessions. check_activesessions() { local RETURNCODE=${STATE_UNKNOWN} local TOTALSESSIONS=0 local PERFDATA="" local QUERY="${NOHEAD} set numf 999 select username || '=' || count(*) from v\\\$session where status='ACTIVE' and username not in ( 'SYS','SYSMAN','MDSYS','SYSTEM','NAGIOS', 'DBSNMP' ) group by username / " local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting sessions: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi for LINE in ${RESSULT} ; do PERFDATA="${PERFDATA} ${LINE}" TOTALSESSIONS=$((${TOTALSESSIONS}+$(echo ${LINE} | awk -F= '{print $2}'))) done MSG="$(return_values ${TOTALSESSIONS})" RETURNCODE=$? echo "${MSG} - ${ORACLE_SID} Concurrent Active Sessions Count: ${TOTALSESSIONS} |Sessions=${TOTALSESSIONS};${WARNING};${CRITICAL};0;20 ${PERFDATA}" return ${RETURNCODE} } check_checknewtickets() { local let RETURNCODE=${STATE_UNKNOWN} local let NEWTICKETS=0 local PERFDATA="" # local QUERY="${NOHEAD} #set numf 999 #select 'NewTickets =' || count(*) from DEVOLUIVA.requested_tickets where recption_date > sysdate - 0.010416; #" local QUERY="${NOHEAD} set numf 999 select count(*) from DEVOLUIVA.requested_tickets where recption_date > sysdate - 0.010416; " local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}' | egrep -v "^[[:space:]]{0,}$")" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting requested_tickets: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi # for LINE in ${RESSULT} ; do # PERFDATA="${PERFDATA} ${LINE}" # NEWTICKETS=$((${NEWTICKETS}+$(echo ${LINE} | awk -F= '{print $2}'))) # done NEWTICKETS=${RESSULT} PERFDATA="NewTickets=${NEWTICKETS}" MSG="$(reverse_return_values ${NEWTICKETS})" RETURNCODE=$? echo "${MSG} - ${ORACLE_SID} New requested tikets: ${NEWTICKETS} |NewTickets=${NEWTICKETS};${WARNING};${CRITICAL};0;20 ${PERFDATA}" return ${RETURNCODE} } check_cache() { local let RETURNCODE=${STATE_UNKNOWN} local QUERY="${NOHEAD} set numf 9999999.99 SELECT (1-(pr.value/(dbg.value+cg.value)))*100 from v\\\$sysstat pr, v\\\$sysstat dbg, v\\\$sysstat cg where pr.name='physical reads' and dbg.name='db block gets' and cg.name='consistent gets' /" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local LIBHITS="$(${SSH} "${AUX}" | awk '{print $1}')" local QUERY="${NOHEAD} set numf 9999999.99 select sum(lc.pins)/(sum(lc.pins)+sum(lc.reloads))*100 from v\\\$librarycache lc /" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local CACHEHITS="$(${SSH} "${AUX}" | awk '{print $1}')" if [[ "${CACHEHITS}" =~ .*(ORA\-[0-9]{1,}).* || "${LIBHITS}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting Cache: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi if ! [[ "${CACHEHITS}" =~ [0-9]{1,2}\.[0-9]{0,2} || "${LIBHITS}" =~ [0-9]{1,2}\.[0-9]{0,2} ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting Cache, values returned: ${CACHEHITS} , ${LIBHITS}" return ${STATE_CRITICAL} fi if [[ ${CACHEHITS/.*} -le ${CRITICAL} || ${LIBHITS/.*} -le ${CRITICAL} ]] ; then MSG="CRITICAL" RETURNCODE=${STATE_CRITICAL} elif [[ ${CACHEHITS/.*} -le ${WARNING} || ${LIBHITS/.*} -le ${WARNING} ]] ; then MSG="WARNING" RETURNCODE=${STATE_WARNING} elif [[ ${CACHEHITS/.*} -gt ${WARNING} && ${LIBHITS/.*} -gt ${WARNING} ]] ; then MSG="OK" RETURNCODE=${STATE_OK} else MSG="UNKNOWN" RETURNCODE=${STATE_UNKNOWN} fi echo "${MSG} - ${ORACLE_SID} - Cache Hit Rates: ${CACHEHITS}% Lib -- ${LIBHITS}% Buff|lib=${CACHEHITS}%;${CRITICAL};${WARNING};0;100 buffer=${LIBHITS}%;${CRITICAL};${WARNING};0;100" return ${RETURNCODE} } check_parsing() { local let RETURNCODE=${STATE_UNKNOWN} local QUERY="${NOHEAD} set numf 99999999999999 SELECT VALUE FROM V\\\$SYSSTAT WHERE NAME = 'parse count (total)' ; SELECT VALUE FROM V\\\$SYSSTAT WHERE NAME = 'parse count (hard)' ; SELECT VALUE FROM V\\\$SYSSTAT WHERE NAME = 'parse count (failures)' ; SELECT VALUE FROM V\\\$SYSSTAT WHERE NAME = 'parse count (describe)' ;" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | tr '\n' ' ')" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* || "${RESSULT}" =~ ^(([[:space:]]|)[0-9]{1,}){4}$ ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting parsing data: ${RESSULT}" return ${STATE_CRITICAL} fi # PARSING INDEXES like possitional parameter # TOTAL=1 # HARD=2 # FAIL=3 # DESCRIBE=4 SOFTPARSE="$(echo "${RESSULT}" | awk '{printf "%2.2f",($1-$2-$3-$4)/$1*100}')" HARDPARSE="$(echo "${RESSULT}" | awk '{printf "%2.2f",$2/$1*100}')" FAILEDPARSE="$(echo "${RESSULT}" | awk '{printf "%2.2f",$3/$1*100}')" if [[ ${SOFTPARSE/.*} -le ${CRITICAL} ]] ; then MSG="CRITICAL" RETURNCODE=${STATE_CRITICAL} elif [[ ${SOFTPARSE/.*} -le ${WARNING} ]] ; then MSG="WARNING" RETURNCODE=${STATE_WARNING} elif [[ ${SOFTPARSE/.*} -gt ${WARNING} ]] ; then MSG="OK" RETURNCODE=${STATE_OK} else MSG="UNKNOWN" RETURNCODE=${STATE_UNKNOWN} fi echo "${MSG} - ${ORACLE_SID} - Parse Ratio %: ${SOFTPARSE}% Soft -- ${HARDPARSE}% Hard -- ${FAILEDPARSE}% Failed|Soft=${SOFTPARSE}%;${CRITICAL};${WARNING};0;100 Hard=${HARDPARSE}%;${CRITICAL};${WARNING};0;100 Failed=${FAILEDPARSE}%;${CRITICAL};${WARNING};0;100" return ${RETURNCODE} } check_bigger_tables() { local let RETURNCODE=${STATE_UNKNOWN} # IN GIGABYTES #local BIGGERTHAN=2 local BIGGERTHAN=${WARNING} local QUERY="${NOHEAD} set numf 99999999999999 COL OWNER FORMAT A10; COL SEGMENT_NAME FORMAT A35; COL TABLESPACE_NAME FORMAT A35; SELECT SEGMENT_NAME || '=' || SUM_BYTES FROM ( SELECT SEGMENT_NAME, SUM(BYTES) SUM_BYTES FROM DBA_EXTENTS WHERE OWNER NOT IN ('SYS', 'SYSTEM' ) AND SEGMENT_TYPE='TABLE' GROUP BY SEGMENT_NAME, SEGMENT_TYPE, OWNER, TABLESPACE_NAME ) WHERE SUM_BYTES>$((${BIGGERTHAN}*1024*1024*1024)) ORDER BY SUM_BYTES DESC ;" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}")" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* || "${RESSULT}" =~ ^(([[:space:]]|)[0-9]{1,}){4}$ ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting parsing data: ${RESSULT}" return ${STATE_CRITICAL} fi for LINE in ${RESSULT} ; do PERFDATA="${LINE} ${PERFDATA}" done echo "OK - ${ORACLE_SID} - BIGGER tables|${PERFDATA}" printf "%s${RESSULT}\n" return ${STATE_OK} } # this version of the check is to cover #132284 check_sessionlock_v5() { ###################################################### # HARD LOCKS (CRITICAL) ###################################################### # type hard 1: v$lock based local QUERY="${NOHEAD} SELECT L1.SID || ';' || L2.SID FROM V\\\$LOCK L1, V\\\$LOCK L2 WHERE L1.BLOCK=1 AND L2.REQUEST > 0 AND L1.ID1=L2.ID1 AND L1.ID2=L2.ID2 / " local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | tr '\n' ' ')" if [[ "${RESSULT}" ]] ; then RETURNCODE=${STATE_CRITICAL} echo "CRITICAL - ${ORACLE_SID} HARD LOCKS ${RESSULT//;/ is blocking }" # return is here cause hardlock is much more important tan soft... return ${RETURNCODE} fi # type hard 2: v$session based local QUERY="${NOHEAD} select sid || '.' || serial# || ';' || username || ';' || osuser || ';' || WAIT_CLASS || ';' || EVENT THEINFO from v\\\$session where state='WAITING' AND WAIT_CLASS='Concurrency' / " local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}")" if [[ "${RESSULT}" ]] ; then RETURNCODE=${STATE_CRITICAL} echo "CRITICAL - ${ORACLE_SID} HARD LOCKS : $(echo -e "${RESSULT}" | wc -l) Sessions in lock" # return is here cause hardlock is much more important tan soft... echo -e "${RESSULT}" return ${RETURNCODE} fi ###################################################### # SOFT LOCKS (WARNING) ###################################################### local QUERY="${NOHEAD} SELECT lk.SID || '.' || se.SERIAL# || ';' || se.username || ';' || se.OSUser || ';' || lk.type THEINFO FROM v\\\$lock lk, v\\\$session se WHERE lk.type IN ( 'AT', 'IV', 'JQ', 'TA', 'TM', 'TX', 'UL', 'CU', 'LA', 'LB', 'LC', 'LD', 'LE', 'LF', 'LG', 'LH', 'LI', 'LJ', 'LK', 'LL', 'LM', 'LN', 'LO', 'LP', 'LQ', 'LR', 'LS', 'LT', 'LU', 'LV', 'LW', 'LX', 'LY', 'LZ', 'NA', 'NB', 'NC', 'ND', 'NE', 'NF', 'NG', 'NH', 'NI', 'NJ', 'NK', 'NL', 'NM', 'NN', 'NO', 'NP', 'NQ', 'NR', 'NS', 'NT', 'NU', 'NV', 'NW', 'NX', 'NY', 'NZ' ) AND lk.SID = se.SID AND SE.USERNAME NOT IN ('MANAGER_AGENDAMAKER', 'SYS', 'SYSTEM', 'DBSNMP') AND ( LK.ID1 in ( select object_id from dba_objects where object_name IN ( 'ESTABS', 'T_ENTERPRISES') AND OBJECT_TYPE='TABLE' ) or LK.ID2 in ( select object_id from dba_objects where object_name IN ( 'ESTABS', 'T_ENTERPRISES') AND OBJECT_TYPE='TABLE' ) ) order by lk.sid, se.username, se.osuser, lk.type ; " local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}")" if [[ "${RESSULT}" ]] ; then RETURNCODE=${STATE_WARNING} echo "WARNING - ${ORACLE_SID} SOFT LOCKS" echo -e "${RESSULT}" else RETURNCODE=${STATE_OK} echo "OK - ${ORACLE_SID} NO LOCK FOUND" fi return ${RETURNCODE} } check_sessionlock() { local let SESSIONLOCK=1 local let RETURNCODE=${STATE_UNKNOWN} local RETURNMSG="" local QUERY="${NOHEAD} set numf 99999999999999 SELECT COUNT(*) FROM V\\\$LOCK L1, V\\\$LOCK L2 WHERE L1.BLOCK=1 AND L2.REQUEST > 0 AND L1.ID1=L2.ID1 AND L1.ID2=L2.ID2 ;" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | tr '\n' ' ')" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* || "${RESSULT}" =~ ^(([[:space:]]|)[0-9]{1,}){4}$ ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting locks: ${RESSULT}" return ${STATE_CRITICAL} fi SESSIONLOCK=$(echo ${RESSULT}| awk '{print $1}') SIDLOCKER=$(echo ${RESSULT}| awk '{print $2}') if [[ ${SESSIONLOCK/.*} -gt 0 ]] ; then MSG="CRITICAL" RETURNCODE=${STATE_CRITICAL} # Getting lockers local QUERY="${NOHEAD} SET COLSEP \\\";\\\" COL SIDSERIAL FORMAT A15; COL HOSTNAME FORMAT A30; COL PROGRAM FORMAT A30; SELECT ses.sid || ',' || ses.serial# SIDSERIAL, SES.MACHINE HOSTNAME, SES.PROGRAM PROGRAM FROM V\\\$SESSION SES, V\\\$PROCESS P WHERE SES.paddr = p.addr AND SES.SID IN ( SELECT l1.sid FROM v\\\$lock l1, v\\\$lock l2 WHERE l1.block =1 AND l2.request > 0 AND l1.id1=l2.id1 AND l1.id2=l2.id2 AND ROWNUM=1 ) ORDER BY SES.MACHINE /" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" #Trimming the string local RESSULT="$(${SSH} "${AUX}"| awk '{print $1$2$3}')" # no spaces here (i think), so using for instead of readline for i in ${RESSULT} ; do RETURNMSG="$(echo ${i}| awk -F\; '{print $2";"$3}') ${PERFDATA}" done # while read LINE ; do # PERFDATA="$(echo ${LINE} | awk -F\; '{print $2"/"$3}') ; ${PERFDATA}" # echo ${LINE} # read # done < <(printf "%s${RESSULT}") EXTENDEDSTATUS="${RESSULT}" elif [[ ${SESSIONLOCK/.*} -eq 0 ]] ; then MSG="OK" RETURNCODE=${STATE_OK} EXTENDEDSTATUS="" RETURNMSG="No locks" else MSG="UNKNOWN" RETURNCODE=${STATE_UNKNOWN} fi echo "${MSG} - ${ORACLE_SID} LOCKS : ${RETURNMSG}" [[ "${EXTENDEDSTATUS}" ]] && printf "%s${EXTENDEDSTATUS}\n" return ${RETURNCODE} } check_sessionlock_extended() { local let SESSIONLOCK=1 local let RETURNCODE=${STATE_UNKNOWN} local RETURNMSG="" local TMPFILE=$(mktemp) local ALERTMAIL="dodger@ciberterminal.net" local QUERY="${NOHEAD} set numf 99999999999999 SELECT COUNT(*) FROM V\\\$LOCK L1, V\\\$LOCK L2 WHERE L1.BLOCK=1 AND L2.REQUEST > 0 AND L1.ID1=L2.ID1 AND L1.ID2=L2.ID2 ;" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | tr '\n' ' ')" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* || "${RESSULT}" =~ ^(([[:space:]]|)[0-9]{1,}){4}$ ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting locks: ${RESSULT}" return ${STATE_CRITICAL} fi SESSIONLOCK=$(echo ${RESSULT}| awk '{print $1}') SIDLOCKER=$(echo ${RESSULT}| awk '{print $2}') if [[ ${SESSIONLOCK/.*} -gt 0 ]] ; then MSG="CRITICAL" RETURNCODE=${STATE_CRITICAL} # Getting lockers local QUERY="${NOHEAD} SET COLSEP \\\";\\\" COL SIDSERIAL FORMAT A15; COL SSID FORMAT 999999; col SSERIAL FORMAT 999999; COL HOSTNAME FORMAT A30; COL PROGRAM FORMAT A30; SELECT SES.SID SSID, SES.SERIAL# SSERIAL, SES.MACHINE HOSTNAME, SES.PROGRAM PROGRAM, SES.SQL_ID FROM V\\\$SESSION SES, V\\\$PROCESS P WHERE SES.paddr = p.addr AND SES.SID IN ( SELECT l1.sid FROM v\\\$lock l1, v\\\$lock l2 WHERE l1.block =1 AND l2.request > 0 AND l1.id1=l2.id1 AND l1.id2=l2.id2 AND ROWNUM=1 ) ORDER BY SES.MACHINE /" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" #Trimming the string local RESSULT="$(${SSH} "${AUX}" | awk -F\; '{gsub(/^ +| +$/,"",$1);gsub(/^ +| +$/,"",$2);gsub(/^ +| +$/,"",$3);gsub(/^ +| +$/,"",$4);gsub(/^ +| +$/,"",$5)} {print $1";"$2";"$3";"$4";"$5}')" printf "%s${RESSULT}\n" >> ${TMPFILE} OFS="${IFS}" IFS=";" local AUXARRAY=( ${RESSULT} ) IFS="${OFS}" # if there's any SQLID (4th position), then try to get the SQL if [[ "${AUXARRAY[4]}" ]] ; then local QUERY="${NOHEAD} SELECT SQL_FULLTEXT FROM V\\\$SQLAREA SQL WHERE SQL.SQL_ID='${AUXARRAY[4]}' AND ROWNUM=1 /" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" ${SSH} "${AUX}" >> ${TMPFILE} # local RESSULT="$(${SSH} "${AUX}")" # printf "%s${RESSULT}\n" >> ${TMPFILE} fi # no spaces here (i think), so using for instead of readline for i in ${RESSULT} ; do RETURNMSG="$(echo ${i}| awk -F\; '{print $2";"$3}') ${PERFDATA}" done # don't know but the hostname is not trimmed anyway except using hardcore regexps... [[ "${AUXARRAY[2]}" =~ ^([[:alnum:][:graph:]]{1,100})[[:space:]]{1,}$ ]] && AUXARRAY[2]="${BASH_REMATCH[1]}" RETURNMSG="${AUXARRAY[2]}; ${AUXARRAY[3]}; ${AUXARRAY[4]}" EXTENDEDSTATUS="$(cat ${TMPFILE})" # sending by mail the ressult cat ${TMPFILE} | mail -s "${MSG} - ${ORACLE_SID} LOCKS : ${RETURNMSG}" ${ALERTMAIL} elif [[ ${SESSIONLOCK/.*} -eq 0 ]] ; then MSG="OK" RETURNCODE=${STATE_OK} EXTENDEDSTATUS="" RETURNMSG="No locks" else MSG="UNKNOWN" RETURNCODE=${STATE_UNKNOWN} fi echo "${MSG} - ${ORACLE_SID} LOCKS : ${RETURNMSG}" [[ "${EXTENDEDSTATUS}" ]] && printf "%s${EXTENDEDSTATUS}\n" rm -f ${TMPFILE} return ${RETURNCODE} } all_tablespaces_space() { declare -a RESSULTARRAY declare -a WARNINGARRAY declare -a CRITICALARRAY declare -a OKARRAY local QUERY="${NOHEAD} SELECT TABLESPACE_NAME || '=' || REPLACE(PERCENT, ' ') FROM ( SELECT TABLESPACE_NAME,to_char(((MAX_MB-REAL_FREE_MB)/MAX_MB*100),'00') PERCENT FROM ( SELECT MAXUSAGE.TABLESPACE_NAME, MAXUSAGE.MAX_MB, CASE WHEN MAXUSAGE.ACTUAL_DATAFILE_MB < MAXUSAGE.MAX_MB THEN MAX_MB-(ACTUAL_DATAFILE_MB-FREE_MB) ELSE FREE_MB END REAL_FREE_MB FROM ( SELECT TABLESPACE_NAME, (CASE WHEN INNER_MAX_MB < INNER_ACTUAL_DATAFILE_MB THEN INNER_ACTUAL_DATAFILE_MB ELSE INNER_MAX_MB END) MAX_MB, INNER_ACTUAL_DATAFILE_MB ACTUAL_DATAFILE_MB FROM ( SELECT TABLESPACE_NAME, SUM(CASE WHEN MAXBYTES > 0 THEN MAXBYTES ELSE BYTES END)/1024/1024 INNER_MAX_MB, SUM(BYTES)/1024/1024 INNER_ACTUAL_DATAFILE_MB FROM DBA_DATA_FILES GROUP BY TABLESPACE_NAME ) INNER_USAGE ) MAXUSAGE, ( SELECT TABLESPACE_NAME, SUM(BYTES)/1024/1024 FREE_MB FROM dba_free_space GROUP BY TABLESPACE_NAME ) FREEUSAGE WHERE MAXUSAGE.TABLESPACE_NAME=FREEUSAGE.TABLESPACE_NAME ) ALL_TABLESPACES_SPACE order by TABLESPACE_NAME ) ; " local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting ${RETURNMSG}: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi RESSULTARRAY=( ${RESSULT} ) for ((x=0; x<${#RESSULTARRAY[@]}; x++)) ; do PERFDATA="${PERFDATA} ${RESSULTARRAY[$x]}" TABLESPACENAME="$(echo ${RESSULTARRAY[$x]} | awk -F\= '{print $1}')" TABLESPACEPERCENT=$(echo ${RESSULTARRAY[$x]} | awk -F\= '{print $2}') #echo -e "${LIGHTGREEN}${TABLESPACENAME}${RESET}=${LIGHTRED}${TABLESPACEPERCENT}${RESET}" if [[ ${TABLESPACEPERCENT} -ge ${CRITICAL} ]] ; then CRITICALARRAY+=( "${TABLESPACENAME}=${TABLESPACEPERCENT}" ) elif [[ ${TABLESPACEPERCENT} -ge ${WARNING} ]] ; then WARNINGARRAY+=( "${TABLESPACENAME}=${TABLESPACEPERCENT}" ) else OKARRAY+=( "${TABLESPACENAME}=${TABLESPACEPERCENT}" ) fi done if [[ ${#CRITICALARRAY[@]} -gt 0 ]] ; then MSG="CRITICAL" echo "${MSG} - ${ORACLE_SID} Check Tablespace(s) Space: ${CRITICALARRAY[@]} ${WARNINGARRAY[@]} | ${CRITICALARRAY[@]} ${WARNINGARRAY[@]} ${OKARRAY[@]}" return ${STATE_CRITICAL} elif [[ ${#WARNINGARRAY[@]} -gt 0 ]] ; then MSG="WARNING" echo "${MSG} - ${ORACLE_SID} Check Tablespace(s) Space: ${CRITICALARRAY[@]} ${WARNINGARRAY[@]} | ${CRITICALARRAY[@]} ${WARNINGARRAY[@]} ${OKARRAY[@]}" return ${STATE_WARNING} else MSG="OK" echo "${MSG} - ${ORACLE_SID} ALL Tablespaces Space | ${CRITICALARRAY[@]} ${WARNINGARRAY[@]} ${OKARRAY[@]}" return ${STATE_OK} fi } generic_space_check() { local CHECK="$1" local OBJECTNAME="$2" case ${CHECK,,} in "undo" ) local QUERY="${NOHEAD} set numf 9999999.99 select TOTALSPACE.TOTAL TOTAL_SPACE, TOTALSPACE.TOTAL-NVL(USEDSPACE.USED,0.0) FREE_SPACE FROM ( SELECT TABLESPACE_NAME, SUM(MAXBYTES)/1024/1024 TOTAL FROM DBA_DATA_FILES WHERE TABLESPACE_NAME = (SELECT value FROM V\\\$parameter WHERE name = 'undo_tablespace') GROUP BY TABLESPACE_NAME ) TOTALSPACE LEFT OUTER JOIN ( SELECT TABLESPACE_NAME, SUM(BYTES)/1024/1024 USED FROM DBA_UNDO_EXTENTS WHERE (STATUS='UNEXPIRED' OR STATUS='ACTIVE') AND TABLESPACE_NAME = (SELECT value FROM V\\\$parameter WHERE name = 'undo_tablespace') GROUP BY TABLESPACE_NAME ) USEDSPACE ON TOTALSPACE.TABLESPACE_NAME=USEDSPACE.TABLESPACE_NAME ;" OBJECTNAME=UNDO ;; "tablespace" ) local QUERY="${NOHEAD} SET NUMF 99999999.99 SELECT MAX_MB, REAL_FREE_MB FREE_MB FROM ( SELECT MAXUSAGE.TABLESPACE_NAME, MAXUSAGE.MAX_MB, CASE WHEN MAXUSAGE.ACTUAL_DATAFILE_MB < MAXUSAGE.MAX_MB THEN MAX_MB-(ACTUAL_DATAFILE_MB-FREE_MB) ELSE FREE_MB END REAL_FREE_MB FROM ( select TABLESPACE_NAME, SUM(case when MAXBYTES > 0 then MAXBYTES else BYTES END)/1024/1024 MAX_MB, SUM(BYTES)/1024/1024 ACTUAL_DATAFILE_MB FROM DBA_DATA_FILES GROUP BY TABLESPACE_NAME ) MAXUSAGE, ( select TABLESPACE_NAME, SUM(BYTES)/1024/1024 FREE_MB FROM dba_free_space GROUP BY TABLESPACE_NAME ) FREEUSAGE WHERE MAXUSAGE.TABLESPACE_NAME=FREEUSAGE.TABLESPACE_NAME AND MAXUSAGE.TABLESPACE_NAME = '${OBJECTNAME}' ) ;" ;; "diskgroup" ) local QUERY="${NOHEAD} SET NUMF 9999999999 SELECT TOTAL_MB, NVL(FREE_MB,0.0) FREE_MB FROM V\\\$ASM_DISKGROUP WHERE NAME='${OBJECTNAME}' ;" ;; "fra") local QUERY="${NOHEAD} set numf 99999999999999 SELECT (SUM(SPACE_LIMIT))/1024/1024 TOTAL, (SUM(SPACE_LIMIT-SPACE_USED))/1024/1024 FREE, (SUM(SPACE_USED))/1024/1024 USED FROM v\\\$recovery_file_dest ; " OBJECTNAME=FLASH_RECOVERY_AREA ;; * ) echo "CRITICAL - Function generic_space_check received wrong parameter : ${CHECK} " return ${STATE_CRITICAL} ;; esac local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}")" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* || "${RESSULT}" =~ ^(([[:space:]]|)[0-9]{1,}){2}$ || ! "${RESSULT}" ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting ${CHECK^} usage: ${RESSULT}" return ${STATE_CRITICAL} fi local TOTAL="$(echo ${RESSULT} | awk '{print $1}')" local FREE="$(echo ${RESSULT} | awk '{print $2}')" local USED="$(echo "${RESSULT}" | awk '{printf "%2.2f",$1-$2}')" local PERCENT="$(echo "${RESSULT}" | awk '{printf "%2.2f",100-($2/$1*100)}')" MSG="$(return_values ${PERCENT/.*})" RETURNCODE=$? echo "${MSG} - ${ORACLE_SID} ${CHECK^} ${OBJECTNAME} : ${PERCENT}%, Used : ${USED} of ${TOTAL} MB |${OBJECTNAME}=${PERCENT};${WARNING};${CRITICAL};0;20" return ${RETURNCODE} } asmfs_space_check() { local OBJECTNAME="$1" # symlink patch local AUX="readlink ${OBJECTNAME}" local RESSULT="$(${SSH} "${AUX}" 2> /dev/null)" if [[ "${RESSULT}" ]] ; then # the provided fs is a symlink if [[ "${RESSULT}" =~ ^\/.*$ ]] ; then OBJECTNAME=${RESSULT} else OBJECTNAME=$(dirname ${OBJECTNAME})/$(basename ${RESSULT}) fi fi local AUX="df -P ${OBJECTNAME} | egrep ${OBJECTNAME}" local RESSULT="$(${SSH} "${AUX}" 2> /dev/null)" #if [[ ! "${RESSULT}" =~ ^(\/|[a-z]{1,4}[a-z0-9]{1,8}:\/).*%.*${OBJECTNAME}$ ]] ; then if [[ ! "${RESSULT}" =~ ^(\/|[a-z]{1,4}[a-z0-9]{1,8}:\/|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:).*%.*${OBJECTNAME}$ ]] ; then echo "CRITICAL - Error getting ${COMMAND} space for ${OBJECTNAME}" return ${STATE_CRITICAL} fi local TOTAL="$(echo ${RESSULT} | awk '{print $2*1024}')" local FREE="$(echo ${RESSULT} | awk '{print $4*1024}')" local USED="$(echo "${RESSULT}" | awk '{printf $3*1024}')" local PERCENT="$(echo "${RESSULT}" | awk '{printf $5}')" local WARNINGVALUE="$(echo ${TOTAL} ${WARNING} | awk '{printf "%.2f",$1*$2/100}')" local CRITICALVALUE="$(echo ${TOTAL} ${CRITICAL} | awk '{printf "%.2f",$1*$2/100}')" MSG="$(return_values ${PERCENT//%/})" RETURNCODE=$? echo "${MSG} - ${CHECK^} ${OBJECTNAME} : ${PERCENT}, Used : $((${USED}/1024/1024/1024)) GB of $((${TOTAL}/1024/1024/1024)) GB |size=${TOTAL}B used=${USED}B;${WARNINGVALUE};${CRITICALVALUE};0;${TOTAL}" return ${RETURNCODE} } # This check needs SYS/ AS SYSDBA priviledge as connect to the standby (supposed to be in mount state) dataguard_stats_new() { local ORAENVSID="${ORAENV} export ORACLE_SID=${ORACLE_SID} ;" local let RETURNCODE=${STATE_UNKNOWN} local SQLPLUS="sqlplus -s '/ as sysdba'" local TRANSPORTLAG="" local APPLYLAG="" local QUERY="${NOHEAD} set numf 99999999999999 SELECT NVL(VALUE,'+00 00:00:00') FROM V\\\$DATAGUARD_STATS WHERE (NAME LIKE 'apply lag' OR NAME LIKE 'transport lag') ;" local AUX="${ORAENVSID} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}")" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* || "${RESSULT}" =~ ^(([[:space:]]|)[0-9]{1,}){4}$ ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting dataguard data: ${RESSULT}" return ${STATE_CRITICAL} fi TRANSPORTLAG="$(echo "${RESSULT}" | head -1)" APPLYLAG="$(echo "${RESSULT}" | head -2| tail -1)" # echo "Transport: ${TRANSPORTLAG}" # echo "Apply: ${APPLYLAG}" # read TRANSPORTLAGSECONDS=$(echo "(((${TRANSPORTLAG:1:2}*24)+${TRANSPORTLAG:4:2})*60+${TRANSPORTLAG:7:2})*60+${TRANSPORTLAG:10:2}" | bc) APPLYLAGSECONDS=$(echo "(((${APPLYLAG:1:2}*24)+${APPLYLAG:4:2})*60+${APPLYLAG:7:2})*60+${APPLYLAG:10:2}" | bc) if [ ${TRANSPORTLAGSECONDS} -gt ${APPLYLAGSECONDS} ] ; then MSG="$(return_values ${TRANSPORTLAGSECONDS})" RETURNCODE=$? else MSG="$(return_values ${APPLYLAGSECONDS})" RETURNCODE=$? fi echo "${MSG} - Dataguard stats for ${ORACLE_SID} - TransportLag: ${TRANSPORTLAG} ApplyLag: ${APPLYLAG}|transport=${TRANSPORTLAGSECONDS} apply=${APPLYLAGSECONDS};${WARNING};${CRITICAL};0;86400" return ${RETURNCODE} } # to use this function you must create the table and grant permissions to nagios user: # CREATE TABLE NAGIOS.TOTALSPACE (MYDATE VARCHAR(8), TOTALSPACE FLOAT(30)); # GRANT INSERT, UPDATE, DELETE ON NAGIOS.TOTALSPACE TO NAGIOS ; # GRANT UNLIMITED TABLESPACE TO NAGIOS ; totalspace_delta() { local let RETURNCODE=${STATE_UNKNOWN} local TODAY="$(date +%Y%m%d)" local YESTERDAY="$(date --date=yesterday +%Y%m%d)" local DAYBEFOREY="$(date --date='2 days ago' +%Y%m%d)" local let TOTALSPACE=0 local let TOTALSPACEY=0 local let DELTA=0 # quering for totalspace to our custom table local QUERY="${NOHEAD} SELECT TOTALSPACE FROM NAGIOS.TOTALSPACE WHERE MYDATE='${YESTERDAY}' AND ROWNUM=1 ;" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting ${RETURNMSG}: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi # if the totalspace is logged on table, that will be the returned value #if [[ "${RESSULT}" ]] ; then if [[ "${RESSULT}" =~ ^[0-9]{1,}$ ]] ; then TOTALSPACE=${RESSULT} else # if there's no value in the table, then we must calculate it and then update the table local QUERY="${NOHEAD} set numf 9999999999 SELECT SUM(BYTES)/1024/1024 TOTAL_MB FROM DBA_DATA_FILES /" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" TOTALSPACE=${RESSULT} local QUERY="${NOHEAD} set numf 9999999999 INSERT INTO NAGIOS.TOTALSPACE VALUES ('${YESTERDAY}', '${TOTALSPACE}') ; commit ; " local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" fi # quering for 2 days ago totalspace to our custom table local QUERY="${NOHEAD} SELECT TOTALSPACE FROM NAGIOS.TOTALSPACE WHERE MYDATE='${DAYBEFOREY}' AND ROWNUM=1;" local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" # if there's no 2 days ago totalspace, then DELTA must be 0 if [[ "${RESSULT}" =~ ^[0-9]{1,}$ ]] ; then DELTA=$(echo "${TOTALSPACE} ${RESSULT}" | awk '{print $1-$2}') else DELTA=0 fi #printf "%s${RESSULT}" echo "OK - ${ORACLE_SID} TotalSpace Delta: ${DELTA} |TotalSpaceDelta=${DELTA}" return 0 } #This a statistics-only control, so it always return OK unless it can't connect to Oracle statistics_check() { local CHECK=$1 local let RETURNCODE=${STATE_UNKNOWN} unset RETURNMSG declare -a RETURNMSG case "${CHECK,,}" in "old_totalspace_simple" ) RETURNMSG[0]="TOTAL DB SPACE" RETURNMSG[1]="TotalSpace" local QUERY="${NOHEAD} set numf 9999999999 SELECT SUM(BYTES)/1024/1024 TOTAL_MB FROM DBA_DATA_FILES /" ;; "totalspace_simple" ) RETURNMSG[0]="TOTAL DB SPACE" RETURNMSG[1]="TotalSpace" local QUERY="${NOHEAD} select ( select sum(bytes)/1024/1024 data_size from dba_data_files ) + ( select nvl(sum(bytes),0)/1024/1024 temp_size from dba_temp_files ) + ( select sum(bytes)/1024/1024 redo_size from sys.v_\\\$log ) + ( select sum(BLOCK_SIZE*FILE_SIZE_BLKS)/1024/1024 controlfile_size from v\\\$controlfile) TOTAL_MB from dual /" ;; "redogen" ) RETURNMSG[0]="Redo generation" RETURNMSG[1]="RedoGen" local QUERY="${NOHEAD} set numf 9999999999 SELECT Round(A.COUNT#*B.AVG#/1024/1024) YESTERDAY_REDOGEN_MB FROM ( SELECT To_Char(First_Time,'YYYY-MM-DD') DAY, COUNT(1) COUNT#, MIN(RECID) MIN#, MAX(RECID) MAX# FROM v\\\$log_history WHERE To_Char(First_Time,'YYYY-MM-DD')=To_Char(SYSDATE-1,'YYYY-MM-DD') GROUP BY To_Char(First_Time,'YYYY-MM-DD') ORDER BY 1 DESC ) A, ( SELECT Avg(BYTES) AVG# FROM v\\\$log ) B /" ;; "plsqllines") local QUERY="${NOHEAD} set numf 9999999999 select count(*) from dba_source where NAME IN ( select object_NAME from dba_objects where object_type in ('PROCEDURE', 'PACKAGE BODY', 'PACKAGE', 'TYPE BODY', 'TYPE', 'FUNCTION') ) and owner not in ('SYS', 'SYSTEM', 'PUBLIC' ) ;" ;; * ) echo "CRITICAL - Wrong value on function statistics_check: ${CHECK}" return ${STATE_CRITICAL} ;; esac local AUX="${ORAENV} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error getting ${RETURNMSG}: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi if [ $(echo ${RESSULT} | wc -w) -gt 1 ] ; then RESSULTARRAY=( ${RESSULT} ) local let x=0 PERFDATA="" STATUSINFO="" for i in ${RETURNMSG[1]} ; do PERFDATA="${PERFDATA} $i=${RESSULTARRAY[$x]}" STATUSINFO="${STATUSINFO} $i: ${RESSULTARRAY[$x]}" let x++ done echo "OK - ${ORACLE_SID} ${STATUSINFO} |${PERFDATA}" else echo "OK - ${ORACLE_SID} ${RETURNMSG[0]}: ${RESSULT} |${RETURNMSG[1]}=${RESSULT}" fi return 0 } check_password_expiration() { #local AUX="chage -l oracle | egrep \"^Password expires\" | cut -d\: -f 2" local EXPIREDATE="$(${SSH} "chage -l ${ORACLE_OSUSER}" | egrep "^Password expires" | cut -d\: -f 2)" local TIMESLICESECONDS=0 if [[ "${EXPIREDATE}" = " never" ]] ; then # xD local EXPIREEPOH=$(date --date="Jan 1, 2999" +%s) else local EXPIREEPOH=$(date --date="${EXPIREDATE}" +%s) fi local ACTUALDATE=$(date +%s) local TIMESLICESECONDS=$((${EXPIREEPOH}-${ACTUALDATE})) local TIMESLICE=$((${TIMESLICESECONDS}/60/60/24)) MSG="$(reverse_return_values ${TIMESLICE})" RETURNCODE=$? echo "${MSG} - Password Expires in ${TIMESLICE} days" return ${RETURNCODE} } check_userslocked() { local USERGROUPS="" USERGROUPS=( 'DBA' 'CORE' 'CRON' 'EXTRA' 'INTRA' 'MANAGER' 'MIRINDA' 'BACKEND' 'INTEGRACION' ) #SELECT '' || USERNAME || '' FROM SYS.DBA_users WHERE ( local QUERY="${NOHEAD} SELECT USERNAME FROM SYS.DBA_users WHERE ( $(for ((x=0;x<${#USERGROUPS[@]};x++)); do echo "USERNAME like '${USERGROUPS[${x}]}\\_%' ESCAPE '\\' OR"; done ) USERNAME = 'JHOLGADO' ) and NOT USERNAME LIKE '%\\_VOXELDEV' ESCAPE '\\' AND ACCOUNT_STATUS LIKE 'LOCK%' ORDER BY USERNAME ; " local AUX="${ORAENV} echo -e \"\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}'| tr '\n' ' ')" if [[ "${RESSULT}" ]] ; then RETURNCODE=${STATE_CRITICAL} echo "CRITICAL - ${ORACLE_SID} Production USER locked: ${RESSULT}" else RETURNCODE=${STATE_OK} echo "OK - ${ORACLE_SID} All Production USERS unlocked" fi return ${RETURNCODE} } check_seqapply() { if [[ "${ORACLE_SID}" =~ (.*)GDN$ ]] ; then local AUXSID=${BASH_REMATCH[1]} #echo ${AUXSID} local AUXSID="$(${SSH} "ps -ef" | grep -v grep | grep "ora_pmon_${AUXSID}" | awk '{print $8}' | sed 's/ora_pmon_//g')" ORACLE_SID="${AUXSID}" fi local ORAENVSID="${ORAENV} export ORACLE_SID=${ORACLE_SID} ;" local SQLPLUS="sqlplus -s '/ as sysdba'" local RETURNTHIS="" local EXTENDEDINFORMATION="" local QUERY="" QUERY="${NOHEAD} SELECT (ARCH.SEQUENCE# - APPL.SEQUENCE#) Difference FROM (SELECT THREAD# ,SEQUENCE# FROM V\\\$ARCHIVED_LOG WHERE (THREAD#,FIRST_TIME ) IN (SELECT THREAD#,MAX(FIRST_TIME) FROM V\\\$ARCHIVED_LOG GROUP BY THREAD#)) ARCH, (SELECT THREAD# ,SEQUENCE# FROM V\\\$LOG_HISTORY WHERE (THREAD#,FIRST_TIME ) IN (SELECT THREAD#,MAX(FIRST_TIME) FROM V\\\$LOG_HISTORY GROUP BY THREAD#)) APPL WHERE ARCH.THREAD# = APPL.THREAD# ORDER BY 1; " #local AUX="${ORAENV} echo -e \"\n${QUERY}\" | ${SQLPLUS}" local AUX="${ORAENVSID} printf \"%s\n${QUERY}\" | ${SQLPLUS}" local RESSULT="$(${SSH} "${AUX}" | awk '{print $1}')" if [[ "${RESSULT}" =~ .*(ORA\-[0-9]{1,}).* ]] ; then echo "CRITICAL - ${ORACLE_SID} Error executing query: ${BASH_REMATCH[1]}" return ${STATE_CRITICAL} fi local DIFFERENCE=$(echo ${RESSULT} | awk -F\; '{print $1}') MSG="$(return_values ${DIFFERENCE})" RETURNCODE=$? RETURNTHIS="${MSG} - ${ORACLE_SID} Apply difference = ${DIFFERENCE}" echo "${RETURNTHIS}" if [[ ${RETURNCODE} -ne ${STATE_OK} ]] ; then EXTENDEDINFORMATION="AppyDifference=${DIFFERENCE}" echo "${EXTENDEDINFORMATION}" fi return ${RETURNCODE} } printmsg() { echo -e "$*" } abort_message() { local let ABORTCODE=1 [[ ${EXITCODE} -ne 0 ]] && ABORTCODE=${EXITCODE} printmsg "${LIGHTRED}ERROR${RESET}: $*" exit ${ABORTCODE} } # debug_me uses variable ${DEBUG} debug_me() { if [[ "${DEBUG}" && ${DEBUG} -eq 0 ]] ; then echo -e "${LIGHTBLUE}DEBUG: ${RESET}$*" fi } ######################################################################## # # / FUNCTIONS # ######################################################################## ######################################################################## # # VARIABLES # ######################################################################## PROGNAME=$(basename $0) PROGPATH=$(dirname $0) ## getops ###[ $# -le 1 ] && usage $* ## getops ### ## getops ###REMOTE_SERVER=$2 && shift 2 ## getops ### ## getops ###if [[ ! ${REMOTE_SERVER} ]] ## getops ###then ## getops ### echo "No remote server specified!!!" ## getops ### exit ${STATE_UNKNOWN} ## getops ###fi ## getops ### ## getops #### Checking for non-standard user to connect ## getops ###if [[ "${1}" = "-U" ]] ## getops ###then ## getops ### ORACLE_OSUSER=$2 && shift 2 ## getops ###else ## getops ### ORACLE_OSUSER="oracle" ## getops ###fi ## getops ### ## getops ###SSH="ssh ${ORACLE_OSUSER}@${REMOTE_SERVER} -xq" ORACLEUSER="NAGIOS" ORACLEUSERPASSWORD="D2HSHBFMO5IINME9I9WT" ######################################################################## # # / VARIABLES # ######################################################################## ######################################################################## # # MAIN # ######################################################################## while getopts "H:U:S:W:C:tdloscpbugfrhkaDF" arg; do case $arg in # H host H) REMOTE_SERVER=${OPTARG} ;; # U oracle user U) ORACLE_OSUSER="${OPTARG}" ;; # S sid S) ORACLE_SID="${OPTARG}" ;; # W warning W) WARNING="${OPTARG}" ;; # C critical C) CRITICAL="${OPTARG}" ;; # t tns t) COMMAND="tns" ;; # d db d) COMMAND="db" ;; # l login l) COMMAND="login" ;; # o ospassword <- not necessary # o totalspace o) #COMMAND="ospassword" COMMAND="totalspace" ;; # s sessions s) COMMAND="sessions" ;; # c cache c) COMMAND="cache" ;; # p parsing p) COMMAND="parsing" ;; # b tablespace b) #COMMAND="tablespace" COMMAND="alltablespacesspace" ;; # u undo u) COMMAND="undo" ;; # g diskgroup g) COMMAND="diskgroup" ;; # f FRA f) COMMAND="fra" ;; # r redogen r) COMMAND="redogen" ;; # k sessionlock k) COMMAND="sessionlock" ;; # a dgstats a) COMMAND="dgstats" ;; h) usage ;; F) MAYTHEFORCEBEWITHYOU=true echo -e "${LIGHTBLUE}The force is strong in you?${RESET}" ;; D) DEBUG=0 ;; *) usage ;; esac done # mandatory ops if [[ ! "${REMOTE_SERVER}" ]] ; then debug_me "No REMOTE_SERVER" usage fi if [[ ! "${ORACLE_OSUSER}" ]] ; then debug_me "No ORACLE_OSUSER" usage fi if [[ ! "${ORACLE_SID}" ]] ; then debug_me "No ORACLE_SID" usage fi if [[ ! "${WARNING}" || ! "${CRITICAL}" ]] ; then debug_me "no warning or critical, maybe this will fail" fi if [[ ! "${COMMAND}" ]] ; then debug_me "No COMMAND received" usage fi SSH="ssh ${ORACLE_OSUSER}@${REMOTE_SERVER} -xq" get_remote_oraclehome RES=$? if [[ ${RES} -ne 0 ]] ; then echo "CRITICAL - ORACLE_HOME not found" exit ${STATE_CRITICAL} fi # SQLPLUS FOR CONNECTIONS SQLPLUS="sqlplus -s '${ORACLEUSER}/${ORACLEUSERPASSWORD}@${ORACLE_SID}'" ORAENV="ORACLE_HOME=${ORACLE_HOME};PATH=$PATH:$ORACLE_HOME/bin;LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib;export ORACLE_HOME PATH LD_LIBRARY_PATH;" debug_me "${SSH}" debug_me "${SQLPLUS}" debug_me "${ORAENV}" debug_me "${COMMAND}" case "${COMMAND}" in "tns") check_tns RES=$? if [ ${RES} -eq ${STATE_OK} ] ; then echo "OK - reply time ${BASH_REMATCH[1]} from ${ORACLE_SID}" else echo "CRITICAL - No TNS Listener on ${ORACLE_SID}" fi ;; "db") check_db RES=$? if [ ${RES} -eq ${STATE_OK} ] ; then echo "OK - ${ORACLE_SID} Database running" else echo "CRITICAL - ${ORACLE_SID} Database is DOWN" fi ;; "login") check_login RES=$? if [ ${RES} -eq ${STATE_OK} ] ; then echo "OK - ${ORACLE_SID} dummy login connected" else echo "CRITICAL - ${ORACLE_SID} dummy login fail" fi ;; "asessions") check_asessions_v3 RES=$? ;; "tsessions") check_total_sessions RES=$? ;; "seqapply") check_seqapply; RES=$? ;; "sessions") # here the message is printed inside the function, sorry #check_sessions check_activesessions RES=$? ;; "cache") check_cache RES=$? ;; "parsing") check_parsing RES=$? ;; "undo") generic_space_check undo RES=$? ;; "tablespace") generic_space_check tablespace "${TSDG}" RES=$? ;; "diskgroup") generic_space_check diskgroup "${TSDG}" RES=$? ;; "asmfs") ASMFS_DISK=${ORACLE_SID} asmfs_space_check ${ASMFS_DISK} RES=$? ;; "fra") # check_FRA generic_space_check fra RES=$? ;; "dgstats") dataguard_stats_new RES=$? ;; "redogen") statistics_check redogen RES=$? ;; "totalspace") #statistics_check totalspace statistics_check totalspace_simple RES=$? ;; "totalspacedelta") totalspace_delta RES=$? ;; "sessionlock") check_sessionlock RES=$? ;; "newtickets") check_checknewtickets RES=$? ;; "locksextended") check_sessionlock_v5 #check_sessionlock_v4 #check_sessionlock_v3 #check_sessionlock_extended RES=$? ;; "biggertables") check_bigger_tables RES=$? ;; "sharedpool") check_sharedpool RES=$? ;; "developers") check_developers RES=$? ;; "activesessions") check_activesessions RES=$? ;; "ospassword") check_password_expiration RES=$? ;; "userslocked") check_userslocked RES=$? ;; "sessionlockv5") check_sessionlock_v5 RES=$? ;; "alltablespacesspace") all_tablespaces_space RES=$? ;; "plsqllines") statistics_check plsqllines ;; *) exit $STATE_UNKNOWN ;; esac # EXIT STATUS # STATE_OK=0 # STATE_WARNING=1 # STATE_CRITICAL=2 # STATE_UNKNOWN=3 # STATE_DEPENDENT=4 # /EXIT STATUS #WIP exit ${RES}