Browse Source

rabbitmq: api/nodes requests fix (#5142)

* nodes_stats fix

* fix
Ilya Mashchenko 6 years ago
parent
commit
2fb6282350
1 changed files with 45 additions and 63 deletions
  1. 45 63
      collectors/python.d.plugin/rabbitmq/rabbitmq.chart.py

+ 45 - 63
collectors/python.d.plugin/rabbitmq/rabbitmq.chart.py

@@ -3,19 +3,12 @@
 # Author: l2isbad
 # SPDX-License-Identifier: GPL-3.0-or-later
 
-from collections import namedtuple
 from json import loads
-from socket import gethostbyname, gaierror
-from threading import Thread
-try:
-        from queue import Queue
-except ImportError:
-        from Queue import Queue
 
 from bases.FrameworkServices.UrlService import UrlService
 
-
-METHODS = namedtuple('METHODS', ['get_data', 'url', 'stats'])
+API_NODE = 'api/nodes'
+API_OVERVIEW = 'api/overview'
 
 NODE_STATS = [
     'fd_used',
@@ -123,74 +116,62 @@ class Service(UrlService):
         UrlService.__init__(self, configuration=configuration, name=name)
         self.order = ORDER
         self.definitions = CHARTS
-        self.host = self.configuration.get('host', '127.0.0.1')
-        self.port = self.configuration.get('port', 15672)
-        self.scheme = self.configuration.get('scheme', 'http')
+        self.url = '{0}://{1}:{2}'.format(
+            configuration.get('scheme', 'http'),
+            configuration.get('host', '127.0.0.1'),
+            configuration.get('port', 15672),
+        )
+        self.node_name = str()
 
-    def check(self):
-        # We can't start if <host> AND <port> not specified
-        if not (self.host and self.port):
-            self.error('Host is not defined in the module configuration file')
-            return False
+    def _get_data(self):
+        data = dict()
 
-        # Hostname -> ip address
-        try:
-            self.host = gethostbyname(self.host)
-        except gaierror as error:
-            self.error(str(error))
-            return False
-
-        # Add handlers (auth, self signed cert accept)
-        self.url = '{scheme}://{host}:{port}/api'.format(scheme=self.scheme,
-                                                         host=self.host,
-                                                         port=self.port)
-        # Add methods
-        api_node = self.url + '/nodes'
-        api_overview = self.url + '/overview'
-        self.methods = [METHODS(get_data=self._get_overview_stats,
-                                url=api_node,
-                                stats=NODE_STATS),
-                        METHODS(get_data=self._get_overview_stats,
-                                url=api_overview,
-                                stats=OVERVIEW_STATS)]
-        return UrlService.check(self)
+        stats = self.get_overview_stats()
 
-    def _get_data(self):
-        threads = list()
-        queue = Queue()
-        result = dict()
+        if not stats:
+            return None
+
+        data.update(stats)
+
+        stats = self.get_nodes_stats()
+
+        if not stats:
+            return None
+
+        data.update(stats)
 
-        for method in self.methods:
-            th = Thread(target=method.get_data,
-                        args=(queue, method.url, method.stats))
-            th.start()
-            threads.append(th)
+        return data or None
 
-        for thread in threads:
-            thread.join()
-            result.update(queue.get())
+    def get_overview_stats(self):
+        url = '{0}/{1}'.format(self.url, API_OVERVIEW)
 
-        return result or None
+        raw = self._get_raw_data(url)
 
-    def _get_overview_stats(self, queue, url, stats):
-        """
-        Format data received from http request
-        :return: dict
-        """
+        if not raw:
+            return None
 
-        raw_data = self._get_raw_data(url)
+        data = loads(raw)
 
-        if not raw_data:
-            return queue.put(dict())
-        data = loads(raw_data)
-        data = data[0] if isinstance(data, list) else data
+        self.node_name = data['node']
 
-        to_netdata = fetch_data(raw_data=data, metrics=stats)
-        return queue.put(to_netdata)
+        return fetch_data(raw_data=data, metrics=OVERVIEW_STATS)
+
+    def get_nodes_stats(self):
+        url = '{0}/{1}/{2}'.format(self.url, API_NODE, self.node_name)
+
+        raw = self._get_raw_data(url)
+
+        if not raw:
+            return None
+
+        data = loads(raw)
+
+        return fetch_data(raw_data=data, metrics=NODE_STATS)
 
 
 def fetch_data(raw_data, metrics):
     data = dict()
+
     for metric in metrics:
         value = raw_data
         metrics_list = metric.split('.')
@@ -200,4 +181,5 @@ def fetch_data(raw_data, metrics):
         except KeyError:
             continue
         data['_'.join(metrics_list)] = value
+
     return data