reachable-watcher 1.0.91 → 1.0.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/reachable-watcher.service +28 -0
- package/reachable-watcher.sh +285 -0
- package/readme.md +6 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reachable-watcher",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.92",
|
|
4
4
|
"license": "CC-BY-3.0",
|
|
5
5
|
"description": "Check status codes of web servers and sends notification e-mails",
|
|
6
6
|
"homepage": "https://torben.website/reachable-watcher",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"lint:given": "shellcheck -x",
|
|
38
38
|
"test": "bashlink-doctest --verbose ../../reachable-watcher",
|
|
39
39
|
"update": "yarn version --patch && yarn publish",
|
|
40
|
-
"update:documentation": "
|
|
40
|
+
"update:documentation": "documentation-website"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"bashlink": "*",
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# region header
|
|
3
|
+
# Copyright Torben Sickert (t.sickert["~at~"]gmail.com) 16.12.2012
|
|
4
|
+
|
|
5
|
+
# License
|
|
6
|
+
# -------
|
|
7
|
+
|
|
8
|
+
# This library written by Torben Sickert stand under a creative commons naming
|
|
9
|
+
# 3.0 unported license. See https://creativecommons.org/licenses/by/3.0/deed.de
|
|
10
|
+
# endregion
|
|
11
|
+
[Unit]
|
|
12
|
+
Description=Checks server reachabilities.
|
|
13
|
+
Conflicts=shutdown.target reboot.target halt.target
|
|
14
|
+
Wants=network-online.target
|
|
15
|
+
After=network.target network-online.target
|
|
16
|
+
|
|
17
|
+
[Service]
|
|
18
|
+
Restart=always
|
|
19
|
+
RestartSec=10
|
|
20
|
+
ExecStart=/usr/bin/reachable-watcher
|
|
21
|
+
NotifyAccess=all
|
|
22
|
+
|
|
23
|
+
[Install]
|
|
24
|
+
WantedBy=multi-user.target
|
|
25
|
+
# region vim modline
|
|
26
|
+
# vim: set tabstop=4 shiftwidth=4 expandtab:
|
|
27
|
+
# vim: foldmethod=marker foldmarker=region,endregion:
|
|
28
|
+
# endregion
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# region header
|
|
4
|
+
# [Project page](https://torben.website/reachableWatcher)
|
|
5
|
+
|
|
6
|
+
# Copyright Torben Sickert (info["~at~"]torben.website) 16.12.2012
|
|
7
|
+
|
|
8
|
+
# License
|
|
9
|
+
# -------
|
|
10
|
+
|
|
11
|
+
# This library written by Torben Sickert stand under a creative commons naming
|
|
12
|
+
# 3.0 unported license. See https://creativecommons.org/licenses/by/3.0/deed.de
|
|
13
|
+
# endregion
|
|
14
|
+
# shellcheck disable=SC1004,SC2016,SC2034,SC2155
|
|
15
|
+
# region import
|
|
16
|
+
if [ -f "$(dirname "${BASH_SOURCE[0]}")/node_modules/bashlink/module.sh" ]; then
|
|
17
|
+
# shellcheck disable=SC1090
|
|
18
|
+
source "$(dirname "${BASH_SOURCE[0]}")/node_modules/bashlink/module.sh"
|
|
19
|
+
elif [ -f "/usr/lib/bashlink/module.sh" ]; then
|
|
20
|
+
# shellcheck disable=SC1091
|
|
21
|
+
source "/usr/lib/bashlink/module.sh"
|
|
22
|
+
else
|
|
23
|
+
declare -gr reachableWatcher_bashlink_path="$(
|
|
24
|
+
mktemp --directory --suffix -reachable-watcher-bashlink
|
|
25
|
+
)/bashlink/"
|
|
26
|
+
mkdir "$reachableWatcher_bashlink_path"
|
|
27
|
+
if wget \
|
|
28
|
+
https://torben.website/bashlink/data/distributionBundle/module.sh \
|
|
29
|
+
--output-document "${reachableWatcher_bashlink_path}module.sh"
|
|
30
|
+
then
|
|
31
|
+
declare -gr bl_module_retrieve_remote_modules=true
|
|
32
|
+
# shellcheck disable=SC1090
|
|
33
|
+
source "${reachableWatcher_bashlink_path}/module.sh"
|
|
34
|
+
rm --force --recursive "$reachableWatcher_bashlink_path"
|
|
35
|
+
else
|
|
36
|
+
echo Needed bashlink library not found 1>&2
|
|
37
|
+
rm --force --recursive "$reachableWatcher_bashlink_path"
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
fi
|
|
41
|
+
bl.module.import bashlink.array
|
|
42
|
+
bl.module.import bashlink.dictionary
|
|
43
|
+
bl.module.import bashlink.exception
|
|
44
|
+
bl.module.import bashlink.logging
|
|
45
|
+
bl.module.import bashlink.tools
|
|
46
|
+
# endregion
|
|
47
|
+
# region variables
|
|
48
|
+
declare -gr reachableWatcher__documentation__='
|
|
49
|
+
Watches a list of urls and sends mails to configured email addresses if one
|
|
50
|
+
does not fit the expected status code.
|
|
51
|
+
|
|
52
|
+
You have to install program `msmtp` to get this script working. A proper
|
|
53
|
+
user specific "~/.msmtprc" or global "/etc/msmtprc" have to be present on
|
|
54
|
+
your distribution. A sample configuration using simple gmail account to
|
|
55
|
+
send mails (Replace "ACCOUNT_NAME", "ACCOUNT_E_MAIL_ADDRESS",
|
|
56
|
+
"ACCOUNT_PASSWORD"):
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
defaults
|
|
60
|
+
auth on
|
|
61
|
+
tls on
|
|
62
|
+
tls_starttls on
|
|
63
|
+
tls_trust_file /etc/ssl/certs/ca-certificates.crt
|
|
64
|
+
logfile /tmp/msmtpLog
|
|
65
|
+
|
|
66
|
+
account gmail
|
|
67
|
+
host smtp.gmail.com
|
|
68
|
+
port 587
|
|
69
|
+
from ACCOUNT_E_MAIL_ADDRESS
|
|
70
|
+
user ACCOUNT_NAME@gmail.com
|
|
71
|
+
password ACCOUNT_PASSWORD
|
|
72
|
+
|
|
73
|
+
account default : gmail
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Furthermore you should create a file "/etc/reachableWatcher" to overwrite
|
|
77
|
+
the following variables. You need to set values for
|
|
78
|
+
`reachableWatcher_urls_to_check` and
|
|
79
|
+
`reachableWatcher_sender_e_mail_address` at least:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
reachableWatcher_sender_e_mail_address="ACCOUNT_E_MAIL_ADDRESS"
|
|
83
|
+
declare -A reachableWatcher_urls_to_check=(
|
|
84
|
+
["URL1"]="200 RECIPIENT_E_MAIL_ADDRESS"
|
|
85
|
+
["URL2"]="200 RECIPIENT_E_MAIL_ADDRESS ANOTHER_RECIPIENT_E_MAIL_ADDRESS"
|
|
86
|
+
...
|
|
87
|
+
)
|
|
88
|
+
```
|
|
89
|
+
'
|
|
90
|
+
declare -agr reachableWatcher__dependencies__=(
|
|
91
|
+
bash
|
|
92
|
+
curl
|
|
93
|
+
date
|
|
94
|
+
grep
|
|
95
|
+
msmtp
|
|
96
|
+
sleep
|
|
97
|
+
)
|
|
98
|
+
## region default options
|
|
99
|
+
declare -ag reachableWatcher_urls_to_check=()
|
|
100
|
+
# Wait for 5 minutes (60 * 5 = 300).
|
|
101
|
+
declare -ig reachableWatcher_delay_between_two_consequtive_requests_in_seconds=300
|
|
102
|
+
declare -g reachableWatcher_date_time_format='%T:%N at %d.%m.%Y'
|
|
103
|
+
declare -g reachableWatcher_sender_e_mail_address=''
|
|
104
|
+
declare -g reachableWatcher_replier_e_mail_address="$reachableWatcher_sender_e_mail_address"
|
|
105
|
+
declare -g reachableWatcher_verbose=false
|
|
106
|
+
declare -g reachableWatcher_name=NODE_NAME
|
|
107
|
+
## endregion
|
|
108
|
+
## region load options if present
|
|
109
|
+
if [ -f /etc/reachableWatcher ]; then
|
|
110
|
+
# shellcheck disable=SC1091
|
|
111
|
+
source /etc/reachableWatcher
|
|
112
|
+
fi
|
|
113
|
+
## endregion
|
|
114
|
+
# endregion
|
|
115
|
+
# region functions
|
|
116
|
+
alias reachableWatcher.is_status_valid=reachableWatcher_is_status_valid
|
|
117
|
+
reachableWatcher_is_status_valid() {
|
|
118
|
+
local -r __documentation__='
|
|
119
|
+
Checks if given and expected status codes results in valid state.
|
|
120
|
+
|
|
121
|
+
>>> reachableWatcher.is_status_valid 200 200; echo $?
|
|
122
|
+
0
|
|
123
|
+
|
|
124
|
+
>>> reachableWatcher.is_status_valid 200 "000"; echo $?
|
|
125
|
+
0
|
|
126
|
+
|
|
127
|
+
>>> reachableWatcher.is_status_valid 200 0; echo $?
|
|
128
|
+
0
|
|
129
|
+
|
|
130
|
+
>>> reachableWatcher.is_status_valid "000" 200; echo $?
|
|
131
|
+
0
|
|
132
|
+
|
|
133
|
+
>>> reachableWatcher.is_status_valid "000" 206; echo $?
|
|
134
|
+
0
|
|
135
|
+
|
|
136
|
+
>>> reachableWatcher.is_status_valid 206 "000"; echo $?
|
|
137
|
+
0
|
|
138
|
+
|
|
139
|
+
>>> reachableWatcher.is_status_valid 206 200; echo $?
|
|
140
|
+
0
|
|
141
|
+
|
|
142
|
+
>>> reachableWatcher.is_status_valid 200 206; echo $?
|
|
143
|
+
0
|
|
144
|
+
|
|
145
|
+
>>> reachableWatcher.is_status_valid 201 206; echo $?
|
|
146
|
+
1
|
|
147
|
+
|
|
148
|
+
>>> reachableWatcher.is_status_valid 206 201; echo $?
|
|
149
|
+
1
|
|
150
|
+
|
|
151
|
+
>>> reachableWatcher.is_status_valid 201 506; echo $?
|
|
152
|
+
1
|
|
153
|
+
'
|
|
154
|
+
# NOTE: Given state "000" resolves to "0" as interpreted integer.
|
|
155
|
+
local -ir expected_status_code=$1
|
|
156
|
+
local -ir given_status_code=$2
|
|
157
|
+
local -ar valid_ok_codes=(0 200 206)
|
|
158
|
+
if \
|
|
159
|
+
(( expected_status_code == given_status_code )) || \
|
|
160
|
+
(( given_status_code == 0 ))
|
|
161
|
+
then
|
|
162
|
+
return 0
|
|
163
|
+
fi
|
|
164
|
+
if \
|
|
165
|
+
bl.array.contains "${valid_ok_codes[*]}" "$expected_status_code" &&
|
|
166
|
+
bl.array.contains "${valid_ok_codes[*]}" "$given_status_code"
|
|
167
|
+
then
|
|
168
|
+
return 0
|
|
169
|
+
fi
|
|
170
|
+
return 1
|
|
171
|
+
}
|
|
172
|
+
## region controller
|
|
173
|
+
alias reachableWatcher.main=reachableWatcher_main
|
|
174
|
+
reachableWatcher_main() {
|
|
175
|
+
local -r __documentation__='
|
|
176
|
+
Main entry point.
|
|
177
|
+
'
|
|
178
|
+
$reachableWatcher_verbose && \
|
|
179
|
+
bl.logging.set_level info
|
|
180
|
+
while true; do
|
|
181
|
+
local url_to_check
|
|
182
|
+
for url_to_check in "${!reachableWatcher_urls_to_check[@]}"; do
|
|
183
|
+
local -i expected_status_code="$(
|
|
184
|
+
echo "${reachableWatcher_urls_to_check[$url_to_check]}" | \
|
|
185
|
+
grep '^[^ ]+' --only-matching --extended-regexp)"
|
|
186
|
+
bl.logging.debug "Check url \"$url_to_check\" for status code $expected_status_code."
|
|
187
|
+
local -i given_status_code="$(
|
|
188
|
+
curl \
|
|
189
|
+
--head \
|
|
190
|
+
--insecure \
|
|
191
|
+
--output /dev/null \
|
|
192
|
+
--silent \
|
|
193
|
+
--write-out '%{http_code}' \
|
|
194
|
+
"$url_to_check"
|
|
195
|
+
)"
|
|
196
|
+
local normalized_url_to_check="$(
|
|
197
|
+
echo "$url_to_check" | sed 's/[:/.]/_/g')"
|
|
198
|
+
if reachableWatcher.is_status_valid \
|
|
199
|
+
"$expected_status_code" \
|
|
200
|
+
"$given_status_code"
|
|
201
|
+
then
|
|
202
|
+
local message="Requested URL \"$url_to_check\" returns valid status code $given_status_code on $(date +"$reachableWatcher_date_time_format")."
|
|
203
|
+
bl.logging.debug "$message"
|
|
204
|
+
if [ "$(bl.dictionary.get state "$normalized_url_to_check")" = invalid ]; then
|
|
205
|
+
bl.logging.info "Status has changed to \"valid\" for \"$url_to_check\". Do notification."
|
|
206
|
+
local e_main_address
|
|
207
|
+
for e_mail_address in $(
|
|
208
|
+
echo "${reachableWatcher_urls_to_check[$url_to_check]}" | \
|
|
209
|
+
grep ' .+$' --only-matching --extended-regexp)
|
|
210
|
+
do
|
|
211
|
+
msmtp -t <<EOF
|
|
212
|
+
From: $reachableWatcher_sender_e_mail_address
|
|
213
|
+
To: $e_mail_address
|
|
214
|
+
Reply-To: $reachableWatcher_replier_e_mail_address
|
|
215
|
+
Date: $(date)
|
|
216
|
+
Subject: $reachableWatcher_name registers: "$url_to_check" responses with valid status code $given_status_code.
|
|
217
|
+
|
|
218
|
+
$message
|
|
219
|
+
|
|
220
|
+
EOF
|
|
221
|
+
done
|
|
222
|
+
bl.dictionary.set state "$normalized_url_to_check" valid
|
|
223
|
+
else
|
|
224
|
+
bl.logging.debug "Status unchanged."
|
|
225
|
+
fi
|
|
226
|
+
else
|
|
227
|
+
local message="Requested URL \"$url_to_check\" returns status code $given_status_code (instead of \"$expected_status_code\") on $(date +"$reachableWatcher_date_time_format")."
|
|
228
|
+
bl.logging.debug "$message"
|
|
229
|
+
if \
|
|
230
|
+
[ "$(bl.dictionary.get state "$normalized_url_to_check")" = valid ] ||
|
|
231
|
+
[ "$(bl.dictionary.get state "$normalized_url_to_check")" = '' ]
|
|
232
|
+
then
|
|
233
|
+
bl.logging.info "Status has changed to \"invalid for \"$url_to_check\". Do notification."
|
|
234
|
+
local e_main_address
|
|
235
|
+
for e_mail_address in $(
|
|
236
|
+
echo "${reachableWatcher_urls_to_check[$url_to_check]}" | \
|
|
237
|
+
grep ' .+$' --only-matching --extended-regexp)
|
|
238
|
+
do
|
|
239
|
+
msmtp -t <<EOF
|
|
240
|
+
From: $reachableWatcher_sender_e_mail_address
|
|
241
|
+
To: $e_mail_address
|
|
242
|
+
Reply-To: $reachableWatcher_replier_e_mail_address
|
|
243
|
+
Date: $(date)
|
|
244
|
+
Subject: $reachableWatcher_name registers: "$url_to_check" responses with invalid status code $given_status_code!
|
|
245
|
+
|
|
246
|
+
$message
|
|
247
|
+
|
|
248
|
+
EOF
|
|
249
|
+
done
|
|
250
|
+
bl.dictionary.set state "$normalized_url_to_check" invalid
|
|
251
|
+
else
|
|
252
|
+
bl.logging.debug "Status unchanged."
|
|
253
|
+
fi
|
|
254
|
+
fi
|
|
255
|
+
done
|
|
256
|
+
bl.logging.debug "Wait for $reachableWatcher_delay_between_two_consequtive_requests_in_seconds seconds until next check."
|
|
257
|
+
sleep "$reachableWatcher_delay_between_two_consequtive_requests_in_seconds"
|
|
258
|
+
done
|
|
259
|
+
}
|
|
260
|
+
## endregion
|
|
261
|
+
# endregion
|
|
262
|
+
if bl.tools.is_main; then
|
|
263
|
+
bl.exception.activate
|
|
264
|
+
bl.exception.try
|
|
265
|
+
reachableWatcher.main "$@"
|
|
266
|
+
bl.exception.catch_single
|
|
267
|
+
{
|
|
268
|
+
[ -d "$reachableWatcher_bashlink_path" ] && \
|
|
269
|
+
rm --recursive "$reachableWatcher_bashlink_path"
|
|
270
|
+
# shellcheck disable=SC2154
|
|
271
|
+
[ -d "$bl_module_remote_module_cache_path" ] && \
|
|
272
|
+
rm --recursive "$bl_module_remote_module_cache_path"
|
|
273
|
+
# shellcheck disable=SC2154
|
|
274
|
+
bl.logging.error "$bl_exception_last_traceback"
|
|
275
|
+
}
|
|
276
|
+
[ -d "$reachableWatcher_bashlink_path" ] && \
|
|
277
|
+
rm --recursive "$reachableWatcher_bashlink_path"
|
|
278
|
+
# shellcheck disable=SC2154
|
|
279
|
+
[ -d "$bl_module_remote_module_cache_path" ] && \
|
|
280
|
+
rm --recursive "$bl_module_remote_module_cache_path"
|
|
281
|
+
fi
|
|
282
|
+
# region vim modline
|
|
283
|
+
# vim: set tabstop=4 shiftwidth=4 expandtab:
|
|
284
|
+
# vim: foldmethod=marker foldmarker=region,endregion:
|
|
285
|
+
# endregion
|
package/readme.md
CHANGED
|
@@ -13,13 +13,15 @@ endregion -->
|
|
|
13
13
|
Project status
|
|
14
14
|
--------------
|
|
15
15
|
|
|
16
|
-
[](https://www.npmjs.com/package/reachable-watcher)
|
|
18
|
-
|
|
16
|
+
[](https://www.npmjs.com/package/reachable-watcher)
|
|
17
|
+
[](https://www.npmjs.com/package/reachable-watcher)
|
|
18
|
+
|
|
19
|
+
<!-- Too unstable yet
|
|
19
20
|
[](https://david-dm.org/thaibault/reachable-watcher)
|
|
20
21
|
[](https://david-dm.org/thaibault/reachable-watcher?type=dev)
|
|
21
22
|
[](https://david-dm.org/thaibault/reachable-watcher?type=peer)
|
|
22
|
-
|
|
23
|
+
-->
|
|
24
|
+
[](https://torben.website/reachable-watcher)
|
|
23
25
|
|
|
24
26
|
Use case
|
|
25
27
|
--------
|