-
Notifications
You must be signed in to change notification settings - Fork 0
/
check_dockerapi_stats
executable file
·203 lines (172 loc) · 5.08 KB
/
check_dockerapi_stats
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
#!/bin/bash
# See https://docs.docker.com/engine/api/v1.40/#operation/ContainerStats
JQ=`which jq`
CURL=`which curl`
AWK=`which awk`
# Nagios return codes
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3
# Plugin variable description
PROGNAME=$(basename $0)
RELEASE="Revision 1.0.1"
AUTHOR="(c) 2020 Paul Bargewell ([email protected])"
if [ ! -x $JQ ]; then
echo "UNKNOWN: jq not found or is not executable"
exit $STATE_UNKNOWN
fi
if [ ! -x $CURL ]; then
echo "UNKNOWN: curl not found or is not executable"
exit $STATE_UNKNOWN
fi
if [ ! -x $AWK ]; then
echo "UNKNOWN: awk not found or is not executable"
exit $STATE_UNKNOWN
fi
# Functions plugin usage
print_release() {
echo "$RELEASE $AUTHOR"
}
print_usage() {
echo ""
echo "$PROGNAME $RELEASE - Checks Docker Container Status from Docker API for Icinga2"
echo ""
echo "Usage: $PROGNAME"
echo ""
echo " -h Show this page"
echo ""
echo " -H | --host Host name / IP of Docker API server (required)"
echo ""
echo " -P | --port Port Number of Docker API Service"
echo ""
echo " --https Use HTTPS requires cert, key and cacert set"
echo ""
echo " --cert Client certificate (pem)"
echo ""
echo " --key Client key (pem)"
echo ""
echo " --cacert CA cert (pem)"
echo ""
echo " -C | --container Name of container to inspect"
echo ""
echo "Usage: $PROGNAME --help"
echo ""
exit 0
}
print_help() {
print_usage
echo ""
echo "This plugin will check Docker container statuses using the Docker API"
echo ""
exit 0
}
# Defaults
PROTOCOL=http://
PORT=2376
EXCLUDE=
INCLUDE=
# Parse parameters
while [ $# -gt 0 ]; do
case "$1" in
-h | --help)
print_help
exit $STATE_OK
;;
-v | --version)
print_release
exit $STATE_OK
;;
-H | --host)
shift
HOST=$1
;;
-P | --port)
shift
PORT=$1
;;
-C | --container)
shift
CONTAINER=$1
;;
--exclude)
shift
EXCLUDE=$1
;;
--include)
shift
INCLUDE=$1
;;
--https)
PROTOCOL=https://
;;
--cert)
shift
CERT=$1
;;
--key)
shift
KEY=$1
;;
--cacert)
shift
CACERT=$1
;;
*)
echo "Unknown argument: $1"
print_usage
exit $STATE_UNKNOWN
;;
esac
shift
done
if [ -z "$HOST" ]; then
echo "UNKNOWN: Host name must be specified"
exit $STATE_UNKNOWN
fi
TLS_OPTIONS=
if [ "$PROTOCOL" == "https://" ]; then
# Check all cert info is set
if [[ -z "$CERT" || -z "$KEY" || -z "$CACERT" ]]; then
echo "UNKNOWN: Missing client certificate, key or ca cert."
exit $STATE_UNKNOWN
else
TLS_OPTIONS="--cert $CERT --key $KEY --cacert $CACERT"
fi
fi
# Get the ID of the container for the next call to stats
ID=$(eval "${CURL} --silent ${PROTOCOL}${HOST}:${PORT}/containers/json?all=true $TLS_OPTIONS | ${JQ} -r '.[] | select(.Names[0] == \"/${CONTAINER}\") .Id'")
# Make a one time (not streaming) call to stats
JSON=`${CURL} --silent ${PROTOCOL}${HOST}:${PORT}/containers/${ID}/stats?stream=false $TLS_OPTIONS`
if [ -z "$JSON" ]; then
echo "UNKNOWN: Unable to collect container data from the docker API"
exit $STATE_UNKNOWN
fi
NAGIOS_DATA=
memory_stats_usage=`echo ${JSON} | ${JQ} .memory_stats.usage`
memory_stats_stats_cache=`echo ${JSON} | ${JQ} .memory_stats.stats.cache`
used_memory=($memory_stats_usage - $memory_stats_stats_cache)
available_memory=`echo ${JSON} | ${JQ} .memory_stats.limit`
memory_usage=`echo "${used_memory} ${available_memory}" | ${AWK} '{printf "%.2f", $1 / $2 * 100}'`
memory_usage_d=`echo "${used_memory} ${available_memory}" | ${AWK} '{printf "%d", $1 / $2 * 100}'`
cpu_stats_cpu_usage_total_usage=`echo ${JSON} | ${JQ} .cpu_stats.cpu_usage.total_usage`
precpu_stats_cpu_usage_total_usage=`echo ${JSON} | ${JQ} .precpu_stats.cpu_usage.total_usage`
cpu_delta=`echo "${cpu_stats_cpu_usage_total_usage} ${precpu_stats_cpu_usage_total_usage}" | ${AWK} '{printf "%d", $1 - $2}'`
cpu_stats_system_cpu_usage=`echo ${JSON} | ${JQ} .cpu_stats.system_cpu_usage`
precpu_stats_system_cpu_usage=`echo ${JSON} | ${JQ} .precpu_stats.system_cpu_usage`
system_cpu_delta=`echo "${cpu_stats_system_cpu_usage} ${precpu_stats_system_cpu_usage}" | ${AWK} '{printf "%d", $1 - $2}'`
number_cpus=`echo ${JSON} | ${JQ} .cpu_stats.online_cpus`
cpu_usage=`echo "${cpu_delta} ${system_cpu_delta} ${number_cpus}" | ${AWK} '{printf "%f", ($1 / $2) * 100}'`
cpu_usage_d=`echo "${cpu_delta} ${system_cpu_delta} ${number_cpus}" | ${AWK} '{printf "%d", ($1 / $2) * 100}'`
NAGIOS_DATA="${NAGIOS_DATA}cpu_usage=${cpu_usage}%, memory_usage=${memory_usage}%, number_cpus=${number_cpus}"
# Use the integer (non-decimal) version for the comparison
if [ $cpu_usage_d -gt 90 ]; then
echo "DOCKER CONTAINER CRITICAL: ${NAGIOS_DATA}"
exit $STATE_CRITICAL
elif [ $cpu_usage_d -gt 50 ]; then
echo "DOCKER CONTAINER WARNING: ${NAGIOS_DATA}"
exit $STATE_WARNING
else
echo "DOCKER CONTAINER OK: ${NAGIOS_DATA}"
exit $STATE_OK
fi