-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhc_wrap
executable file
·202 lines (172 loc) · 4.34 KB
/
hc_wrap
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
#!/bin/bash
# Usage:
# Replace the CRON shell with this script.
# In the crontab set to call this wrapper instead of "sh"
# SHELL=.../log_wrap
# and tell us the previous shell cron used
# OLD_SHELL = /bin/sh
#
# Then the cron record format changes to
# m h dom mon dow check name command
# 23 * * * * "server online" df -h
# 64 21 * * * "server backup" /root/backup --onedisk /
#### Logging
LOG_PATH=${HOME}/.healthchecks
LOG_FILE=wrap_cmd
if [[ ${HC_DEBUG} ]]; then
mkdir -p ${LOG_PATH} > /dev/null
rm ${LOG_PATH}/${LOG_FILE} > /dev/null
fi
log_cmd()
{
if [[ ${HC_DEBUG} ]]; then
echo "[${LOGNAME}][`date -Is`] - ${*}" >> ${LOG_PATH}/${LOG_FILE}
fi
}
#### command split
hc_name=
hc_command=
split_name_command()
{
local argv="$@"
# Quotes surround name
local pattern_1='^[ ]*\"(.*)\" (.*)$'
# One word name
local pattern_2='^[ ]*(\w+) (.*)$'
if [[ $argv =~ ${pattern_1} ]]; then
hc_name=${BASH_REMATCH[1]}
hc_command="${BASH_REMATCH[2]}"
elif [[ $argv =~ ${pattern_2} ]]; then
hc_name=${BASH_REMATCH[1]}
hc_command="${BASH_REMATCH[2]}"
fi
}
#### Settings
# settings will be read from:
# $HOME/.hc_wrap_config
# /etc/healthchecks_config (optional)
# crontab variables
config_file=${HOME}/.hc_wrap_config
# create a template config file if it does not yet exist
if [[ ! -r $config_file ]]; then
cat << EOF > $config_file
# The API key for accessing the server
#API_KEY=sUHYjHWeyJ8yRbbpvtbhw7cIDrVEfpQi
# The api URL for querying the server
#HC_API_URL=https://hc-ping.com/api/v1/checks
# e.g. https://hc-ping.com/b6f811ed-1718-4538-bd36-4f4b7376596a
#https://hc-ping.com/b6f811ed-1718-4538-bd36-4f4b7376596a = server online
#https://hc-ping.com/63219b04-4072-431a-a7c0-d5336d1a431b = server backup
EOF
fi
# called with config file name
parse_config()
{
if [[ ! -r $1 ]]; then
return
fi
local lhs rhs
while IFS='= ' read -r lhs rhs
do
if [[ ! $lhs =~ ^\ *# && -n $lhs ]]; then
rhs="${rhs%%\#*}" # Del in line right comments
rhs="${rhs%%*( )}" # Del trailing spaces
rhs="${rhs%\"*}" # Del opening string quotes
rhs="${rhs#\"*}" # Del closing string quotes
set_config $lhs "$rhs"
fi
done < $1
}
declare API_KEY HC_API_URL
declare -A ping_urls
set_config()
{
log_cmd "config - $@"
case $1 in
API_KEY) API_KEY=$2 ;;
HC_API_URL) HC_API_URL=$2 ;;
*)
ping_urls["$2"]="$1"
;;
esac
}
#### Get ping url
hc_ping_url=
# called with task name
get_ping_url()
{
hc_ping_url=${ping_urls["$1"]}
if [[ -n $hc_ping_url ]]; then
log_cmd "Found url: $hc_ping_url"
return
fi
log_cmd "Create url for: $1"
local response data
# "api_key": "${API_KEY}",
read -r -d '' data << EOF
{
"name": "${hc_name}",
"unique": ["name"],
"timeout": 86400,
"channels": "*"
}
EOF
log_cmd "$data"
response=$(
curl ${HC_API_URL} \
--header "X-Api-Key: ${API_KEY}" \
--data "${data}"
)
local response_status=$?
log_cmd "response - $response_status $response"
if [[ $response_status -ne 0 ]]; then
log_cmd "error connecting to server api"
return
fi
# response comes back as a single line
hc_ping_url=$(echo "${response}" | jq --raw-output '.ping_url' )
log_cmd "hc_ping_url: $hc_ping_url"
if [[ -n $hc_ping_url ]]; then
echo "${hc_ping_url} = $1" >> $config_file
fi
}
#### Poll server
poll_server()
{
log_cmd "poll: $1"
# server logs the first 10k
echo "${2:0:10000}" |
curl -fsS --retry 3 --request POST --data-binary @- $1 >/dev/null
log_cmd "poll ret $?"
}
#### ########
if [[ ${HC_DEBUG} ]]; then
env > ${LOG_PATH}/wrap_vars
fi
log_cmd "$@"
# get rid of the '-c'
shift
split_name_command "$1"
log_cmd "hc_name: $hc_name"
log_cmd "hc_command: $hc_command"
parse_config $config_file
if [[ ${HC_DEBUG} ]]; then
declare -p API_KEY HC_API_URL ping_urls >> ${LOG_PATH}/${LOG_FILE}
fi
get_ping_url "$hc_name"
poll_server "${hc_ping_url}/start"
# make fd/5 an alias of stdout
exec 5>&1
hc_out=$( $OLD_SHELL -c "$hc_command" |& tee /dev/fd/5 | { head -n 10000; cat >/dev/null; }; exit ${PIPESTATUS[0]} )
hc_exit=$?
if [[ ${HC_DEBUG} ]]; then
log_cmd "hc_exit: $hc_exit"
log_cmd "hc_out-"
echo "${hc_out}" >> ${LOG_PATH}/${LOG_FILE}
log_cmd "hc_out-"
fi
fail_tag=
if [[ ${hc_exit} -ne 0 ]]; then
fail_tag=/fail
fi
poll_server "${hc_ping_url}${fail_tag}" "${hc_out}"