summaryrefslogtreecommitdiffstats
path: root/python.d/python_modules/bases
diff options
context:
space:
mode:
authorFederico Ceratto <federico.ceratto@gmail.com>2018-03-27 21:28:21 +0000
committerFederico Ceratto <federico.ceratto@gmail.com>2018-03-27 21:28:21 +0000
commitd4dd00f58a502c9ca4b63e36ce6bc7a9945dc63c (patch)
treefaac99f51f182bb8c0a03e95e393d421ac9ddf42 /python.d/python_modules/bases
parentNew upstream version 1.9.0+dfsg (diff)
downloadnetdata-d4dd00f58a502c9ca4b63e36ce6bc7a9945dc63c.tar.xz
netdata-d4dd00f58a502c9ca4b63e36ce6bc7a9945dc63c.zip
New upstream version 1.10.0+dfsgupstream/1.10.0+dfsg
Diffstat (limited to 'python.d/python_modules/bases')
-rw-r--r--python.d/python_modules/bases/FrameworkServices/ExecutableService.py5
-rw-r--r--python.d/python_modules/bases/FrameworkServices/SimpleService.py12
-rw-r--r--python.d/python_modules/bases/FrameworkServices/SocketService.py29
-rw-r--r--python.d/python_modules/bases/FrameworkServices/UrlService.py33
-rw-r--r--python.d/python_modules/bases/charts.py6
5 files changed, 63 insertions, 22 deletions
diff --git a/python.d/python_modules/bases/FrameworkServices/ExecutableService.py b/python.d/python_modules/bases/FrameworkServices/ExecutableService.py
index b6d7871f..a71f2bfd 100644
--- a/python.d/python_modules/bases/FrameworkServices/ExecutableService.py
+++ b/python.d/python_modules/bases/FrameworkServices/ExecutableService.py
@@ -30,7 +30,10 @@ class ExecutableService(SimpleService):
data = list()
std = p.stderr if stderr else p.stdout
for line in std:
- data.append(line.decode())
+ try:
+ data.append(line.decode('utf-8'))
+ except TypeError:
+ continue
return data or None
diff --git a/python.d/python_modules/bases/FrameworkServices/SimpleService.py b/python.d/python_modules/bases/FrameworkServices/SimpleService.py
index 14c83910..177332c1 100644
--- a/python.d/python_modules/bases/FrameworkServices/SimpleService.py
+++ b/python.d/python_modules/bases/FrameworkServices/SimpleService.py
@@ -33,6 +33,7 @@ class RuntimeCounters:
self.RETRIES = 0
self.RETRIES_MAX = configuration.pop('retries')
self.PENALTY = 0
+ self.RUNS = 1
def is_sleep_time(self):
return self.START_RUN < self.NEXT_RUN
@@ -82,6 +83,10 @@ class SimpleService(Thread, PythonDLimitedLogger, OldVersionCompatibility, objec
return self.fake_name or self.name
@property
+ def runs_counter(self):
+ return self._runtime_counters.RUNS
+
+ @property
def update_every(self):
return self._runtime_counters.FREQ
@@ -178,6 +183,8 @@ class SimpleService(Thread, PythonDLimitedLogger, OldVersionCompatibility, objec
self.error('update() unhandled exception: {error}'.format(error=error))
updated = False
+ job.RUNS += 1
+
if not updated:
if not self.manage_retries():
return
@@ -209,7 +216,10 @@ class SimpleService(Thread, PythonDLimitedLogger, OldVersionCompatibility, objec
for chart in self.charts:
if chart.flags.obsoleted:
- continue
+ if chart.can_be_updated(data):
+ chart.refresh()
+ else:
+ continue
elif self.charts.cleanup and chart.penalty >= self.charts.cleanup:
chart.obsolete()
self.error("chart '{0}' was suppressed due to non updating".format(chart.name))
diff --git a/python.d/python_modules/bases/FrameworkServices/SocketService.py b/python.d/python_modules/bases/FrameworkServices/SocketService.py
index 90631df1..8d27ae66 100644
--- a/python.d/python_modules/bases/FrameworkServices/SocketService.py
+++ b/python.d/python_modules/bases/FrameworkServices/SocketService.py
@@ -14,6 +14,7 @@ class SocketService(SimpleService):
self.host = 'localhost'
self.port = None
self.unix_socket = None
+ self.dgram_socket = False
self.request = ''
self.__socket_config = None
self.__empty_request = "".encode()
@@ -115,7 +116,11 @@ class SocketService(SimpleService):
if self.__socket_config is not None:
self._connect2socket()
else:
- for res in socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM):
+ if self.dgram_socket:
+ sock_type = socket.SOCK_DGRAM
+ else:
+ sock_type = socket.SOCK_STREAM
+ for res in socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, sock_type):
if self._connect2socket(res):
break
@@ -158,12 +163,15 @@ class SocketService(SimpleService):
return False
return True
- def _receive(self):
+ def _receive(self, raw=False):
"""
Receive data from socket
- :return: str
+ :param raw: set `True` to return bytes
+ :type raw: bool
+ :return: decoded str or raw bytes
+ :rtype: str/bytes
"""
- data = ""
+ data = "" if not raw else b""
while True:
self.debug('receiving response')
try:
@@ -174,7 +182,7 @@ class SocketService(SimpleService):
break
if buf is None or len(buf) == 0: # handle server disconnect
- if data == "":
+ if data == "" or data == b"":
self._socket_error('unexpectedly disconnected')
else:
self.debug('server closed the connection')
@@ -182,17 +190,20 @@ class SocketService(SimpleService):
break
self.debug('received data')
- data += buf.decode('utf-8', 'ignore')
+ data += buf.decode('utf-8', 'ignore') if not raw else buf
if self._check_raw_data(data):
break
self.debug('final response: {0}'.format(data))
return data
- def _get_raw_data(self):
+ def _get_raw_data(self, raw=False):
"""
Get raw data with low-level "socket" module.
- :return: str
+ :param raw: set `True` to return bytes
+ :type raw: bool
+ :return: decoded data (str) or raw data (bytes)
+ :rtype: str/bytes
"""
if self._sock is None:
self._connect()
@@ -203,7 +214,7 @@ class SocketService(SimpleService):
if not self._send():
return None
- data = self._receive()
+ data = self._receive(raw)
if not self._keep_alive:
self._disconnect()
diff --git a/python.d/python_modules/bases/FrameworkServices/UrlService.py b/python.d/python_modules/bases/FrameworkServices/UrlService.py
index 0941ab16..bb340ba3 100644
--- a/python.d/python_modules/bases/FrameworkServices/UrlService.py
+++ b/python.d/python_modules/bases/FrameworkServices/UrlService.py
@@ -75,20 +75,31 @@ class UrlService(SimpleService):
:return: str
"""
try:
- url = url or self.url
- manager = manager or self._manager
- response = manager.request(method='GET',
- url=url,
- timeout=self.request_timeout,
- retries=1,
- headers=manager.headers)
+ status, data = self._get_raw_data_with_status(url, manager)
except (urllib3.exceptions.HTTPError, TypeError, AttributeError) as error:
self.error('Url: {url}. Error: {error}'.format(url=url, error=error))
return None
- if response.status == 200:
- return response.data.decode()
- self.debug('Url: {url}. Http response status code: {code}'.format(url=url, code=response.status))
- return None
+
+ if status == 200:
+ return data.decode()
+ else:
+ self.debug('Url: {url}. Http response status code: {code}'.format(url=url, code=status))
+ return None
+
+ def _get_raw_data_with_status(self, url=None, manager=None, retries=1, redirect=True):
+ """
+ Get status and response body content from http request. Does not catch exceptions
+ :return: int, str
+ """
+ url = url or self.url
+ manager = manager or self._manager
+ response = manager.request(method='GET',
+ url=url,
+ timeout=self.request_timeout,
+ retries=retries,
+ headers=manager.headers,
+ redirect=redirect)
+ return response.status, response.data
def check(self):
"""
diff --git a/python.d/python_modules/bases/charts.py b/python.d/python_modules/bases/charts.py
index 1e9348e5..5394fbf6 100644
--- a/python.d/python_modules/bases/charts.py
+++ b/python.d/python_modules/bases/charts.py
@@ -217,6 +217,12 @@ class Chart:
safe_print(chart + dimensions + variables)
+ def can_be_updated(self, data):
+ for dim in self.dimensions:
+ if dim.get_value(data) is not None:
+ return True
+ return False
+
def update(self, data, interval):
updated_dimensions, updated_variables = str(), str()