From 88e046a48ca09f6d8776b930f02340203784bc5e Mon Sep 17 00:00:00 2001
From: Jan-Philipp Litza <janphilipp@litza.de>
Date: Sat, 22 Feb 2014 13:35:34 +0100
Subject: [PATCH] NodeRRD: add many more DS and reduce retention duration

---
 backend.py     |  2 +-
 lib/NodeRRD.py | 48 +++++++++++++++++++++++++++++++++++++++---------
 lib/rrddb.py   |  4 ++--
 3 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/backend.py b/backend.py
index 3ea2f5d..1fec130 100755
--- a/backend.py
+++ b/backend.py
@@ -154,7 +154,7 @@ def main(params):
         script_directory = os.path.dirname(os.path.realpath(__file__))
         rrd = RRD(os.path.join(script_directory, 'nodedb'),
                   os.path.join(params['dest_dir'], 'nodes'))
-        rrd.update_database(nodedb['nodes'])
+        rrd.update_database(nodedb['nodes'], batadv_graph)
         rrd.update_images()
 
 
diff --git a/lib/NodeRRD.py b/lib/NodeRRD.py
index afabe6f..e744525 100644
--- a/lib/NodeRRD.py
+++ b/lib/NodeRRD.py
@@ -8,25 +8,35 @@ class NodeRRD(RRD):
     ds_list = [
         DS('upstate', 'GAUGE', 120, 0, 1),
         DS('clients', 'GAUGE', 120, 0, float('NaN')),
+        DS('neighbors', 'GAUGE', 120, 0, float('NaN')),
+        DS('vpn_neighbors', 'GAUGE', 120, 0, float('NaN')),
+        DS('loadavg', 'GAUGE', 120, 0, float('NaN')),
+        DS('rx_bytes', 'DERIVE', 120, 0, float('NaN')),
+        DS('rx_packets', 'DERIVE', 120, 0, float('NaN')),
+        DS('tx_bytes', 'DERIVE', 120, 0, float('NaN')),
+        DS('tx_packets', 'DERIVE', 120, 0, float('NaN')),
+        DS('mgmt_rx_bytes', 'DERIVE', 120, 0, float('NaN')),
+        DS('mgmt_rx_packets', 'DERIVE', 120, 0, float('NaN')),
+        DS('mgmt_tx_bytes', 'DERIVE', 120, 0, float('NaN')),
+        DS('mgmt_tx_packets', 'DERIVE', 120, 0, float('NaN')),
+        DS('forward_bytes', 'DERIVE', 120, 0, float('NaN')),
+        DS('forward_packets', 'DERIVE', 120, 0, float('NaN')),
     ]
     rra_list = [
         # 2 hours of  1 minute samples
         RRA('AVERAGE', 0.5, 1, 120),
-        #  5 days  of  5 minute samples
-        RRA('AVERAGE', 0.5, 5, 1440),
-        # 30 days  of  1 hour   samples
-        RRA('AVERAGE', 0.5, 60, 720),
-        #  1 year  of 12 hour   samples
-        RRA('AVERAGE', 0.5, 720, 730),
+        # 7 days  of  15 minute samples
+        RRA('AVERAGE', 0.5, 15, 672),
     ]
 
-    def __init__(self, filename, node=None):
+    def __init__(self, filename, node=None, graph=None):
         """
         Create a new RRD for a given node.
 
         If the RRD isn't supposed to be updated, the node can be omitted.
         """
         self.node = node
+        self.node_graph = graph
         super().__init__(filename)
         self.ensure_sanity(self.ds_list, self.rra_list, step=60)
 
@@ -37,8 +47,28 @@ class NodeRRD(RRD):
 
     # TODO: fix this, python does not support function overloading
     def update(self):
-        super().update({'upstate': int(self.node['flags']['online']),
-                        'clients': self.node['statistics']['clients']})
+        values = {
+            'upstate': int(self.node['flags']['online']),
+            'clients': float(self.node['statistics']['clients']),
+            'loadavg': float(self.node['statistics'].get('loadavg', 0)),
+        }
+        for item in ('rx', 'tx', 'mgmt_rx', 'mgmt_tx', 'forward'):
+            try:
+                values.update({
+                    ('%s_bytes' % item): int(self.node['statistics'].get('traffic', {}).get(item, {}).get('bytes', 0)),
+                    ('%s_packets' % item): int(self.node['statistics'].get('traffic', {}).get(item, {}).get('packets', 0)),
+                })
+            except TypeError:
+                pass
+        try:
+            graph_node = next(key for key, node in self.node_graph.nodes(data=True) if node.get('node_id') == self.node['nodeinfo']['node_id'])
+            values.update({
+                'neighbors': float(len(self.node_graph[graph_node])),
+                'vpn_neighbors': float(len(list(filter(lambda edge: edge.get('vpn', False), self.node_graph[graph_node].values())))),
+            })
+        except StopIteration:
+            pass
+        super().update(values)
 
     def graph(self, directory, timeframe):
         """
diff --git a/lib/rrddb.py b/lib/rrddb.py
index f1678f5..7e486a3 100644
--- a/lib/rrddb.py
+++ b/lib/rrddb.py
@@ -27,7 +27,7 @@ class RRD(object):
         except OSError:
             os.mkdir(self.imagePath)
 
-    def update_database(self, nodes):
+    def update_database(self, nodes, graph):
         online_nodes = dict(filter(
             lambda d: d[1]['flags']['online'], nodes.items()))
         client_count = sum(map(
@@ -35,7 +35,7 @@ class RRD(object):
 
         self.globalDb.update(len(online_nodes), client_count)
         for node_id, node in online_nodes.items():
-            rrd = NodeRRD(os.path.join(self.dbPath, node_id + '.rrd'), node)
+            rrd = NodeRRD(os.path.join(self.dbPath, node_id + '.rrd'), node, graph)
             rrd.update()
 
     def update_images(self):