forked from hugme/Nag_checks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck_linux_net
executable file
·422 lines (359 loc) · 16.2 KB
/
check_linux_net
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
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
#!/bin/bash
##############################################
## This project was built to check networking
## from the servers point of view. It is
## nice for a device which you don't have
## access to network hardware such as a
## public cloud or managed NOC.
##
## You can find the lastest version of my
## nagios checks here: https://github.com/hugme/Nag_checks
##############################################
##############################################
## Set some user variables
##############################################
TMP_DIR="/tmp/check_linux_net"
IFCONFIG="/sbin/ifconfig"
NETDEV="/proc/net/dev"
###################################################
## We call them functions because they're fun
###################################################
print_help() {
cat << EOF
Last Modified: 2013.10.31
Usage: check_linux_net
Options:
-h = Display the help page
-hh = Display an extended help page with calculations
Basic Arguments
-i [interface] = Interface, or leave blank for all
-m [tmp suffix] = suffix to use for temporary files.
-l = Show data since the last run instead of per second
-d [debug level] = debug for testing (do not run on nagios with debug on)
To set your warning and critical levels
-ki[0-9999999999] = Your warning level in kilobytes IN.
-ko [0-9999999999] = Your warning level in kilobytes OUT.
-kt [0-9999999999] = Your warning level in kilobytes TOTAL
-pi [0-999999] = Your warning level in packets IN.
-po [0-999999] = Your warning level in packets OUT.
-pt [0-999999] = Your warning level in packets TOTAL.
-ei [0-9999] = Your warning level errors IN
-eo [0-9999] = Your warning level errors OUT
-et [0-9999] = Your warning level errors TOTAL
-di[0-9999] = Your warning level for dropped packets
-Ki [0-9999999999] = Your critical level in kilobytes IN.
-Ko 0-9999999999] = Your critical level in kilobytes OUT.
-Kt 0-9999999999] = Your critical level in kilobytes TOTAL.
-Pi [0-999999] = Your critical level in packets IN.
-Po [0-999999] = Your critical level in packets OUT.
-Pt [0-999999] = Your critical level in packets TOTAL.
-Ei [0-9999] = Your critical level errors IN
-Eo [0-9999] = Your critical level errors OUT
-Et [0-9999] = Your critical level errors TOTAL
-Di [0-9999] = Your critical level for dropped packets
To adjust performance data
-D [B,K,M,G,T] = divider B=bytes, K=kilobytes, M=megabytes, G=gigabytes, T=terabytes
(for performance data)
-b = output is in bits instead of bytes
-S [SHOW] = a list of the performance data you would like to see seperated by
commas. If order is important they will output in the same order
you give them. The default is:
DATA_TOT,PKT_TOT,ERR_TOT,DROP
Show Data
DATA_IN = Amount of data incomming. Kilobytes by default, change this default
with -d.
DATA_OUT = Amount of data outgoing. Kilobytes by default, change this default
with -d.
DATA_TOT = Amount of total data. Kilobytes by default, change this default
with -d.
PKT_IN = Number of packing incomming
PKT_OUT = Number of packing outgoing
PKT_TOT = Number of packing total
ERR_IN = Incomming packet errors
ERR_OUT = Outgoing packet errors
ERR_TOT = Total packet errors
DROP = Dropped packets. These are incoming only.
Leaving your warking and/or critical blank or setting them to 0 will disable the alert. This is
useful if you are only trying to build statictical data.
Leaving your divider blank will show in bytes. If your REALLY useing this to watch more than a
terabyte of traffic go by every 5 minutes let me know... That's just cool. If you need it it's
there.
The temporary directory is required and can be changed as a variable within the script. If you
want to run this script in multiple intervals make sure you use -m so the temporary
files don't overlap.
EOF
}
print_ext_help() {
cat << EOF
###############################
## EXTENDED HELP INFORMATION ##
###############################
This check relys on the kernel and the network driver for the interface it's checking. I was going to
pull data driectly from the hardware however these calls are expensive on the system and I would
prefer as little impact as possible. This being said the data is only as accurate as the kernel and
network driver can provide. Keep this in mind when especially using experimental or new code.
All calculations are done in Bytes. If you set it for bits (-b) it will calulate it before displaying
as: Bytes * 8 = Bits
Other calculations are as followes
1 Kilobyte = 2^10 Bytes
1 Megabyte = 2^20 Bytes
1 Gigabyte = 2^30 Bytes
1 Terabyte = 2^40 Bytes
EOF
}
print_error() {
printf "\nError: \n"
status_messages[$DISTILLER_UNKNOWN]="Something is wrong with your script, you should check it"
print_help
exit 3
}
check_for_number() {
[[ -n $(echo "$1"|tr -d [:digit:]) ]] && echo 1
}
check_for_alnum() {
[[ -n $(echo "$1"|tr -d [:alnum:]) ]] && echo 1
}
set_warn() {
[[ $X_STATUS != 2 ]] && X_STATUS=1
}
##############################################
## Suck in the user input
##############################################
unset WARN CRIT SHOW_DATA DIV INT MON DEBUG BIT ERROR
while [[ -n "$1" ]]; do
case $1 in
--help) print_help ; exit 0 ;;
-h) print_help ; exit 0 ;;
-hh) print_help; print_ext_help ; exit 0 ;;
-ki) WARN[11]=$2; shift ;;
-ko) WARN[12]=$2; shift ;;
-kt) WARN[13]=$2; shift ;;
-pi) WARN[21]=$2; shift ;;
-po) WARN[22]=$2; shift ;;
-pt) WARN[23]=$2; shift ;;
-ei) WARN[31]=$2; shift ;;
-eo) WARN[32]=$2; shift ;;
-et) WARN[33]=$2; shift ;;
-di) WARN[50]=$2; shift ;;
-Ki) CRIT[11]=$2; shift ;;
-Ko) CRIT[12]=$2; shift ;;
-Kt) CRIT[13]=$2; shift ;;
-Pi) CRIT[21]=$2; shift ;;
-Po) CRIT[22]=$2; shift ;;
-Pt) CRIT[23]=$2; shift ;;
-Ei) CRIT[31]=$2; shift ;;
-Eo) CRIT[32]=$2; shift ;;
-Et) CRIT[33]=$2; shift ;;
-Di) CRIT[50]=$2; shift ;;
-S) SHOW_DATA=$2; shift ;;
-D) DIV=$2; shift ;;
-b) SHOW_BITS="ON";;
-l) LAST_RUN="ON";;
-i) INT=$2; shift ;;
-m) MON="${2}_"; shift
[[ -n "$(check_for_alnum $MON)" ]] && ERROR="$ERROR\nInvalad characters were found in your temporary file suffix" ;;
-d) DEBUG="1";;
-dd) DEBUG="1";;
esac
shift
done
[[ -n $SHOW_BITS ]] && BB_TYPE="bits" || BB_TYPE="bytes"
[[ -n $LAST_RUN ]] && LR_TYPE="since the last run" || LR_TYPE="Per Second"
WARN_NAME[11]="$BB_TYPE $LR_TYPE in"
WARN_NAME[12]="$BB_TYPE $LR_TYPE out"
WARN_NAME[13]="$BB_TYPE $LR_TYPE total"
WARN_NAME[21]="Packets $LR_TYPE in"
WARN_NAME[22]="Packets $LR_TYPE out"
WARN_NAME[23]="Packets $LR_TYPE total"
WARN_NAME[31]="Errors in"
WARN_NAME[32]="Errors out"
WARN_NAME[33]="Errors total"
##############################################
## Set the defaults if needed
##############################################
[ -z "$DIV" ] && DIV="b"
case $DIV in
b|B) DIVNUM=1;unset DIV;PERF_DIV=B;;
k|K) DIVNUM=1024; DIV="K";PERF_DIV=KB;;
m|M) DIVNUM=1048576; DIV="M";PERF_DIV=MB;;
g|G) DIVNUM=1073741824; DIV="G";PERF_DIV=GB;;
t|T) DIVNUM=1099511627776; DIV="T";PERF_DIV=TB;;
*) ERROR="Invalid Divider (-D argument)"
esac
##############################################
## Check user input
##############################################
for CK_TYPE in {11..13} {21..23} {31..33}; do
unset BAD_CHAR
[[ -z "${WARN[$CK_TYPE]}" && -n "${CRIT[$CK_TYPE]}" ]] && ERROR="$ERROR\nWarning amount for ${WARN_NAME[$CK_TYPE]} was missing"
[[ -n "${WARN[$CK_TYPE]}" ]] && {
[ -z ${CRIT[$CK_TYPE]} ] && ERROR="$ERROR\nCritical amount for ${WARN_NAME[$CK_TYPE]} was missing"
[[ -n $(check_for_number "${WARN[$CK_TYPE]}") ]] && {
ERROR="$ERROR\nInvalid Characters in warning for ${WARN_NAME[$CK_TYPE]}"
BAD_CHAR=YES
}
[[ -n $(check_for_number "${CRIT[$CK_TYPE]}") ]] && {
ERROR="$ERROR\nInvalid Characters in critical for ${WARN_NAME[$CK_TYPE]}"
BAD_CHAR=YES
}
[[ -z $BAD_CHAR ]] && {
case $CK_TYPE in
1[1-3]) [[ "${WARN[$CK_TYPE]}" -ge 10000000000 ]] && ERROR="$ERROR\nYour $BB_TYPE warning is set too high"
[[ "${CRIT[$CK_TYPE]}" -ge 10000000000 ]] && ERROR="$ERROR\nYour $BB_TYPE critical is set too high" ;;
2[1-3]) [[ "${WARN[$CK_TYPE]}" -ge 1000000 ]] && ERROR="$ERROR\nYour packet warning is set too high"
[[ "${CRIT[$CK_TYPE]}" -ge 1000000 ]] && ERROR="$ERROR\nYour packet critical is set too high" ;;
3[1-3]) [[ "${WARN[$CK_TYPE]}" -ge 10000 ]] && ERROR="$ERROR\nYour error warning is set too high"
[[ "${CRIT[$CK_TYPE]}" -ge 10000 ]] && ERROR="$ERROR\nYour error critical is set too high" ;;
esac
}
}
done
##############################################
## Check Stuff; fix if needed
##############################################
[[ ! -d $TMP_DIR ]] && { mkdir -p $TMP_DIR || ERROR="$ERROR\nSorry, I could not make the directory"; }
[[ -n $IFACE && -n $(grep "${IFACE}:" /proc/net/dev) ]] && ERROR="$ERROR\nThe interface $IFACE does not exist"
##############################################
## Do the work
## grab the lines we need
## Print the information
##############################################
[[ $DEBUG == 1 ]] && {
echo "This is how you have me set up"
echo "Interfaces = $INT"
for CK_TYPE in {11..13} {21..23} {31..33}; do
echo "Warning Level-${WARN_NAME[$CK_TYPE]} = ${WARN[$CK_TYPE]}"
echo "Critical Level${WARN_NAME[$CK_TYPE]} = ${CRIT[$CK_TYPE]}"
done
echo "Show Data = $SHOW_DATA"
[[ -n $LAST_RUN ]] && echo "I will show from the last run." || echo "I will show the average per second"
[[ -n $SHOW_BITS ]] && echo "I will show in Bits." || echo "I will show in bytes."
}
[[ -z $ERROR ]] && {
[[ $WARN != 0 ]] && VAR_INFO=" -v warn=$WARN"
[[ $CRIT != 0 ]] && VAR_INFO=" -v crit=$CRIT"
[[ -n $DIV ]] && VAR_INFO=" -v divnum=$DIVNUM"
## multiple interfaces hasn't been tested yet
## fixed? there is a divide by zero error if it's run too soon
## fixed? error checking needs to be added inside the "for"
## debugging needs to be added
[[ -z $INT ]] && INT="$(awk -F : '{if ($1 !~ "^Inter-" && $1 !~ "face" && $1 !~ "lo$") print $1}' $NETDEV)"
# EPOC=0 IN_PKT=1 IN_ERR=2 IN_DROP=3 IN_BYTE=4 OUT_PKT=5 OUT_ERR=6 OUT_BYTE=7 COLL=8 TOT_PKT=50 TOT_ERR=51 TOT_BYTE=52
[[ $DEBUG == 1 ]] && {
printf "\nThis is the data I found:\n"
printf "These are all the interfaces on the box: $(awk -F : '{if ($1 !~ "^Inter-" && $1 !~ "face" && $1 !~ "lo$") print $1}' $NETDEV)\n"
}
for IFACE in $INT; do
[[ $DEBUG == 1 ]] && {
printf "I am processing for: $IFACE\n"
}
## Gather information
TMP_NAME="$TMP_DIR/${MON}${IFACE}"
sed -n "s/${IFACE}:\(.*\)/\1/p" $NETDEV | awk -v epoc=$(date +%s) '{print epoc" "$2" "$3" "$4" "$1" "$10" "$11" "$9" "$4}' > ${TMP_NAME}_new
[[ -f $TMP_NAME ]] && {
unset NEW LAST i
NEW=($(cat ${TMP_NAME}_new) )
LAST=($(cat ${TMP_NAME}) )
for i in {0..8} ; do
[[ -n ${NEW[$i]} && -n ${LAST[$i]} ]] && {
CURRENT[$i]=$((${NEW[$i]}-${LAST[$i]}))
[[ -z $LAST_RUN && $i != 0 ]] && CURRENT[$i]=$(echo "${CURRENT[$i]}/${CURRENT[0]}"|bc)
}
[[ $DEBUG == 1 ]] && {
DEBUG_DATA="\tLast Run:\t${LAST[$i]}\n\t\t\tThis Run:\t${NEW[$i]}\n\t\t\tDifference:\t${CURRENT[$i]}"
case $i in
0) printf "Time:\t\t\tLast Run:\t$(echo ${LAST[$I]}| awk '{print strftime("%c",$1)}')\n\t\tSeconds since last run:\t${CURRENT[$i]}" ;;
1) printf "Incomming Packets:$DEBUG_DATA";;
2) printf "Incomming Errors:$DEBUG_DATA";;
3) printf "Incomming dropped:$DEBUG_DATA";;
4) printf "Incomming Bytes:$DEBUG_DATA";;
5) printf "Outgoing Packets:$DEBUG_DATA";;
6) printf "Outgoing Errors:$DEBUG_DATA";;
7) printf "Outgoing Bytes:\t$DEBUG_DATA";;
8) printf "Collisions:\t$DEBUG_DATA";;
esac
printf "\n"
}
done
}
## Check information for errors
for i in {0..8} ; do
[[ -z ${CURRENT[$i]} ]] && ERROR="$ERROR\n Input data is missing. check your -i argument"
[[ ${CURRNET[$i]} -lt 0 ]] && exit 0
done
[[ ${CURRENT[0]} == 0 ]] && ERROR="$ERROR\n You must wait at least 1 second before running this script again"
[[ ! -f $TMP_NAME && -f ${TMP_NAME}_new ]] && {
mv ${TMP_NAME}_new $TMP_NAME
echo "Network First Run: OK |"
exit 0
}
## Print information
[[ -z $ERROR ]] && {
mv ${TMP_NAME}_new $TMP_NAME
CURRENT[50]=$((${CURRENT[1]}+${CURRENT[5]}))
CURRENT[51]=$((${CURRENT[2]}+${CURRENT[6]}))
CURRENT[52]=$((${CURRENT[4]}+${CURRENT[7]}))
for i in 4 7 52 ; do
[[ $SHOW_BITS == ON && $i != 0 ]] && {
CURRENT[$i]=$(echo "${CURRENT[$i]}*8"|bc)
}
CURRENT[$i]=$(echo "${CURRENT[$i]}/$DIVNUM" | bc)
done
[[ $SHOW_BITS == ON ]] && {
DIV="${DIV}bits"
} || {
DIV="${DIV}bytes"
}
[[ -z $LAST_RUN ]] && {
TXTSCALE="average per second over the last ${CURRENT[0]} seconds."
} || {
TXTSCALE="total for the last ${CURRENT[0]} seconds."
}
##############################################
## Exit Status
##############################################
X_STATUS=0
[[ -n ${WARN[11]} && ${CURRENT[4]} -gt ${WARN[11]} ]] && { X_TEXT="${X_TEXT} ${CURRENT[4]} ${DIV} incomming data $TXTSCALE"; [[ ${CURRENT[4]} -gt ${CRIT[11]} ]] && X_STATUS=2 || set_warn; }
[[ -n ${WARN[12]} && ${CURRENT[7]} -gt ${WARN[12]} ]] && { X_TEXT="${X_TEXT} ${CURRENT[7]} ${DIV} outgoing data $TXTSCALE"; [[ ${CURRENT[7]} -gt ${CRIT[12]} ]] && X_STATUS=2 || set_warn; }
[[ -n ${WARN[13]} && ${CURRENT[52]} -gt ${WARN[13]} ]] && { X_TEXT="${X_TEXT} ${CURRENT[52]} ${DIV} total data $TXTSCALE"; [[ ${CURRENT[52]} -gt ${CRIT[13]} ]] && X_STATUS=2 || set_warn; }
[[ -n ${WARN[21]} && ${CURRENT[1]} -gt ${WARN[21]} ]] && { X_TEXT="${X_TEXT} ${CURRENT[1]} incomming packets $TXTSCALE"; [[ ${CURRENT[1]} -gt ${CRIT[21]} ]] && X_STATUS=2 || set_warn; }
[[ -n ${WARN[22]} && ${CURRENT[5]} -gt ${WARN[22]} ]] && { X_TEXT="${X_TEXT} ${CURRENT[5]} outgoing packets $TXTSCALE"; [[ ${CURRENT[5]} -gt ${CRIT[22]} ]] && X_STATUS=2 || set_warn; }
[[ -n ${WARN[23]} && ${CURRENT[50]} -gt ${WARN[23]} ]] && { X_TEXT="${X_TEXT} ${CURRENT[50]} total packets $TXTSCALE"; [[ ${CURRENT[50]} -gt ${CRIT[23]} ]] && X_STATUS=2 || set_warn; }
[[ -n ${WARN[31]} && ${CURRENT[2]} -gt ${WARN[31]} ]] && { X_TEXT="${X_TEXT} ${CURRENT[2]} incomming errors $TXTSCALE"; [[ ${CURRENT[2]} -gt ${CRIT[31]} ]] && X_STATUS=2 || set_warn; }
[[ -n ${WARN[32]} && ${CURRENT[6]} -gt ${WARN[32]} ]] && { X_TEXT="${X_TEXT} ${CURRENT[6]} outgoing errors $TXTSCALE"; [[ ${CURRENT[6]} -gt ${CRIT[32]} ]] && X_STATUS=2 || set_warn; }
[[ -n ${WARN[33]} && ${CURRENT[51]} -gt ${WARN[33]} ]] && { X_TEXT="${X_TEXT} ${CURRENT[51]} total errors $TXTSCALE"; [[ ${CURRENT[51]} -gt ${CRIT[33]} ]] && X_STATUS=2 || set_warn; }
[[ -n ${WARN[50]} && ${CURRENT[3]} -gt ${WARN[50]} ]] && { X_TEXT="${X_TEXT} ${CURRENT[3]} incomming dropped $TXTSCALE"; [[ ${CURRENT[3]} -gt ${CRIT[50]} ]] && X_STATUS=2 || set_warn; }
case $X_STATUS in
0) X_MESSAGE="OK" ;;
1) X_MESSAGE="WARNING: " ;;
2) X_MESSAGE="CRITICAL:" ;;
*) X_MESSAGE="UNKNOWN: " ;;
esac
[[ -n $X_TEXT ]] && printf "${0##*/} $X_MESSAGE $X_TEXT|" || printf "${0##*/} ${X_MESSAGE}|"
##############################################
## Output Performance data
##############################################
[[ -z $SHOW_DATA ]] && SHOW_DATA="DATA_TOT,PKT_TOT,ERR_TOT,DROP"
for CURR_SHOW_DATA in $(echo $SHOW_DATA | tr [:lower:] [:upper:] | tr "," " "); do
case $CURR_SHOW_DATA in
DATA_IN) PERF_DATA="${PERF_DATA} 'Incoming Data ($DIV)'=${CURRENT[4]}${PERF_DIV}:${WARN[11]}:${CRIT[11]}::" ;;
DATA_OUT) PERF_DATA="${PERF_DATA} 'Outgoing Data ($DIV)'=${CURRENT[7]}${PERF_DIV}:${WARN[12]}:${CRIT[12]}::" ;;
DATA_TOT) PERF_DATA="${PERF_DATA} 'Total Data ($DIV)'=${CURRENT[52]}${PERF_DIV}:${WARN[13]}:${CRIT[13]}::" ;;
PKT_IN) PERF_DATA="${PERF_DATA} 'Incoming Packets'=${CURRENT[1]}:${WARN[21]}:${CRIT[21]}::" ;;
PKT_OUT) PERF_DATA="${PERF_DATA} 'Outgoing Packets'=${CURRENT[5]}:${WARN[22]}:${CRIT[22]}::" ;;
PKT_TOT) PERF_DATA="${PERF_DATA} 'Total Packets'=${CURRENT[50]}:${WARN[23]}:${CRIT[23]}::" ;;
ERR_IN) PERF_DATA="${PERF_DATA} 'Incoming Errors'=${CURRENT[2]}:${WARN[31]}:${CRIT[31]}::" ;;
ERR_OUT) PERF_DATA="${PERF_DATA} 'Outgoing Errors'=${CURRENT[6]}:${WARN[32]}:${CRIT[32]}::" ;;
ERR_TOT) PERF_DATA="${PERF_DATA} 'Total Errors'=${CURRENT[51]}:${WARN[33]}:${CRIT[33]}::" ;;
DROP) PERF_DATA="${PERF_DATA} 'Dropped Packets'=${CURRENT[3]}:${WARN[50]}:${CRIT[50]}::" ;;
esac
done
printf "${PERF_DATA}\n"
}
done
}
[[ -n $ERROR ]] && {
printf "$ERROR\n"
X_STATUS=3
}
exit $X_STATUS