nagios_oracle_check_plugin/check_remote_oracle
2023-06-20 09:38:16 +02:00

1862 lines
53 KiB
Bash
Executable File

#!/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}