]> arthur.barton.de Git - netdata.git/commitdiff
Merge pull request #1237 from ktsaou/master
authorCosta Tsaousis <costa@tsaousis.gr>
Sat, 12 Nov 2016 01:09:38 +0000 (03:09 +0200)
committerGitHub <noreply@github.com>
Sat, 12 Nov 2016 01:09:38 +0000 (03:09 +0200)
SocketService and more improvements

conf.d/health.d/swap.conf
python.d/memcached.chart.py
python.d/python_modules/base.py
python.d/redis.chart.py
python.d/squid.chart.py
web/index.html

index 0cfa888c4c14419b6301fb67af07ca4ca9194ab3..98ba9b52f2a077dd5efb7379987137859b210ceb 100644 (file)
@@ -12,7 +12,7 @@
     info: the amount of memory swapped in the last 30 minutes, as a percentage of the system RAM
       to: sysadmin
 
-   alarm: used_swap_space
+   alarm: ram_in_swap
       on: system.swap
     calc: $used * 100 / ( $system.ram.used + $system.ram.cached + $system.ram.free )
    units: % of RAM
    delay: up 0 down 15m multiplier 1.5 max 1h
     info: the swap memory used, as a percentage of the system RAM
       to: sysadmin
+
+   alarm: used_swap
+      on: system.swap
+    calc: $used * 100 / ( $used + $free )
+   units: %
+   every: 10s
+    warn: $this > (($status >= $WARNING)  ? (60) : (80))
+    crit: $this > (($status == $CRITICAL) ? (80) : (90))
+   delay: up 0 down 15m multiplier 1.5 max 1h
+    info: the percentage of swap memory used
+      to: sysadmin
index 09ceed2210fc322a917aaf895c3ca87f127ba820..0d6807ba731580b8345a26527aee094ad59a1f9d 100644 (file)
@@ -20,89 +20,89 @@ retries = 60
 #          }}
 
 ORDER = ['cache', 'net', 'connections', 'items', 'evicted_reclaimed',
-         'get', 'get_rate', 'set_rate', 'delete', 'cas', 'increment', 'decrement', 'touch', 'touch_rate']
+         'get', 'get_rate', 'set_rate', 'cas', 'delete', 'increment', 'decrement', 'touch', 'touch_rate']
 
 CHARTS = {
     'cache': {
-        'options': [None, 'Cache Size', 'megabytes', 'Cache', 'memcached.cache', 'stacked'],
+        'options': [None, 'Cache Size', 'megabytes', 'cache', 'memcached.cache', 'stacked'],
         'lines': [
-            ['used', 'used', 'absolute', 1, 1048576],
-            ['avail', 'available', 'absolute', 1, 1048576]
+            ['avail', 'available', 'absolute', 1, 1048576],
+            ['used', 'used', 'absolute', 1, 1048576]
         ]},
     'net': {
-        'options': [None, 'Network', 'kilobytes/s', 'Network', 'memcached.net', 'line'],
+        'options': [None, 'Network', 'kilobits/s', 'network', 'memcached.net', 'area'],
         'lines': [
-            ['bytes_read', 'read', 'incremental', 1, 1024],
-            ['bytes_written', 'written', 'incremental', 1, 1024]
+            ['bytes_read', 'in', 'incremental', 8, 1024],
+            ['bytes_written', 'out', 'incremental', -8, 1024]
         ]},
     'connections': {
-        'options': [None, 'Connections', 'connections/s', 'Cluster', 'memcached.connections', 'line'],
+        'options': [None, 'Connections', 'connections/s', 'connections', 'memcached.connections', 'line'],
         'lines': [
             ['curr_connections', 'current', 'incremental'],
             ['rejected_connections', 'rejected', 'incremental'],
             ['total_connections', 'total', 'incremental']
         ]},
     'items': {
-        'options': [None, 'Items', 'items', 'Cluster', 'memcached.items', 'line'],
+        'options': [None, 'Items', 'items', 'items', 'memcached.items', 'line'],
         'lines': [
             ['curr_items', 'current', 'absolute'],
             ['total_items', 'total', 'absolute']
         ]},
     'evicted_reclaimed': {
-        'options': [None, 'Items', 'items', 'Evicted and Reclaimed', 'memcached.evicted_reclaimed', 'line'],
+        'options': [None, 'Items', 'items', 'items', 'memcached.evicted_reclaimed', 'line'],
         'lines': [
-            ['evictions', 'evicted', 'absolute'],
-            ['reclaimed', 'reclaimed', 'absolute']
+            ['reclaimed', 'reclaimed', 'absolute'],
+            ['evictions', 'evicted', 'absolute']
         ]},
     'get': {
-        'options': [None, 'Requests', 'requests', 'GET', 'memcached.get', 'stacked'],
+        'options': [None, 'Requests', 'requests', 'get ops', 'memcached.get', 'stacked'],
         'lines': [
             ['get_hits', 'hits', 'percent-of-absolute-row'],
             ['get_misses', 'misses', 'percent-of-absolute-row']
         ]},
     'get_rate': {
-        'options': [None, 'Rate', 'requests/s', 'GET', 'memcached.get_rate', 'line'],
+        'options': [None, 'Rate', 'requests/s', 'get ops', 'memcached.get_rate', 'line'],
         'lines': [
             ['cmd_get', 'rate', 'incremental']
         ]},
     'set_rate': {
-        'options': [None, 'Rate', 'requests/s', 'SET', 'memcached.set_rate', 'line'],
+        'options': [None, 'Rate', 'requests/s', 'set ops', 'memcached.set_rate', 'line'],
         'lines': [
             ['cmd_set', 'rate', 'incremental']
         ]},
     'delete': {
-        'options': [None, 'Requests', 'requests', 'DELETE', 'memcached.delete', 'stacked'],
+        'options': [None, 'Requests', 'requests', 'delete ops', 'memcached.delete', 'stacked'],
         'lines': [
             ['delete_hits', 'hits', 'percent-of-absolute-row'],
             ['delete_misses', 'misses', 'percent-of-absolute-row'],
         ]},
     'cas': {
-        'options': [None, 'Requests', 'requests', 'CAS', 'memcached.cas', 'stacked'],
+        'options': [None, 'Requests', 'requests', 'check and set ops', 'memcached.cas', 'stacked'],
         'lines': [
             ['cas_hits', 'hits', 'percent-of-absolute-row'],
             ['cas_misses', 'misses', 'percent-of-absolute-row'],
             ['cas_badval', 'bad value', 'percent-of-absolute-row']
         ]},
     'increment': {
-        'options': [None, 'Requests', 'requests', 'Increment', 'memcached.increment', 'stacked'],
+        'options': [None, 'Requests', 'requests', 'increment ops', 'memcached.increment', 'stacked'],
         'lines': [
             ['incr_hits', 'hits', 'percent-of-absolute-row'],
             ['incr_misses', 'misses', 'percent-of-absolute-row']
         ]},
     'decrement': {
-        'options': [None, 'Requests', 'requests', 'Decrement', 'memcached.decrement', 'stacked'],
+        'options': [None, 'Requests', 'requests', 'decrement ops', 'memcached.decrement', 'stacked'],
         'lines': [
             ['decr_hits', 'hits', 'percent-of-absolute-row'],
             ['decr_misses', 'misses', 'percent-of-absolute-row']
         ]},
     'touch': {
-        'options': [None, 'Requests', 'requests', 'Touch', 'memcached.touch', 'stacked'],
+        'options': [None, 'Requests', 'requests', 'touch ops', 'memcached.touch', 'stacked'],
         'lines': [
             ['touch_hits', 'hits', 'percent-of-absolute-row'],
             ['touch_misses', 'misses', 'percent-of-absolute-row']
         ]},
     'touch_rate': {
-        'options': [None, 'Rate', 'requests/s', 'Touch', 'memcached.touch_rate', 'line'],
+        'options': [None, 'Rate', 'requests/s', 'touch ops', 'memcached.touch_rate', 'line'],
         'lines': [
             ['cmd_touch', 'rate', 'incremental']
         ]}
@@ -125,46 +125,52 @@ class Service(SocketService):
         Get data from socket
         :return: dict
         """
+        response = self._get_raw_data()
+        if response is None:
+            # error has already been logged
+            return None
+
+        if response.startswith('ERROR'):
+            self.error("received ERROR")
+            return None
+
         try:
-            raw = self._get_raw_data().split("\n")
+            parsed = response.split("\n")
         except AttributeError:
-            self.error("no data received")
-            return None
-        if raw[0].startswith('ERROR'):
-            self.error("memcached returned ERROR")
+            self.error("response is invalid/empty")
             return None
+
+        # split the response
         data = {}
-        for line in raw:
+        for line in parsed:
             if line.startswith('STAT'):
                 try:
                     t = line[5:].split(' ')
-                    data[t[0]] = int(t[1])
+                    data[t[0]] = t[1]
                 except (IndexError, ValueError):
+                    self.debug("invalid line received: " + str(line))
                     pass
-        try:
-            data['hit_rate'] = int((data['keyspace_hits'] / float(data['keyspace_hits'] + data['keyspace_misses'])) * 100)
-        except:
-            data['hit_rate'] = 0
 
+        if len(data) == 0:
+            self.error("received data doesn't have any records")
+            return None
+
+        # custom calculations
         try:
             data['avail'] = int(data['limit_maxbytes']) - int(data['bytes'])
-            data['used'] = data['bytes']
+            data['used'] = int(data['bytes'])
         except:
             pass
 
-        if len(data) == 0:
-            self.error("received data doesn't have needed records")
-            return None
-        else:
-            return data
+        return data
 
     def _check_raw_data(self, data):
         if data.endswith('END\r\n'):
-            self.debug("received response")
+            self.debug("received full response from memcached")
             return True
-        else:
-            self.debug("waiting response")
-            return False
+
+        self.debug("waiting more data from memcached")
+        return False
 
     def check(self):
         """
index cf2f7847e1529a103a235d67229e6d4fbf03bf57..c92b9c9749476b32f7ab16d5f6c607a2dba53e1a 100644 (file)
@@ -506,8 +506,82 @@ class SocketService(SimpleService):
         self.unix_socket = None
         self.request = ""
         self.__socket_config = None
+        self.__empty_request = "".encode()
         SimpleService.__init__(self, configuration=configuration, name=name)
 
+    def _socketerror(self, msg=None):
+        if self.unix_socket is not None:
+            self.error("unix socket '" + self.unix_socket + "':", msg)
+        else:
+            if self.__socket_config is not None:
+                af, socktype, proto, canonname, sa = self.__socket_config
+                self.error("socket to '" + str(sa[0]) + "' port " + str(sa[1]) + ":", msg)
+            else:
+                self.error("unknown socket:", msg)
+
+    def _connect2socket(self, res=None):
+        """
+        Connect to a socket, passing the result of getaddrinfo()
+        :return: boolean
+        """
+        if res is None:
+            res = self.__socket_config
+            if res is None:
+                self.error("Cannot create socket to 'None':")
+                return False
+
+        af, socktype, proto, canonname, sa = res
+        try:
+            self.debug("creating socket to '" + str(sa[0]) + "', port " + str(sa[1]))
+            self._sock = socket.socket(af, socktype, proto)
+        except socket.error as e:
+            self.error("Failed to create socket to '" + str(sa[0]) + "', port " + str(sa[1]) + ":", str(e))
+            self._sock = None
+            self.__socket_config = None
+            return False
+
+        try:
+            self.debug("connecting socket to '" + str(sa[0]) + "', port " + str(sa[1]))
+            self._sock.connect(sa)
+        except socket.error as e:
+            self.error("Failed to connect to '" + str(sa[0]) + "', port " + str(sa[1]) + ":", str(e))
+            self._disconnect()
+            self.__socket_config = None
+            return False
+
+        self.debug("connected to '" + str(sa[0]) + "', port " + str(sa[1]))
+        self.__socket_config = res
+        return True
+
+    def _connect2unixsocket(self, path=None):
+        """
+        Connect to a unix socket, given its filename
+        :return: boolean
+        """
+        if path is None:
+            self.error("cannot connect to unix socket 'None'")
+            return False
+
+        try:
+            self.debug("attempting DGRAM unix socket '" + str(path) + "'")
+            self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
+            self._sock.connect(path)
+            self.debug("connected DGRAM unix socket '" + str(path) + "'")
+            return True
+        except socket.error as e:
+            self.error("Failed to connect DGRAM unix socket '" + str(path) + "':", str(e))
+
+        try:
+            self.debug("attempting STREAM unix socket '" + str(path) + "'")
+            self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+            self._sock.connect(path)
+            self.debug("connected STREAM unix socket '" + str(path) + "'")
+            return True
+        except socket.error as e:
+            self.error("Failed to connect STREAM unix socket '" + str(path) + "':", str(e))
+            self._sock = None
+            return False
+
     def _connect(self):
         """
         Recreate socket and connect to it since sockets cannot be reused after closing
@@ -515,59 +589,24 @@ class SocketService(SimpleService):
         :return:
         """
         try:
-            if self.unix_socket is None:
-                if self.__socket_config is None:
-                    # establish ipv6 or ipv4 connection.
-                    for res in socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM):
-                        self.debug("connecting socket to host '" + str(self.host) + "', port " + str(self.port))
-                        try:
-                            # noinspection SpellCheckingInspection
-                            af, socktype, proto, canonname, sa = res
-                            self._sock = socket.socket(af, socktype, proto)
-                        except socket.error as e:
-                            self.debug("Cannot create socket:", str(e))
-                            self._sock = None
-                            continue
-                        try:
-                            self._sock.connect(sa)
-                        except socket.error as e:
-                            self.debug("Cannot connect to socket:", str(e))
-                            self._disconnect()
-                            continue
-                        self.__socket_config = res
-                        break
-                else:
-                    # connect to socket with previously established configuration
-                    try:
-                        af, socktype, proto, canonname, sa = self.__socket_config
-                        self._sock = socket.socket(af, socktype, proto)
-                        self._sock.connect(sa)
-                    except socket.error as e:
-                        self.debug("Cannot create or connect to socket:", str(e))
-                        self._disconnect()
+            if self.unix_socket is not None:
+                _connect2unixsocket(self.unix_socket)
+
             else:
-                # connect to unix socket
-                try:
-                    self.debug("connecting unix socket '" + str(self.unix_socket) + "'")
-                    self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
-                    self._sock.connect(self.unix_socket)
-                except socket.error:
-                    self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-                    self._sock.connect(self.unix_socket)
+                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._connect2socket(res): break
 
         except Exception as e:
-            self.error(str(e),
-                       "Cannot create socket with following configuration: host:", str(self.host),
-                       "port:", str(self.port),
-                       "socket:", str(self.unix_socket))
             self._sock = None
+            self.__socket_config = None
 
         if self._sock is not None:
             self._sock.setblocking(0)
             self._sock.settimeout(5)
-            self.debug("connected with timeout " + str(self._sock.gettimeout()))
-        else:
-            self.debug("not connected")
+            self.debug("set socket timeout to: " + str(self._sock.gettimeout()))
 
     def _disconnect(self):
         """
@@ -576,7 +615,7 @@ class SocketService(SimpleService):
         """
         if self._sock is not None:
             try:
-                self.debug("disconnecting")
+                self.debug("closing socket")
                 self._sock.shutdown(2)  # 0 - read, 1 - write, 2 - all
                 self._sock.close()
             except Exception:
@@ -589,16 +628,13 @@ class SocketService(SimpleService):
         :return: boolean
         """
         # Send request if it is needed
-        if self.request != "".encode():
+        if self.request != self.__empty_request:
             try:
-                self.debug("sending request")
+                self.debug("sending request:", str(self.request))
                 self._sock.send(self.request)
             except Exception as e:
+                self._socketerror("error sending request:" + str(e))
                 self._disconnect()
-                self.error(str(e),
-                           "used configuration: host:", str(self.host),
-                           "port:", str(self.port),
-                           "socket:", str(self.unix_socket))
                 return False
         return True
 
@@ -609,26 +645,25 @@ class SocketService(SimpleService):
         """
         data = ""
         while True:
+            self.debug("receiving response")
             try:
-                self.debug("receiving response")
-                ready_to_read, _, in_error = select.select([self._sock], [], [], 5)
+                buf = self._sock.recv(4096)
             except Exception as e:
-                self.error("timeout while waiting for response:", str(e))
+                self._socketerror("failed to receive response:" + str(e))
                 self._disconnect()
                 break
-            if len(ready_to_read) > 0:
-                buf = self._sock.recv(4096)
-                if buf is None or len(buf) == 0:  # handle server disconnect
-                    self._disconnect()
-                    break
-                data += buf.decode(errors='ignore')
-                if self._check_raw_data(data):
-                    break
-            else:
-                self.error("Socket timed out.")
+
+            if buf is None or len(buf) == 0:  # handle server disconnect
+                self.debug("server closed the connection")
                 self._disconnect()
                 break
 
+            self.debug("received data:", str(buf))
+            data += buf.decode(errors='ignore')
+            if self._check_raw_data(data):
+                break
+
+        self.debug("final response:", str(data))
         return data
 
     def _get_raw_data(self):
@@ -638,6 +673,8 @@ class SocketService(SimpleService):
         """
         if self._sock is None:
             self._connect()
+            if self._sock is None:
+                return None
 
         # Send request if it is needed
         if not self._send():
index 218401e1276d081a052dff0322cb607984723579..b23160be44eb800beb9eedf5c520da180bff5002 100644 (file)
@@ -19,40 +19,58 @@ retries = 60
 #             'unix_socket': None
 #          }}
 
-ORDER = ['operations', 'hit_rate', 'memory', 'keys', 'clients', 'slaves']
+ORDER = ['operations', 'hit_rate', 'memory', 'keys', 'net', 'connections', 'clients', 'slaves', 'persistence']
 
 CHARTS = {
     'operations': {
-        'options': [None, 'Operations', 'operations/s', 'Statistics', 'redis.operations', 'line'],
+        'options': [None, 'Redis Operations', 'operations/s', 'operations', 'redis.operations', 'line'],
         'lines': [
+            ['total_commands_processed', 'commands', 'incremental'],
             ['instantaneous_ops_per_sec', 'operations', 'absolute']
         ]},
     'hit_rate': {
-        'options': [None, 'Hit rate', 'percent', 'Statistics', 'redis.hit_rate', 'line'],
+        'options': [None, 'Redis Hit rate', 'percent', 'hits', 'redis.hit_rate', 'line'],
         'lines': [
             ['hit_rate', 'rate', 'absolute']
         ]},
     'memory': {
-        'options': [None, 'Memory utilization', 'kilobytes', 'Memory', 'redis.memory', 'line'],
+        'options': [None, 'Redis Memory utilization', 'kilobytes', 'memory', 'redis.memory', 'line'],
         'lines': [
             ['used_memory', 'total', 'absolute', 1, 1024],
             ['used_memory_lua', 'lua', 'absolute', 1, 1024]
         ]},
+    'net': {
+        'options': [None, 'Redis Bandwidth', 'kilobits/s', 'network', 'redis.net', 'area'],
+        'lines': [
+            ['total_net_input_bytes', 'in', 'incremental', 8, 1024],
+            ['total_net_output_bytes', 'out', 'incremental', -8, 1024]
+        ]},
     'keys': {
-        'options': [None, 'Database keys', 'keys', 'Keys', 'redis.keys', 'line'],
+        'options': [None, 'Redis Keys per Database', 'keys', 'keys', 'redis.keys', 'line'],
         'lines': [
             # lines are created dynamically in `check()` method
         ]},
+    'connections': {
+        'options': [None, 'Redis Connections', 'connections/s', 'connections', 'redis.connections', 'line'],
+        'lines': [
+            ['total_connections_received', 'received', 'incremental', 1],
+            ['rejected_connections', 'rejected', 'incremental', -1]
+        ]},
     'clients': {
-        'options': [None, 'Clients', 'clients', 'Clients', 'redis.clients', 'line'],
+        'options': [None, 'Redis Clients', 'clients', 'connections', 'redis.clients', 'line'],
         'lines': [
-            ['connected_clients', 'connected', 'absolute'],
-            ['blocked_clients', 'blocked', 'absolute']
+            ['connected_clients', 'connected', 'absolute', 1],
+            ['blocked_clients', 'blocked', 'absolute', -1]
         ]},
     'slaves': {
-        'options': [None, 'Slaves', 'slaves', 'Replication', 'redis.slaves', 'line'],
+        'options': [None, 'Redis Slaves', 'slaves', 'replication', 'redis.slaves', 'line'],
         'lines': [
             ['connected_slaves', 'connected', 'absolute']
+        ]},
+    'persistence': {
+        'options': [None, 'Redis Persistence Changes Since Last Save', 'changes', 'persistence', 'redis.rdb_changes', 'line'],
+        'lines': [
+            ['rdb_changes_since_last_save', 'changes', 'absolute']
         ]}
 }
 
@@ -74,33 +92,45 @@ class Service(SocketService):
         Get data from socket
         :return: dict
         """
+        response = self._get_raw_data()
+        if response is None:
+            # error has already been logged
+            return None
+
         try:
-            raw = self._get_raw_data().split("\n")
+            parsed = response.split("\n")
         except AttributeError:
-            self.error("no data received")
+            self.error("response is invalid/empty")
             return None
+
         data = {}
-        for line in raw:
-            if line.startswith(('instantaneous', 'keyspace', 'used_memory', 'connected', 'blocked')):
-                try:
-                    t = line.split(':')
-                    data[t[0]] = int(t[1])
-                except (IndexError, ValueError):
-                    pass
-            elif line.startswith('db'):
+        for line in parsed:
+            if len(line) < 5 or line[0] == '$' or line[0] == '#':
+                continue
+
+            if line.startswith('db'):
                 tmp = line.split(',')[0].replace('keys=', '')
                 record = tmp.split(':')
-                data[record[0]] = int(record[1])
+                data[record[0]] = record[1]
+                continue
+
+            try:
+                t = line.split(':')
+                data[t[0]] = t[1]
+            except (IndexError, ValueError):
+                self.debug("invalid line received: " + str(line))
+                pass
+
+        if len(data) == 0:
+            self.error("received data doesn't have any records")
+            return None
+
         try:
-            data['hit_rate'] = int((data['keyspace_hits'] / float(data['keyspace_hits'] + data['keyspace_misses'])) * 100)
+            data['hit_rate'] = (int(data['keyspace_hits']) * 100) / (int(data['keyspace_hits']) + int(data['keyspace_misses']))
         except:
             data['hit_rate'] = 0
 
-        if len(data) == 0:
-            self.error("received data doesn't have needed records")
-            return None
-        else:
-            return data
+        return data
 
     def _check_raw_data(self, data):
         """
@@ -113,11 +143,12 @@ class Service(SocketService):
         supposed = data.split('\n')[0][1:]
         offset = len(supposed) + 4  # 1 dollar sing, 1 new line character + 1 ending sequence '\r\n'
         supposed = int(supposed)
+
         if length - offset >= supposed:
+            self.debug("received full response from redis")
             return True
-        else:
-            return False
 
+        self.debug("waiting more data from redis")
         return False
 
     def check(self):
index 8300d9bad515ec04cf422789e876ca6a47139fe5..e9e8f1d08bbb1f263136a3e59ff0f59d5960d134 100644 (file)
@@ -58,20 +58,25 @@ class Service(SocketService):
         Get data via http request
         :return: dict
         """
+        response = self._get_raw_data()
+
         data = {}
         try:
             raw = ""
-            for tmp in self._get_raw_data().split('\r\n'):
+            for tmp in response.split('\r\n'):
                 if tmp.startswith("sample_time"):
                     raw = tmp
                     break
+
             if raw.startswith('<'):
                 self.error("invalid data received")
                 return None
+
             for row in raw.split('\n'):
                 if row.startswith(("client", "server.all")):
                     tmp = row.split("=")
                     data[tmp[0].replace('.', '_').strip(' ')] = int(tmp[1])
+
         except (ValueError, AttributeError, TypeError):
             self.error("invalid data received")
             return None
@@ -83,15 +88,19 @@ class Service(SocketService):
             return data
 
     def _check_raw_data(self, data):
-        if "Connection: keep-alive" in data[:1024]:
+        header = data[:1024].lower()
+
+        if "connection: keep-alive" in header:
             self._keep_alive = True
         else:
             self._keep_alive = False
 
-        if data[-7:] == "\r\n0\r\n\r\n" and "Transfer-Encoding: chunked" in data[:1024]:  # HTTP/1.1 response
+        if data[-7:] == "\r\n0\r\n\r\n" and "transfer-encoding: chunked" in header:  # HTTP/1.1 response
+            self.debug("received full response from squid")
             return True
-        else:
-            return False
+
+        self.debug("waiting more data from squid")
+        return False
 
     def check(self):
         """
index 0523f60e592d9e36e6c104d87d69283dd7ac0e96..8c7e7ae329c50dcaf7312633691e89fae15b9bc5 100644 (file)
 
         if(typeof charts['system.swap'] !== 'undefined')
             head += '<div style="margin-right: 10px;" data-netdata="system.swap"'
-            + ' data-dimensions="free"'
+            + ' data-dimensions="used"'
             + ' data-append-options="percentage"'
             + ' data-chart-library="easypiechart"'
-            + ' data-title="Free Swap"'
+            + ' data-title="Used Swap"'
             + ' data-units="%"'
             + ' data-easypiechart-max-value="100"'
             + ' data-width="8%"'
 
         if(typeof charts['system.ram'] !== 'undefined')
             head += '<div style="margin-right: 10px;" data-netdata="system.ram"'
-            + ' data-dimensions="cached|free"'
+            + ' data-dimensions="used|buffers"'
             + ' data-append-options="percentage"'
             + ' data-chart-library="easypiechart"'
-            + ' data-title="Available RAM"'
+            + ' data-title="Used RAM"'
             + ' data-units="%"'
             + ' data-easypiechart-max-value="100"'
             + ' data-width="8%"'