Add support for counters info sent by agents

Change-Id: Idb21389186c50d15aac1f2ed4166e9dbd1be15bc
diff --git a/VERSION b/VERSION
index a597e4f..def4250 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.7.14
+0.7.15
diff --git a/edge-monitoring-server/edge_monitoring_server.py b/edge-monitoring-server/edge_monitoring_server.py
index 6e71973..4bde766 100755
--- a/edge-monitoring-server/edge_monitoring_server.py
+++ b/edge-monitoring-server/edge_monitoring_server.py
@@ -159,6 +159,22 @@
                 "rsrp": {"type": "number"}
             },
             "required": ["rsrq", "rsrp"]
+        },
+        "counters": {
+            "type": "object",
+            "properties": {
+                'dongle_read_error': {"type": "number"},
+                'dongle_connect_error': {"type": "number"},
+                'dongle_rsrp_rsrq_error': {"type": "number"},
+                'modem_cfun0_error': {"type": "number"},
+                'modem_cfun1_error': {"type": "number"},
+                'modem_cgatt_error': {"type": "number"},
+                'modem_cesq_error': {"type": "number"},
+                'dry_run_ping_error': {"type": "number"},
+                'ping_error': {"type": "number"},
+                'iperf_error': {"type": "number"},
+                'report_send_error': {"type": "number"}
+            }
         }
     },
     "required": ["name", "status"]
@@ -172,7 +188,7 @@
             'user_plane': 'connected'
         },
         'dongle_stats': {
-            'SuccessfulFetch' : False
+            'SuccessfulFetch': False
         },
         'speedtest': {
             'ping': {
@@ -224,6 +240,19 @@
             'rsrq': 0,
             'rsrp': 0
         },
+        'counters': {
+            'dongle_read_error': 0,
+            'dongle_connect_error': 0,
+            'dongle_rsrp_rsrq_error': 0,
+            'modem_cfun0_error': 0,
+            'modem_cfun1_error': 0,
+            'modem_cgatt_error': 0,
+            'modem_cesq_error': 0,
+            'dry_run_ping_error': 0,
+            'ping_error': 0,
+            'iperf_error': 0,
+            'report_send_error': 0
+        },
         'last_update': time.time()
     }
 ]
@@ -264,40 +293,40 @@
 dongle_stats_phycellid = prom.Gauge("aetheredge_dongle_stats_phycellid", "PhyCellID of the UE", ["name"])
 
 # Ping dry_run metrics
-ping_dry_run_transmitted = prom.Gauge("aetheredge_ping_dry_run_test_transmitted","Last ping test to dry_run number of transmitted packets",["name"])
-ping_dry_run_received = prom.Gauge("aetheredge_ping_dry_run_test_received","Last ping test to dry_run number of received packets",["name"])
-ping_dry_run_median = prom.Gauge("aetheredge_ping_dry_run_test_median","Last ping test to dry_run median value",["name"])
-ping_dry_run_min = prom.Gauge("aetheredge_ping_dry_run_test_min","Last ping test to dry_run minimum value",["name"])
-ping_dry_run_avg = prom.Gauge("aetheredge_ping_dry_run_test_avg","Last ping test to dry_run average",["name"])
-ping_dry_run_max = prom.Gauge("aetheredge_ping_dry_run_test_max","Last ping test to dry_run maximum value",["name"])
-ping_dry_run_stddev = prom.Gauge("aetheredge_ping_dry_run_test_stddev","Last ping test to dry_run standard deviation",["name"])
+ping_dry_run_transmitted = prom.Gauge("aetheredge_ping_dry_run_test_transmitted", "Last ping test to dry_run number of transmitted packets", ["name"])
+ping_dry_run_received = prom.Gauge("aetheredge_ping_dry_run_test_received", "Last ping test to dry_run number of received packets",["name"])
+ping_dry_run_median = prom.Gauge("aetheredge_ping_dry_run_test_median", "Last ping test to dry_run median value", ["name"])
+ping_dry_run_min = prom.Gauge("aetheredge_ping_dry_run_test_min", "Last ping test to dry_run minimum value", ["name"])
+ping_dry_run_avg = prom.Gauge("aetheredge_ping_dry_run_test_avg", "Last ping test to dry_run average", ["name"])
+ping_dry_run_max = prom.Gauge("aetheredge_ping_dry_run_test_max", "Last ping test to dry_run maximum value", ["name"])
+ping_dry_run_stddev = prom.Gauge("aetheredge_ping_dry_run_test_stddev", "Last ping test to dry_run standard deviation", ["name"])
 
 # Ping dns metrics
-ping_dns_transmitted = prom.Gauge("aetheredge_ping_dns_test_transmitted","Last ping test to dns number of transmitted packets",["name"])
-ping_dns_received = prom.Gauge("aetheredge_ping_dns_test_received","Last ping test to dns number of received packets",["name"])
-ping_dns_median = prom.Gauge("aetheredge_ping_dns_test_median","Last ping test to dns median value",["name"])
-ping_dns_min = prom.Gauge("aetheredge_ping_dns_test_min","Last ping test to dns minimum value",["name"])
-ping_dns_avg = prom.Gauge("aetheredge_ping_dns_test_avg","Last ping test to dns average",["name"])
-ping_dns_max = prom.Gauge("aetheredge_ping_dns_test_max","Last ping test to dns maximum value",["name"])
-ping_dns_stddev = prom.Gauge("aetheredge_ping_dns_test_stddev","Last ping test to dns standard deviation",["name"])
+ping_dns_transmitted = prom.Gauge("aetheredge_ping_dns_test_transmitted", "Last ping test to dns number of transmitted packets", ["name"])
+ping_dns_received = prom.Gauge("aetheredge_ping_dns_test_received", "Last ping test to dns number of received packets", ["name"])
+ping_dns_median = prom.Gauge("aetheredge_ping_dns_test_median", "Last ping test to dns median value",["name"])
+ping_dns_min = prom.Gauge("aetheredge_ping_dns_test_min", "Last ping test to dns minimum value",["name"])
+ping_dns_avg = prom.Gauge("aetheredge_ping_dns_test_avg", "Last ping test to dns average",["name"])
+ping_dns_max = prom.Gauge("aetheredge_ping_dns_test_max", "Last ping test to dns maximum value",["name"])
+ping_dns_stddev = prom.Gauge("aetheredge_ping_dns_test_stddev", "Last ping test to dns standard deviation",["name"])
 
 # Ping iperf server metrics
-ping_iperf_server_transmitted = prom.Gauge("aetheredge_ping_iperf_server_test_transmitted","Last ping test to iperf_server number of transmitted packets",["name"])
-ping_iperf_server_received = prom.Gauge("aetheredge_ping_iperf_server_test_received","Last ping test to iperf_server number of received packets",["name"])
-ping_iperf_server_median = prom.Gauge("aetheredge_ping_iperf_server_test_median","Last ping test to iperf_server median value",["name"])
-ping_iperf_server_min = prom.Gauge("aetheredge_ping_iperf_server_test_min","Last ping test to iperf_server minimum value",["name"])
-ping_iperf_server_avg = prom.Gauge("aetheredge_ping_iperf_server_test_avg","Last ping test to iperf_server average",["name"])
-ping_iperf_server_max = prom.Gauge("aetheredge_ping_iperf_server_test_max","Last ping test to iperf_server maximum value",["name"])
-ping_iperf_server_stddev = prom.Gauge("aetheredge_ping_iperf_server_test_stddev","Last ping test to iperf_server standard deviation",["name"])
+ping_iperf_server_transmitted = prom.Gauge("aetheredge_ping_iperf_server_test_transmitted","Last ping test to iperf_server number of transmitted packets", ["name"])
+ping_iperf_server_received = prom.Gauge("aetheredge_ping_iperf_server_test_received","Last ping test to iperf_server number of received packets", ["name"])
+ping_iperf_server_median = prom.Gauge("aetheredge_ping_iperf_server_test_median","Last ping test to iperf_server median value", ["name"])
+ping_iperf_server_min = prom.Gauge("aetheredge_ping_iperf_server_test_min","Last ping test to iperf_server minimum value", ["name"])
+ping_iperf_server_avg = prom.Gauge("aetheredge_ping_iperf_server_test_avg","Last ping test to iperf_server average", ["name"])
+ping_iperf_server_max = prom.Gauge("aetheredge_ping_iperf_server_test_max","Last ping test to iperf_server maximum value", ["name"])
+ping_iperf_server_stddev = prom.Gauge("aetheredge_ping_iperf_server_test_stddev","Last ping test to iperf_server standard deviation", ["name"])
 
 # Ping management_server metrics
-ping_management_server_transmitted = prom.Gauge("aetheredge_ping_management_server_test_transmitted","Last ping test to management_server number of transmitted packets",["name"])
-ping_management_server_received = prom.Gauge("aetheredge_ping_management_server_test_received","Last ping test to management_server number of received packets",["name"])
-ping_management_server_median = prom.Gauge("aetheredge_ping_management_server_test_median","Last ping test to management_server median value",["name"])
+ping_management_server_transmitted = prom.Gauge("aetheredge_ping_management_server_test_transmitted","Last ping test to management_server number of transmitted packets", ["name"])
+ping_management_server_received = prom.Gauge("aetheredge_ping_management_server_test_received","Last ping test to management_server number of received packets", ["name"])
+ping_management_server_median = prom.Gauge("aetheredge_ping_management_server_test_median","Last ping test to management_server median value", ["name"])
 ping_management_server_min = prom.Gauge("aetheredge_ping_management_server_test_min","Last ping test to management_server minimum value",["name"])
-ping_management_server_avg = prom.Gauge("aetheredge_ping_management_server_test_avg","Last ping test to management_server average",["name"])
-ping_management_server_max = prom.Gauge("aetheredge_ping_management_server_test_max","Last ping test to management_server maximum value",["name"])
-ping_management_server_stddev = prom.Gauge("aetheredge_ping_management_server_test_stddev","Last ping test to management_server standard deviation",["name"])
+ping_management_server_avg = prom.Gauge("aetheredge_ping_management_server_test_avg","Last ping test to management_server average", ["name"])
+ping_management_server_max = prom.Gauge("aetheredge_ping_management_server_test_max","Last ping test to management_server maximum value", ["name"])
+ping_management_server_stddev = prom.Gauge("aetheredge_ping_management_server_test_stddev","Last ping test to management_server standard deviation", ["name"])
 
 # Speedtest iperf metrics
 iperf_cluster_downlink = prom.Gauge("aetheredge_iperf_cluster_downlink_test","Last iperf test downlink result",["name"])
@@ -309,6 +338,18 @@
 signal_quality_rsrq = prom.Gauge("aetheredge_signal_quality_rsrq", "Quality of the received signal", ["name"])
 signal_quality_rsrp = prom.Gauge("aetheredge_signal_quality_rsrp", "Power of the received signal", ["name"])
 
+counters_dongle_read_error = prom.Gauge("aetheredge_counters_dongle_read_error", "Dongle read error counter", ["name"])
+counters_dongle_connect_error = prom.Gauge("aetheredge_counters_dongle_connect_error", "Dongle connect error counter", ["name"])
+counters_dongle_rsrp_rsrq_error = prom.Gauge("aetheredge_counters_dongle_rsrp_rsrq_error", "Dongle rsrp/rsrq error counter", ["name"])
+counters_modem_cfun0_error = prom.Gauge("aetheredge_counters_modem_cfun0_error", "Modem cfun0 error counter", ["name"])
+counters_modem_cfun1_error = prom.Gauge("aetheredge_counters_modem_cfun1_error", "Modem cfun1 error counter", ["name"])
+counters_modem_cgatt_error = prom.Gauge("aetheredge_counters_modem_cgatt_error", "Modem cgatt error counter", ["name"])
+counters_modem_cesq_error = prom.Gauge("aetheredge_counters_modem_cesq_error", "Modem cesq error counter", ["name"])
+counters_dry_run_ping_error = prom.Gauge("aetheredge_counters_dry_run_ping_error", "Dry run ping error counter", ["name"])
+counters_ping_error = prom.Gauge("aetheredge_counters_ping_error", "Ping error counter", ["name"])
+counters_iperf_error = prom.Gauge("aetheredge_counters_iperf_error", "Iperf error counter", ["name"])
+counters_report_send_error = prom.Gauge("aetheredge_counters_report_send_error", "Report send error counter", ["name"])
+
 # Other metrics
 last_update = prom.Gauge("aetheredge_last_update", "Last reported test result", ["name"])
 maint_window = prom.Gauge("aetheredge_in_maintenance_window", "Currently in a maintenance window", ["name"])
@@ -366,7 +407,7 @@
         if time_elapsed > NO_RESULT_THRESHOLD:
             edge['status']['control_plane'] = "no result"
             edge['status']['user_plane'] = "no result"
-            edge['dongle_stats'] = {'SuccessfulFetch' : False}
+            edge['dongle_stats'] = {'SuccessfulFetch': False}
             edge['speedtest']['ping']['dry_run'] = {'transmitted': 0,
                                                     'received': 0,
                                                     'median': 0.0,
@@ -479,6 +520,21 @@
         pass
 
     try:
+        counters_dongle_read_error.remove(name)
+        counters_dongle_connect_error.remove(name)
+        counters_dongle_rsrp_rsrq_error.remove(name)
+        counters_modem_cfun0_error.remove(name)
+        counters_modem_cfun1_error.remove(name)
+        counters_modem_cgatt_error.remove(name)
+        counters_modem_cesq_error.remove(name)
+        counters_dry_run_ping_error.remove(name)
+        counters_ping_error.remove(name)
+        counters_iperf_error.remove(name)
+        counters_report_send_error.remove(name)
+    except:
+        pass
+
+    try:
         maint_window.remove(name)
     except:
         pass
@@ -610,6 +666,19 @@
             signal_quality_rsrq.labels(edge['name']).set(edge['signal_quality']['rsrq'])
             signal_quality_rsrp.labels(edge['name']).set(edge['signal_quality']['rsrp'])
 
+        if 'counters' in edge.keys():
+            counters_dongle_read_error.labels(edge['name']).set(edge['counters']['dongle_read_error'])
+            counters_dongle_connect_error.labels(edge['name']).set(edge['counters']['dongle_connect_error'])
+            counters_dongle_rsrp_rsrq_error.labels(edge['name']).set(edge['counters']['dongle_rsrp_rsrq_error'])
+            counters_modem_cfun0_error.labels(edge['name']).set(edge['counters']['modem_cfun0_error'])
+            counters_modem_cfun1_error.labels(edge['name']).set(edge['counters']['modem_cfun1_error'])
+            counters_modem_cgatt_error.labels(edge['name']).set(edge['counters']['modem_cgatt_error'])
+            counters_modem_cesq_error.labels(edge['name']).set(edge['counters']['modem_cesq_error'])
+            counters_dry_run_ping_error.labels(edge['name']).set(edge['counters']['dry_run_ping_error'])
+            counters_ping_error.labels(edge['name']).set(edge['counters']['ping_error'])
+            counters_iperf_error.labels(edge['name']).set(edge['counters']['iperf_error'])
+            counters_report_send_error.labels(edge['name']).set(edge['counters']['report_send_error'])
+
     res.append(prom.generate_latest(cp_status))
     res.append(prom.generate_latest(up_status))
 
@@ -660,6 +729,17 @@
     res.append(prom.generate_latest(e2e_tests_down))
     res.append(prom.generate_latest(signal_quality_rsrq))
     res.append(prom.generate_latest(signal_quality_rsrp))
+    res.append(prom.generate_latest(counters_dongle_read_error))
+    res.append(prom.generate_latest(counters_dongle_connect_error))
+    res.append(prom.generate_latest(counters_dongle_rsrp_rsrq_error))
+    res.append(prom.generate_latest(counters_modem_cfun0_error))
+    res.append(prom.generate_latest(counters_modem_cfun1_error))
+    res.append(prom.generate_latest(counters_modem_cgatt_error))
+    res.append(prom.generate_latest(counters_modem_cesq_error))
+    res.append(prom.generate_latest(counters_dry_run_ping_error))
+    res.append(prom.generate_latest(counters_ping_error))
+    res.append(prom.generate_latest(counters_iperf_error))
+    res.append(prom.generate_latest(counters_report_send_error))
 
     return Response(res, mimetype="text/plain")
 
@@ -700,14 +780,14 @@
             'user_plane': request.json['status']['user_plane']
         },
         'dongle_stats': {
-            'SuccessfulFetch' : False
+            'SuccessfulFetch': False
         },
         'speedtest': {
             'ping': {
                 'dry_run': {
-                    'transmitted' : 0,
-                    'received' : 0,
-                    'median' : 0.0,
+                    'transmitted': 0,
+                    'received': 0,
+                    'median': 0.0,
                     'min': 0.0,
                     'avg': 0.0,
                     'max': 0.0,
@@ -748,6 +828,19 @@
                 }
             }
         },
+        'counters': {
+            'dongle_read_error': 0,
+            'dongle_connect_error': 0,
+            'dongle_rsrp_rsrq_error': 0,
+            'modem_cfun0_error': 0,
+            'modem_cfun1_error': 0,
+            'modem_cgatt_error': 0,
+            'modem_cesq_error': 0,
+            'dry_run_ping_error': 0,
+            'ping_error': 0,
+            'iperf_error': 0,
+            'report_send_error': 0
+        },
         'last_update': time.time()
     }
 
@@ -763,6 +856,9 @@
     if 'dongle_stats' in request.json:
         req_edge['dongle_stats'] = request.json['dongle_stats']
 
+    if 'counters' in request.json:
+        req_edge['counters'] = request.json['counters']
+
     edge = [edge for edge in edges if edge['name'] == req_edge['name']]
     if len(edge) == 0:
         app.logger.info("new edge request " + req_edge['name'])
@@ -775,6 +871,8 @@
         edge[0]['dongle_stats'] = req_edge['dongle_stats']
         if 'signal_quality' in req_edge.keys():
             edge[0]['signal_quality'] = req_edge['signal_quality']
+        if 'counters' in req_edge.keys():
+            edge[0]['counters'] = req_edge['counters']
         edge[0]['last_update'] = req_edge['last_update']
 
     return jsonify({'edge': req_edge}), 201
diff --git a/edge-monitoring-server/test_edge_monitoring_server.py b/edge-monitoring-server/test_edge_monitoring_server.py
index f2bf2a6..16f2df6 100755
--- a/edge-monitoring-server/test_edge_monitoring_server.py
+++ b/edge-monitoring-server/test_edge_monitoring_server.py
@@ -76,6 +76,19 @@
         'rsrq': 30,
         'rsrp': 80
     },
+    'counters': {
+        'dongle_read_error': 0,
+        'dongle_connect_error': 0,
+        'dongle_rsrp_rsrq_error': 0,
+        'modem_cfun0_error': 0,
+        'modem_cfun1_error': 0,
+        'modem_cgatt_error': 0,
+        'modem_cesq_error': 0,
+        'dry_run_ping_error': 0,
+        'ping_error': 0,
+        'iperf_error': 0,
+        'report_send_error': 0
+    },
     'last_update': time.time()
 }
 
@@ -444,7 +457,6 @@
         self.assertTrue('aetheredge_dongle_stats_plmnstatus{name="ace-menlo-rasp-pi"} 3' in data)
         self.assertTrue('aetheredge_dongle_stats_phycellid{name="ace-menlo-rasp-pi"} 101' in data)
 
-
     def test_match_location(self):
         event = MyEvent(location = "ace-menlo-rasp-pi-production")
         self.assertTrue(ems.is_my_event(event, "ace-menlo-rasp-pi"))
@@ -527,7 +539,6 @@
 
         response = self.app.get('/edges/metrics')
         data = response.get_data(as_text=True)
-        # print(data)
 
         self._assert_status_metrics_exist(data)
         self._assert_speedtest_metrics_exist(data)
@@ -539,7 +550,6 @@
 
         response = self.app.get('/edges/metrics')
         data = response.get_data(as_text=True)
-        # print(data)
         self.assertFalse('ace-menlo-rasp-pi' in data)
 
         response = self.app.get('/edges')