Rewritten httpcheck plugin. each error has now its own dimension, which simplifies future alarms.
Chris committed
Feb 24, 2018 at 20:52 UTC
c2c4d81d13458beb6f70c4767ef1096176b73b5f
2 files changed
+35
-24
python.d/httpcheck.chart.py
+31
-19
@@ -18,8 +18,15 @@ except AttributeError:
18
priority = 60000
19
retries = 60
20
21
-HTTP_RESPONSE_TIME = 'http_responsetime'
22
-HTTP_ERROR = 'http_error'
21
+# Latency
22
+HTTP_RESPONSE_TIME = 'response_time'
23
+
24
+# Error dimensions
25
+HTTP_SUCCESS = 'success'
26
+HTTP_UNEXPECTED_CONTENT = 'unexpected_content'
27
+HTTP_UNEXPECTED_STATUS = 'unexpected_status'
28
+HTTP_TIMEOUT = 'timeout'
29
+HTTP_FAILED = 'failed'
30
31
ORDER = ['responsetime', 'error']
32
@@ -32,19 +39,14 @@ CHARTS = {
39
'error': {
40
'options': [None, 'HTTP check error code', 'code', 'error', 'httpcheck.error', 'line'],
41
'lines': [
35
- [HTTP_ERROR, 'error', 'absolute']
42
+ [HTTP_SUCCESS, 'success', 'absolute'],
43
+ [HTTP_UNEXPECTED_CONTENT, 'unexpected content', 'absolute'],
44
+ [HTTP_UNEXPECTED_STATUS, 'unexpected status', 'absolute'],
45
+ [HTTP_TIMEOUT, 'timeout', 'absolute'],
46
+ [HTTP_FAILED, 'failed', 'absolute']
47
]}
48
}
49
39
-# The higher the error code, the "more severe" it is. E.g. an unreachable host is probably much worse than a regex
40
-# mismatch (maybe the web service just has a new design that doesn't match the regex anymore).
41
-# We use steps of 5, which allows future fine-grained error codes, should we need it (fill the blanks where
42
-# appropriate).
43
-CONTENT_MISMATCH = 3
44
-STATUS_NOT_ACCEPTED = 5
45
-CONNECTION_TIMED_OUT = 10
46
-CONNECTION_FAILED = 15
47
-
50
51
class Service(UrlService):
52
def __init__(self, configuration=None, name=None):
@@ -83,13 +85,17 @@ class Service(UrlService):
85
"""
86
data = dict()
87
data[HTTP_RESPONSE_TIME] = 0
86
- data[HTTP_ERROR] = 0
88
+ data[HTTP_SUCCESS] = 0
89
+ data[HTTP_UNEXPECTED_CONTENT] = 0
90
+ data[HTTP_UNEXPECTED_STATUS] = 0
91
+ data[HTTP_TIMEOUT] = 0
92
+ data[HTTP_FAILED] = 0
93
url = self.url
94
try:
89
- retries = 1 if self.follow_redirect else False
95
+ retr = 1 if self.follow_redirect else False
96
start = time.time()
97
response = self._manager.request(
92
- method='GET', url=url, timeout=self.request_timeout, retries=retries, headers=self._manager.headers,
98
+ method='GET', url=url, timeout=self.request_timeout, retries=retr, headers=self._manager.headers,
99
redirect=self.follow_redirect
100
)
101
diff = time.time() - start
@@ -103,17 +109,23 @@ class Service(UrlService):
109
self.debug('Content: \n\n{content}\n'.format(content=content))
110
if self.regex.search(content) is None:
111
self.debug('No match for regex \'{regex}\' found'.format(regex=self.regex.pattern))
106
- data[HTTP_ERROR] = CONTENT_MISMATCH
112
+ data[HTTP_UNEXPECTED_CONTENT] = 1
113
+ else:
114
+ data[HTTP_SUCCESS] = 1
115
else:
108
- data[HTTP_ERROR] = STATUS_NOT_ACCEPTED
116
+ data[HTTP_UNEXPECTED_STATUS] = 1
117
+
118
+ except urllib3.exceptions.NewConnectionError as error:
119
+ self.debug("Connection failed: {url}. Error: {error}".format(url=url, error=error))
120
+ data[HTTP_FAILED] = 1
121
122
except (urllib3.exceptions.TimeoutError, urllib3.exceptions.PoolError) as error:
123
self.debug("Connection timed out: {url}. Error: {error}".format(url=url, error=error))
112
- data[HTTP_ERROR] = CONNECTION_TIMED_OUT
124
+ data[HTTP_TIMEOUT] = 1
125
126
except urllib3.exceptions.HTTPError as error:
127
self.debug("Connection failed: {url}. Error: {error}".format(url=url, error=error))
116
- data[HTTP_ERROR] = CONNECTION_FAILED
128
+ data[HTTP_FAILED] = 1
129
130
except (TypeError, AttributeError) as error:
131
self.error('Url: {url}. Error: {error}'.format(url=url, error=error))
web/dashboard_info.js
+4
-5
@@ -1142,11 +1142,10 @@ netdataDashboard.context = {
1142
},
1143
1144
'httpcheck.error': {
1145
- valueRange: "[0, 3]",
1146
- info: 'The <code>Error</code> is returned by the plugin when it could not connect to the webserver. It is one of: ' +
1147
- '<code>0</code> (connection successful), <code>3</code> (unexpected response content), <code>5</code> (unexpected status code), ' +
1148
- '<code>10</code> (port unreachable), <code>15</code> (host unreachable). ' +
1149
- 'The higher the error code, the "more severe" it is. The error code is most useful for 3rd-party apps and alarms.'
1145
+ valueRange: "[0, 1]",
1146
+ info: 'The <code>error</code> codes are returned by the plugin when it could verify the availability of the webserver. ' +
1147
+ 'Each error dimension will have a value of <code>1</code> if triggered. Dimension <code>success</code> is always <code>1</code> on successful requests.' +
1148
+ 'This chart is most useful for alarms or third-party apps.'
1149
},
1150
1151
// ------------------------------------------------------------------------