Changeset 4f39b4d05385ed2a6a1620e2e3a578b2de6a937a
- Timestamp:
- 06/05/09 01:44:24
(4 years ago)
- Author:
- Theo Schlossnagle <jesus@omniti.com>
- git-committer:
- Theo Schlossnagle <jesus@omniti.com> 1244166264 +0000
- git-parent:
[71ecd80d52072d3327e42dd7c5d60c6efec2b650]
- git-author:
- Theo Schlossnagle <jesus@omniti.com> 1244166264 +0000
- Message:
use regular expression instead, and add a body moatcher as a bonus... closes #141
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r3e39e03 |
r4f39b4d |
|
| 39 | 39 | #include <math.h> |
|---|
| 40 | 40 | |
|---|
| | 41 | #include <pcre.h> |
|---|
| | 42 | |
|---|
| 41 | 43 | #include <libxml/parser.h> |
|---|
| 42 | 44 | #include <libxml/tree.h> |
|---|
| … | … | |
| 177 | 179 | struct timeval duration; |
|---|
| 178 | 180 | stats_t current; |
|---|
| 179 | | int expect_code = 200; |
|---|
| | 181 | pcre *expect_code = NULL, *body_match = NULL; |
|---|
| 180 | 182 | u_int32_t duration_ms; |
|---|
| 181 | | void *code_str; /* void * for use with hash */ |
|---|
| 182 | | char human_buffer[256], code[4], rt[14]; |
|---|
| | 183 | void *code_str, *body_str; /* void * for use with hash */ |
|---|
| | 184 | char human_buffer[256], code[4], rt[14], bmatch[30]; |
|---|
| | 185 | const char *error; |
|---|
| | 186 | int body_matched = 1; |
|---|
| | 187 | int erroffset; |
|---|
| | 188 | int ovector[30]; |
|---|
| 183 | 189 | |
|---|
| 184 | 190 | noit_check_stats_clear(¤t); |
|---|
| 185 | 191 | |
|---|
| 186 | | if(noit_hash_retrieve(check->config, "code", strlen("code"), &code_str)) |
|---|
| 187 | | expect_code = atoi((const char *)code_str); |
|---|
| | 192 | if(!noit_hash_retrieve(check->config, "code", strlen("code"), &code_str)) { |
|---|
| | 193 | code_str = "^200$"; |
|---|
| | 194 | } |
|---|
| | 195 | expect_code = pcre_compile((const char *)code_str, 0, |
|---|
| | 196 | &error, &erroffset, NULL); |
|---|
| | 197 | if(!expect_code) |
|---|
| | 198 | noitL(nlerr, "http code match /%s/ failed @ %d: %s\n", (char *)code_str, |
|---|
| | 199 | erroffset, error); |
|---|
| | 200 | |
|---|
| | 201 | if(noit_hash_retrieve(check->config, "body", strlen("body"), &body_str)) { |
|---|
| | 202 | body_match = pcre_compile((const char *)body_str, 0, |
|---|
| | 203 | &error, &erroffset, NULL); |
|---|
| | 204 | if(!body_match) |
|---|
| | 205 | noitL(nlerr, "http body match /%s/ failed @ %d: %s\n", |
|---|
| | 206 | (char *)body_str, erroffset, error); |
|---|
| | 207 | } |
|---|
| 188 | 208 | |
|---|
| 189 | 209 | sub_timeval(ci->finish_time, check->last_fire_time, &duration); |
|---|
| … | … | |
| 192 | 212 | snprintf(rt, sizeof(rt), "%.3fs", |
|---|
| 193 | 213 | (float)duration.tv_sec + (float)duration.tv_usec / 1000000.0); |
|---|
| | 214 | |
|---|
| | 215 | bmatch[0] = '\0'; |
|---|
| | 216 | if(body_match) { |
|---|
| | 217 | if(pcre_exec(body_match, NULL, ci->body.b, ci->body.l, 0, 0, |
|---|
| | 218 | ovector, sizeof(ovector)/sizeof(*ovector)) <= 0) { |
|---|
| | 219 | body_matched = 0; |
|---|
| | 220 | } |
|---|
| | 221 | snprintf(bmatch, sizeof(bmatch), |
|---|
| | 222 | ",body=%s", body_matched ? "matched" : "failed"); |
|---|
| | 223 | } |
|---|
| | 224 | |
|---|
| 194 | 225 | snprintf(human_buffer, sizeof(human_buffer), |
|---|
| 195 | | "code=%s,rt=%s,bytes=%d", |
|---|
| | 226 | "code=%s,rt=%s,bytes=%d%s", |
|---|
| 196 | 227 | ci->status.code ? code : "undefined", |
|---|
| 197 | 228 | ci->timed_out ? "timeout" : rt, |
|---|
| 198 | | ci->body.l); |
|---|
| | 229 | ci->body.l, bmatch); |
|---|
| 199 | 230 | noitL(nldeb, "http(%s) [%s]\n", check->target, human_buffer); |
|---|
| 200 | 231 | |
|---|
| … | … | |
| 203 | 234 | duration_ms = current.duration; |
|---|
| 204 | 235 | current.available = (ci->timed_out || !ci->status.code) ? NP_UNAVAILABLE : NP_AVAILABLE; |
|---|
| 205 | | current.state = (ci->status.code != expect_code) ? NP_BAD : NP_GOOD; |
|---|
| | 236 | |
|---|
| | 237 | if(body_matched == 0) current.state = NP_BAD; |
|---|
| | 238 | else if(expect_code && |
|---|
| | 239 | pcre_exec(expect_code, NULL, code, strlen(code), 0, 0, |
|---|
| | 240 | ovector, sizeof(ovector)/sizeof(*ovector)) > 0) |
|---|
| | 241 | current.state = NP_GOOD; |
|---|
| | 242 | else |
|---|
| | 243 | current.state = NP_BAD; |
|---|
| | 244 | |
|---|
| 206 | 245 | current.status = human_buffer; |
|---|
| 207 | 246 | if(current.available == NP_AVAILABLE) { |
|---|
| … | … | |
| 219 | 258 | } |
|---|
| 220 | 259 | noit_check_set_stats(self, check, ¤t); |
|---|
| | 260 | if(expect_code) pcre_free(expect_code); |
|---|
| | 261 | if(body_match) pcre_free(body_match); |
|---|
| 221 | 262 | } |
|---|
| 222 | 263 | static void resmon_part_log_results_xml(noit_module_t *self, |
|---|
| r9d30fdf |
r4f39b4d |
|
| 1 | 1 | <module> |
|---|
| 2 | 2 | <name>http</name> |
|---|
| 3 | | <description><para>The http module performs GET requests over either HTTP or HTTPS and checks the return code.</para> |
|---|
| | 3 | <description><para>The http module performs GET requests over either HTTP or HTTPS and checks the return code and optionally the body.</para> |
|---|
| 4 | 4 | </description> |
|---|
| 5 | 5 | <loader>C</loader> |
|---|
| … | … | |
| 28 | 28 | <parameter name="code" |
|---|
| 29 | 29 | required="optional" |
|---|
| 30 | | default="200" |
|---|
| 31 | | allowed="[1-5][0-9][0-9]">The HTTP code that is expected. If the code received matches this code, the check is marked as "good," if it does not match, it is marked as "bad."</parameter> |
|---|
| | 30 | default="^200$" |
|---|
| | 31 | allowed=".+">The HTTP code that is expected. If the code received does not match this regular expression, the check is marked as "bad."</parameter> |
|---|
| | 32 | <parameter name="body" |
|---|
| | 33 | required="optional" |
|---|
| | 34 | allowed=".+">This regular expression is matched against the body of the response. If a match is not found, the check will be marked as "bad."</parameter> |
|---|
| 32 | 35 | </checkconfig> |
|---|
| 33 | 36 | <examples> |
|---|