]>
Commit | Line | Data |
---|---|---|
f46b2c61 IB |
1 | #! /bin/sh |
2 | ||
3 | OS=$(uname) | |
4 | ||
5 | # MIT License | |
6 | # | |
7 | # Copyright (c) 2016 Josef Friedrich <josef@friedrich.rocks> | |
8 | # | |
9 | # Permission is hereby granted, free of charge, to any person obtaining | |
10 | # a copy of this software and associated documentation files (the | |
11 | # "Software"), to deal in the Software without restriction, including | |
12 | # without limitation the rights to use, copy, modify, merge, publish, | |
13 | # distribute, sublicense, and/or sell copies of the Software, and to | |
14 | # permit persons to whom the Software is furnished to do so, subject to | |
15 | # the following conditions: | |
16 | # | |
17 | # The above copyright notice and this permission notice shall be | |
18 | # included in all copies or substantial portions of the Software. | |
19 | # | |
20 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
21 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
22 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
23 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
24 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
25 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
26 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
27 | ||
28 | ######################################################################## | |
29 | # Date functions | |
30 | ######################################################################## | |
31 | ||
32 | # This date function must be placed on the top of this file because | |
33 | # they are used in some global variables. | |
34 | ||
35 | # to_year ### | |
36 | ||
37 | ## | |
38 | # Get the four digit year integer from now. | |
39 | # | |
40 | # Return: | |
41 | # The current 4 digit year. | |
42 | ## | |
43 | _now_to_year() { | |
44 | date +%Y | |
45 | } | |
46 | ||
47 | ## | |
48 | # Convert a date in the format YYYY-MM-DD to a four digit year integer. | |
49 | # | |
50 | # Parameters: | |
51 | # a date in the format YYYY-MM-DD | |
52 | # | |
53 | # Return: | |
54 | # four digit year integer | |
55 | ## | |
56 | _date_to_year() { | |
57 | local OPTIONS | |
58 | if [ "$OS" = 'Linux' ]; then | |
59 | OPTIONS="--date $1" | |
60 | # FreeBSD, Darwin | |
61 | else | |
62 | OPTIONS="-j -f %Y-%m-%d $1" | |
63 | fi | |
64 | date $OPTIONS +%Y | |
65 | } | |
66 | ||
67 | # to_datetime ### | |
68 | ||
69 | ## | |
70 | # Convert a UNIX timestamp to a datetime string. | |
71 | # | |
72 | # Parameters: | |
73 | # UNIX timestamp | |
74 | # | |
75 | # Return: | |
76 | # %Y-%m-%d.%H:%M:%S | |
77 | ## | |
78 | _timestamp_to_datetime() { | |
79 | local OPTIONS | |
80 | if [ "$OS" = 'Linux' ]; then | |
81 | OPTIONS="--date @$1" | |
82 | # FreeBSD, Darwin | |
83 | else | |
84 | OPTIONS="-j -f %s $1" | |
85 | fi | |
86 | date $OPTIONS +%Y-%m-%d.%H:%M:%S | |
87 | } | |
88 | ||
89 | # to_timestamp ### | |
90 | ||
91 | ## | |
92 | # Get the current UNIX timestamp. | |
93 | # | |
94 | # Return: | |
95 | # %current UNIX timestamp | |
96 | ## | |
97 | _now_to_timestamp() { | |
98 | date +%s | |
99 | } | |
100 | ||
101 | PROJECT_PAGES='https://github.com/Josef-Friedrich/check_zfs_snapshot | |
102 | https://exchange.icinga.com/joseffriedrich/check_zfs_snapshot | |
103 | https://exchange.nagios.org/directory/Plugins/System-Metrics/File-System/check_zfs_snapshot/details' | |
104 | ||
105 | VERSION=1.2 | |
106 | FIRST_RELEASE=2016-09-08 | |
107 | SHORT_DESCRIPTION="Monitoring plugin to check how long ago the last \ | |
108 | snapshot of a ZFS dataset was created." | |
109 | USAGE="check_zfs_snapshot v$VERSION | |
110 | Copyright (c) $(_date_to_year $FIRST_RELEASE)-$(_now_to_year) \ | |
111 | Josef Friedrich <josef@friedrich.rocks> | |
112 | ||
113 | $SHORT_DESCRIPTION | |
114 | ||
115 | ||
116 | Usage: check_zfs_snapshot <options> | |
117 | ||
118 | Options: | |
119 | -c, --critical=OPT_CRITICAL | |
120 | Interval in seconds for critical state. | |
121 | -d, --dataset=OPT_DATASET | |
122 | The ZFS dataset to check. | |
123 | -h, --help | |
124 | Show this help. | |
125 | -s, --short-description | |
126 | Show a short description of the command. | |
127 | -v, --version | |
128 | Show the version number. | |
129 | -w, --warning=OPT_WARNING | |
130 | Interval in seconds for warning state. Must be lower than -c | |
131 | ||
132 | Performance data: | |
133 | - last_ago | |
134 | Time interval in seconds for last snapshot. | |
135 | - warning | |
136 | Interval in seconds. | |
137 | - critical | |
138 | Interval in seconds. | |
139 | - snapshot_count | |
140 | How many snapshot exists in the given dataset and all child | |
141 | datasets exists. | |
142 | " | |
143 | ||
144 | # Exit codes | |
145 | STATE_OK=0 | |
146 | STATE_WARNING=1 | |
147 | STATE_CRITICAL=2 | |
148 | STATE_UNKNOWN=3 | |
149 | ||
150 | _get_last_snapshot() { | |
151 | zfs get creation -Hpr -t snapshot "$1" | \ | |
152 | awk 'BEGIN {max = 0} {if ($3>max) max=$3} END {print max}' | |
153 | } | |
154 | ||
155 | _getopts() { | |
156 | while getopts ':c:d:hsvw:-:' OPT ; do | |
157 | case $OPT in | |
158 | ||
159 | c) | |
160 | OPT_CRITICAL=$OPTARG | |
161 | ;; | |
162 | ||
163 | d) | |
164 | OPT_DATASET="$OPTARG" | |
165 | ;; | |
166 | ||
167 | h) | |
168 | echo "$USAGE" | |
169 | exit 0 | |
170 | ;; | |
171 | ||
172 | s) | |
173 | echo "$SHORT_DESCRIPTION" | |
174 | exit 0 | |
175 | ;; | |
176 | ||
177 | v) | |
178 | echo "$VERSION" | |
179 | exit 0 | |
180 | ;; | |
181 | ||
182 | w) | |
183 | OPT_WARNING=$OPTARG | |
184 | ;; | |
185 | ||
186 | \?) | |
187 | echo "Invalid option “-$OPTARG”!" >&2 | |
188 | exit 2 | |
189 | ;; | |
190 | ||
191 | :) | |
192 | echo "Option “-$OPTARG” requires an argument!" >&2 | |
193 | exit 3 | |
194 | ;; | |
195 | ||
196 | -) | |
197 | LONG_OPTARG="${OPTARG#*=}" | |
198 | ||
199 | case $OPTARG in | |
200 | ||
201 | critical=?*) | |
202 | OPT_CRITICAL=$LONG_OPTARG | |
203 | ;; | |
204 | ||
205 | dataset=?*) | |
206 | OPT_DATASET="$LONG_OPTARG" | |
207 | ;; | |
208 | ||
209 | help) | |
210 | echo "$USAGE" | |
211 | exit 0 | |
212 | ;; | |
213 | ||
214 | short-description) | |
215 | echo "$SHORT_DESCRIPTION" | |
216 | exit 0 | |
217 | ;; | |
218 | ||
219 | version) | |
220 | echo "$VERSION" | |
221 | exit 0 | |
222 | ;; | |
223 | ||
224 | warning=?*) | |
225 | OPT_WARNING=$LONG_OPTARG | |
226 | ;; | |
227 | ||
228 | critical*|dataset*|warning*) | |
229 | echo "Option “--$OPTARG” requires an argument!" >&2 | |
230 | exit 3 | |
231 | ;; | |
232 | ||
233 | help*|short-description*|version*) | |
234 | echo "No argument allowed for the option “--$OPTARG”!" >&2 | |
235 | exit 4 | |
236 | ;; | |
237 | ||
238 | '') # "--" terminates argument processing | |
239 | break | |
240 | ;; | |
241 | ||
242 | *) | |
243 | echo "Invalid option “--$OPTARG”!" >&2 | |
244 | exit 2 | |
245 | ;; | |
246 | ||
247 | esac | |
248 | ;; | |
249 | ||
250 | esac | |
251 | done | |
252 | } | |
253 | ||
254 | _snapshot_count() { | |
255 | # FreeBSD wc adds some whitespaces before the number! | |
256 | # cat $HOME/debug | wc -l | |
257 | # 7 | |
258 | local COUNT | |
259 | COUNT="$(zfs list -t snapshot | grep "$1" | wc -l)" | |
260 | echo $COUNT | |
261 | } | |
262 | ||
263 | _performance_data() { | |
264 | echo "| \ | |
265 | last_ago=${DIFF}s;$OPT_WARNING;$OPT_CRITICAL;0 \ | |
266 | count=$(_snapshot_count "$OPT_DATASET");;;0\ | |
267 | " | |
268 | } | |
269 | ||
270 | ## This SEPARATOR is required for test purposes. Please don’t remove! ## | |
271 | ||
272 | _getopts $@ | |
273 | ||
274 | if [ -z "$OPT_WARNING" ]; then | |
275 | # 1 day | |
276 | OPT_WARNING=86400 | |
277 | fi | |
278 | ||
279 | if [ -z "$OPT_CRITICAL" ]; then | |
280 | # 3 day | |
281 | OPT_CRITICAL=259200 | |
282 | fi | |
283 | ||
284 | if [ -z "$OPT_DATASET" ]; then | |
285 | echo "Dataset has to be set! Use option -d <dataset>" >&2 | |
286 | echo "$USAGE" >&2 | |
287 | exit $STATE_UNKNOWN | |
288 | fi | |
289 | ||
290 | if ! zfs list "$OPT_DATASET" > /dev/null 2>&1; then | |
291 | echo "'$OPT_DATASET' is no ZFS dataset!" >&2 | |
292 | echo "$USAGE" >&2 | |
293 | exit $STATE_UNKNOWN | |
294 | fi | |
295 | ||
296 | NOW=$(_now_to_timestamp) | |
297 | ||
298 | CREATION_DATE=$(_get_last_snapshot "$OPT_DATASET") | |
299 | ||
300 | DIFF=$((NOW - CREATION_DATE)) | |
301 | ||
302 | if [ "$OPT_WARNING" -gt "$OPT_CRITICAL" ]; then | |
303 | echo '-w OPT_WARNING must be smaller than -c OPT_CRITICAL' | |
304 | _usage >&2 | |
305 | exit $STATE_UNKNOWN | |
306 | fi | |
307 | ||
308 | RETURN=STATE_UNKNOWN | |
309 | ||
310 | if [ "$DIFF" -gt "$OPT_CRITICAL" ]; then | |
311 | RETURN=$STATE_CRITICAL | |
312 | MESSAGE="CRITICAL:" | |
313 | elif [ "$DIFF" -gt "$OPT_WARNING" ]; then | |
314 | RETURN=$STATE_WARNING | |
315 | MESSAGE="WARNING:" | |
316 | else | |
317 | RETURN=$STATE_OK | |
318 | MESSAGE="OK:" | |
319 | fi | |
320 | ||
321 | DATE="$(_timestamp_to_datetime "$CREATION_DATE")" | |
322 | ||
323 | echo "$MESSAGE Last snapshot for dataset '$OPT_DATASET' was created on $DATE $(_performance_data)" | |
324 | ||
325 | exit $RETURN |