summaryrefslogtreecommitdiffstats
path: root/web/attachments/420074-check_oracle_1.4.15_tsmax_negwarncritlev_easymode_bugfixcache_bugfixperfdatatsmax.patch
blob: c4b1b1990c1bde7b18382443dab01092727acef4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
--- check_oracle	2010-10-07 17:11:31.000000000 +0200
+++ co	2011-08-02 18:23:37.000000000 +0200
@@ -8,18 +8,24 @@
 
 PROGNAME=`basename $0`
 PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'`
-REVISION="1.4.15"
+REVISION="1.4.15-negativewarncrit"
 
 . $PROGPATH/utils.sh
 
+dflt_cachwarn="95%"
+dflt_cachcrit="97%"
+dflt_tswarn="85%"
+dflt_tscrit="95%"
+dflt_tsname="SYSTEM"
+
 
 print_usage() {
   echo "Usage:"
   echo "  $PROGNAME --tns <Oracle Sid or Hostname/IP address>"
   echo "  $PROGNAME --db <ORACLE_SID>"
   echo "  $PROGNAME --login <ORACLE_SID>"
-  echo "  $PROGNAME --cache <ORACLE_SID> <USER> <PASS> <CRITICAL> <WARNING>"
-  echo "  $PROGNAME --tablespace <ORACLE_SID> <USER> <PASS> <TABLESPACE> <CRITICAL> <WARNING>"
+  echo "  $PROGNAME --cache <ORACLE_SID> [USER] [PASS] [CRITICAL] [WARNING]"
+  echo "  $PROGNAME --tablespace <ORACLE_SID> [USER] [PASS] [TABLESPACE] [CRITICAL] [WARNING] [maxbytes]"
   echo "  $PROGNAME --oranames <Hostname>"
   echo "  $PROGNAME --help"
   echo "  $PROGNAME --version"
@@ -40,11 +46,11 @@
   echo "--login SID"
   echo "   Attempt a dummy login and alert if not ORA-01017: invalid username/password"
   echo "--cache"
-  echo "   Check local database for library and buffer cache hit ratios"
+  echo "   Check local database for library and buffer cache hit ratios (default warn:$dflt_cachwarn,crit:$dflt_cachcrit)"
   echo "       --->  Requires Oracle user/password and SID specified."
-  echo "       		--->  Requires select on v_$sysstat and v_$librarycache"
+  echo "       		--->  Requires select on v_\$sysstat and v_\$librarycache"
   echo "--tablespace"
-  echo "   Check local database for tablespace capacity in ORACLE_SID"
+  echo "   Check local database for tablespace capacity in ORACLE_SID (default warn:$dflt_tswarn,crit:$dflt_tscrit,ts:$dflt_tsname)"
   echo "       --->  Requires Oracle user/password specified."
   echo "       		--->  Requires select on dba_data_files and dba_free_space"
   echo "--oranames Hostname"
@@ -54,6 +60,12 @@
   echo "--version"
   echo "   Print version and license information"
   echo ""
+  echo " <WARNING>/<CRITICAL> can either be a percentage (ie. '15%') or a size in Mega/Giga/Terabyte (ie. '2G'; dflt: M)"
+  echo " Prepend the size with minus to be notified for a certain level below the maximum value,"
+  echo " ie. '-2G' to be warned 2G before 'SIZE' (-t) or 'MAXBYTES' (-T) tablespace runs out."
+  echo ""
+  echo "If <USER> and <PASS> are left blank, ie. \"\", \`sqlplus -s / as sysdba\` is tried instead."
+  echo ""
   echo "If the plugin doesn't work, check that the ORACLE_HOME environment"
   echo "variable is set, that ORACLE_HOME/bin is in your PATH, and the"
   echo "tnsnames.ora file is locatable and is properly configured."
@@ -66,6 +78,54 @@
   support
 }
 
+
+# convert_warncrit_val( warnlevel/critlevel ): returns in either % or units of M, no matter what input the user provided
+ReturnVal=
+ReturnUnit=
+convert_warncrit_val() {
+    input=$1;	totalsize=$2
+    tmp=0;	tmpunit=""
+    [ `expr index "$input" "%"` -gt 1 ] && tmp=`echo "scale=0; ${input%*%} * $totalsize" | bc | sed 's/\.[0-9]*$//g'` && tmpunit="%"
+    if [ "$tmp" = "0" ]; then
+      [ `expr index "$input" "G"` -gt 1 ] && tmp=$[ ${input%*G}*1000 ] && tmpunit="M"
+      [ `expr index "$input" "T"` -gt 1 ] && tmp=$[ ${input%*T}*1000*1000 ] && tmpunit="M"
+      if [ "$tmp" = "0" ]; then			# default: M
+        foo=$input
+        [ `expr index "$input" "M"` -gt 1 ] && foo=$[ ${input%*M} ] && tmpunit="M"
+        tmp=$foo
+      fi
+    fi
+
+    [ $tmp -lt 0 ] && tmp=$[ $totalsize + $tmp ]	# ie. -2G
+    [ $tmp -lt 0 ] && tmp=0				# ie. the result of the line before was below zero => set to zero.
+
+    ReturnVal=$tmp
+    ReturnUnit=$tmpunit
+    return
+}
+
+
+# do_warncrit_test(warnlevel, critlevel)
+do_warncrit_test() {
+    convert_warncrit_val $1 100;   tmpwarn=$ReturnVal	# use "100" as "size" for percentile checks, since we don't have that already
+    convert_warncrit_val $2 100;   tmpcrit=$ReturnVal
+    
+    if [ $tmpwarn -lt 0 ]; then				# ie. -2G
+      if [ $tmpwarn -gt $tmpcrit ]; then
+        echo "UNKNOWN - Warning level is less than Crit"
+        exit $STATE_UNKNOWN
+      fi
+    else
+      if [ $tmpwarn -gt $tmpcrit ]; then
+        echo "UNKNOWN - Warning level is more than Crit"
+        exit $STATE_UNKNOWN
+      fi
+    fi
+}
+
+
+
+
 case "$1" in
 1)
     cmd='--tns'
@@ -171,8 +231,13 @@
 	    #exit $STATE_OK
 	#fi
     else
-	echo "${2} Database is DOWN"
-	exit $STATE_CRITICAL
+	if [ "${2}" != "" ]; then
+	  echo "${2} - Database is DOWN (or doesn't exist)"
+	  exit $STATE_CRITICAL
+    	else
+          echo "UNKNOWN - Please supply a database name"
+          exit $STATE_UNKNOWN
+	fi
     fi
     ;;
 --login)
@@ -188,11 +253,24 @@
     fi
     ;;
 --cache)
-    if [ ${5} -gt ${6} ] ; then
-	echo "UNKNOWN - Warning level is less then Crit"
-	exit $STATE_UNKNOWN
+
+    [ "$#" -lt 2 ] && print_usage && exit	# use empty user/pass for default connection / as sysdba, use empty warncrit for dflt-warncrit
+
+    realwarn=$dflt_cachwarn
+    realcrit=$dflt_cachcrit
+    [ "$6" != "" ] && realwarn=$6
+    [ "$5" != "" ] && realcrit=$5
+
+    do_warncrit_test "$realwarn" "$realcrit"
+
+    if [ `expr index "$realwarn" "%"` -lt 1 ]; then
+      echo "${2} UNKNOWN - cache check can only use % value for warn/crit level."
+      exit $STATE_UNKNOWN
     fi
-    result=`sqlplus -s ${3}/${4}@${2} << EOF
+
+    cmdsqlplus="sqlplus -s / as sysdba"
+    [ "$3" != "" ] && [ "$4" != "" ] && cmdsqlplus="sqlplus -s ${3}/${4}@${2}"
+    result=`$cmdsqlplus << EOF
 set pagesize 0
 set numf '9999999.99'
 select (1-(pr.value/(dbg.value+cg.value)))*100
@@ -210,7 +288,7 @@
 
     buf_hr=`echo "$result" | awk '/^[0-9\. \t]+$/ {print int($1)}'` 
     buf_hrx=`echo "$result" | awk '/^[0-9\. \t]+$/ {print $1}'` 
-    result=`sqlplus -s ${3}/${4}@${2} << EOF
+    result=`$cmdsqlplus << EOF
 set pagesize 0
 set numf '9999999.99'
 select sum(lc.pins)/(sum(lc.pins)+sum(lc.reloads))*100
@@ -226,59 +304,105 @@
     lib_hr=`echo "$result" | awk '/^[0-9\. \t]+$/ {print int($1)}'`
     lib_hrx=`echo "$result" | awk '/^[0-9\. \t]+$/ {print $1}'`
 
-    if [ $buf_hr -le ${5} -o $lib_hr -le ${5} ] ; then
-  	echo "${2} CRITICAL - Cache Hit Rates: $lib_hrx% Lib -- $buf_hrx% Buff|lib=$lib_hrx%;${6};${5};0;100 buffer=$buf_hrx%;${6};${5};0;100"
+    # for actually usable warn/crit levels with higher precision number
+    convert_warncrit_val "$realwarn" 10000;  compwarn=$ReturnVal  # $ReturnUnit is being used directly, should be of same type.
+    convert_warncrit_val "$realcrit" 10000;  compcrit=$ReturnVal
+    # just snip of the % of the input to get perfdata
+    perfwarn=${realwarn%*%}
+    perfcrit=${realcrit%*%}
+
+    newbufhr=`echo "$buf_hrx * 10000" | bc -l | sed 's/\.[0-9]*$//g'`
+    newlibhr=`echo "$lib_hrx * 10000" | bc -l | sed 's/\.[0-9]*$//g'`
+
+    if [ $newbufhr -le $compcrit -o $newlibhr -le $compcrit ] ; then
+  	echo "${2} CRITICAL - Cache Hit Rates: $lib_hrx% Lib -- $buf_hrx% Buff|lib=$lib_hrx$ReturnUnit;$perfwarn$ReturnUnit;$perfcrit$ReturnUnit;0; buffer=$buf_hrx$ReturnUnit;$perfwarn$ReturnUnit;$perfcrit$ReturnUnit;0;"
 	exit $STATE_CRITICAL
     fi
-    if [ $buf_hr -le ${6} -o $lib_hr -le ${6} ] ; then
-  	echo "${2} WARNING  - Cache Hit Rates: $lib_hrx% Lib -- $buf_hrx% Buff|lib=$lib_hrx%;${6};${5};0;100 buffer=$buf_hrx%;${6};${5};0;100"
+    if [ $newbufhr -le $compwarn -o $newlibhr -le $compwarn ] ; then
+  	echo "${2} WARNING  - Cache Hit Rates: $lib_hrx% Lib -- $buf_hrx% Buff|lib=$lib_hrx$ReturnUnit;$perfwarn$ReturnUnit;$perfcrit$ReturnUnit;0; buffer=$buf_hrx$ReturnUnit;$perfwarn$ReturnUnit;$perfcrit$ReturnUnit;0;"
 	exit $STATE_WARNING
     fi
-    echo "${2} OK - Cache Hit Rates: $lib_hrx% Lib -- $buf_hrx% Buff|lib=$lib_hrx%;${6};${5};0;100 buffer=$buf_hrx%;${6};${5};0;100"
+    echo "${2} OK - Cache Hit Rates: $lib_hrx% Lib -- $buf_hrx% Buff|lib=$lib_hrx$ReturnUnit;$perfwarn$ReturnUnit;$perfcrit$ReturnUnit;0; buffer=$buf_hrx$ReturnUnit;$perfwarn$ReturnUnit;$perfcrit$ReturnUnit;0;"
 
     exit $STATE_OK
     ;;
 --tablespace)
-    if [ ${6} -lt ${7} ] ; then
-	echo "UNKNOWN - Warning level is more then Crit"
-	exit $STATE_UNKNOWN
-    fi
-    result=`sqlplus -s ${3}/${4}@${2} << EOF
+
+    [ "$#" -lt 2 ] && print_usage && exit	# use empty user/pass for default connection / as sysdba, use empty warncrit for dflt-warncrit...
+
+    tsname="$dflt_tsname"
+    [ -n "$5" ] && tsname="$5"
+
+    realwarn="$dflt_tswarn"
+    realcrit="$dflt_tscrit"
+    [ "$7" != "" ] && realwarn="$7"
+    [ "$6" != "" ] && realcrit="$6"
+    do_warncrit_test "$realwarn" "$realcrit"
+
+    cmdsqlplus="sqlplus -s / as sysdba"
+    [ "$3" != "" ] && [ "$4" != "" ] && cmdsqlplus="sqlplus -s ${3}/${4}@${2}"
+    result=`$cmdsqlplus << EOF
 set pagesize 0
 set numf '9999999.99'
-select NVL(b.free,0.0),a.total,100 - trunc(NVL(b.free,0.0)/a.total * 1000) / 10 prc
+select ROUND(a.maxi,0) MAXI, ROUND(a.total,0) ALLOCATED, ROUND(a.total-b.free,0) USED, ROUND(b.free,0) FREE, ROUND(a.maxi-a.total+b.free,0) FREEMAXI
 from (
-select tablespace_name,sum(bytes)/1024/1024 total
+select tablespace_name,sum(NVL(bytes,0))/1024/1024 total,sum(NVL(maxbytes,0))/1024/1024 maxi
 from dba_data_files group by tablespace_name) A
 LEFT OUTER JOIN
-( select tablespace_name,sum(bytes)/1024/1024 free
+( select tablespace_name,sum(NVL(bytes,0))/1024/1024 free
 from dba_free_space group by tablespace_name) B
-ON a.tablespace_name=b.tablespace_name WHERE a.tablespace_name='${5}';
+ON a.tablespace_name=b.tablespace_name WHERE a.tablespace_name='${tsname}';
 EOF`
 
     if [ -n "`echo $result | grep ORA-`" ] ; then
       error=` echo "$result" | grep "ORA-" | head -1`
-      echo "CRITICAL - $error"
+      echo "${2} : ${tsname} CRITICAL - $error"
       exit $STATE_CRITICAL
     fi
 
-    ts_free=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($1)}'` 
-    ts_total=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($2)}'` 
-    ts_pct=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($3)}'` 
-    ts_pctx=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print $3}'` 
+    ts_total=
+    ts_used=
+    ts_free=
+    if [ "${8}" = "max" ]; then
+      ts_total=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($1)}'` 
+      ts_used=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($3)}'` 
+      ts_free=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($5)}'`
+    else
+      ts_total=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($2)}'`
+      ts_used=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($3)}'`
+      ts_free=`echo "$result" | awk '/^[ 0-9\.\t ]+$/ {print int($4)}'`
+    fi
+ 
+    if [ "$ts_total" = "" ]; then
+      echo "${2} : ${tsname} UNKNOWN - no data was returned"
+      exit $STATE_UNKNOWN
+    fi
+ 
+    ts_pctx=`echo "scale=2; $ts_used/$ts_total * 100" | bc -l`
+    ts_pct=`echo "scale=0; $ts_used/$ts_total * 100" | bc -l`
+
+    # if percentage supplied, use percentage in perfdata
+    [ `expr index "%" "$realwarn"` -gt 0 ] && ts_total=1
+
+    convert_warncrit_val "$realwarn" $ts_total;   compwarn=$ReturnVal # $ReturnUnit is either % or M for the perfdata
+    convert_warncrit_val "$realcrit" $ts_total;   compcrit=$ReturnVal
+
+    perfused=$ts_pctx
+    [ "$ReturnUnit" != "%" ] && perfused=$[ $ts_total - $ts_free ] && ReturnUnit="M"
+
     if [ "$ts_free" -eq 0 -a "$ts_total" -eq 0 -a "$ts_pct" -eq 0 ] ; then
-        echo "No data returned by Oracle - tablespace $5 not found?"
+        echo "${2} : ${tsname} UNKNOWN - No data returned by Oracle - tablespace ${tsname} not found?"
         exit $STATE_UNKNOWN
     fi
-    if [ "$ts_pct" -ge ${6} ] ; then
-  	echo "${2} : ${5} CRITICAL - $ts_pctx% used [ $ts_free / $ts_total MB available ]|${5}=$ts_pctx%;${7};${6};0;100"
+    if [ "$ts_pct" -ge "$compcrit" ] ; then
+  	echo "${2} : ${tsname} CRITICAL - $ts_pctx% used [ $ts_free / $ts_total MB available ]|${tsname}=$perfused$ReturnUnit;$compwarn$ReturnUnit;$compcrit$ReturnUnit;0;"
 	exit $STATE_CRITICAL
     fi
-    if [ "$ts_pct" -ge ${7} ] ; then
-  	echo "${2} : ${5} WARNING  - $ts_pctx% used [ $ts_free / $ts_total MB available ]|${5}=$ts_pctx%;${7};${6};0;100"
+    if [ "$ts_pct" -ge "$compwarn" ] ; then
+  	echo "${2} : ${tsname} WARNING  - $ts_pctx% used [ $ts_free / $ts_total MB available ]|${tsname}=$perfused$ReturnUnit;$compwarn$ReturnUnit;$compcrit$ReturnUnit;0;"
 	exit $STATE_WARNING
     fi
-    echo "${2} : ${5} OK - $ts_pctx% used [ $ts_free / $ts_total MB available ]|${5}=$ts_pctx%;${7};${6};0;100"
+    echo "${2} : ${tsname} OK - $ts_pctx% used [ $ts_free / $ts_total MB available ]|${tsname}=$perfused$ReturnUnit;$compwarn$ReturnUnit;$compcrit$ReturnUnit;0;"
     exit $STATE_OK
     ;;
 *)