diff options
Diffstat (limited to 'overlays/zte-prometheus-exporter/zte-prometheus-exporter.py')
| -rw-r--r-- | overlays/zte-prometheus-exporter/zte-prometheus-exporter.py | 90 |
1 files changed, 56 insertions, 34 deletions
diff --git a/overlays/zte-prometheus-exporter/zte-prometheus-exporter.py b/overlays/zte-prometheus-exporter/zte-prometheus-exporter.py index fc719a96..1d150eda 100644 --- a/overlays/zte-prometheus-exporter/zte-prometheus-exporter.py +++ b/overlays/zte-prometheus-exporter/zte-prometheus-exporter.py | |||
| @@ -54,13 +54,13 @@ class ZTEMetrics: | |||
| 54 | cls._instance.password = environ.get('ZTE_PASSWORD') | 54 | cls._instance.password = environ.get('ZTE_PASSWORD') |
| 55 | cls._instance.attrs = None | 55 | cls._instance.attrs = None |
| 56 | return cls._instance | 56 | return cls._instance |
| 57 | 57 | ||
| 58 | 58 | ||
| 59 | def __init__(self): | 59 | def __init__(self): |
| 60 | raise RuntimeError('Call instance() instead') | 60 | raise RuntimeError('Call instance() instead') |
| 61 | 61 | ||
| 62 | _error_pattern = re.compile('^IF_ERROR(PARAM|TYPE|STR|ID)$') | 62 | _error_pattern = re.compile(r'^IF_ERROR(PARAM|TYPE|STR|ID)$') |
| 63 | _obj_pattern = re.compile('^(?:OBJ_(.+)_ID)|(?:ID_(WAN_COMFIG))$') | 63 | _obj_pattern = re.compile(r'^(?:OBJ_(.+)_ID)|(?:ID_(WAN_COMFIG))$') |
| 64 | def update(self): | 64 | def update(self): |
| 65 | attrs = dict() | 65 | attrs = dict() |
| 66 | 66 | ||
| @@ -106,6 +106,8 @@ class ZTEMetrics: | |||
| 106 | value = child.text | 106 | value = child.text |
| 107 | case _: | 107 | case _: |
| 108 | pass | 108 | pass |
| 109 | if value == '0,0': | ||
| 110 | value = '0' | ||
| 109 | if not name is None and not value is None: | 111 | if not name is None and not value is None: |
| 110 | instance_dict[name] = value | 112 | instance_dict[name] = value |
| 111 | name = None | 113 | name = None |
| @@ -120,11 +122,21 @@ class ZTEMetrics: | |||
| 120 | def json_text(self): | 122 | def json_text(self): |
| 121 | return json.dumps(self.attrs) | 123 | return json.dumps(self.attrs) |
| 122 | 124 | ||
| 123 | _link_pattern = re.compile('^IGD\.WD1\.LINE([0-9]+)$') | 125 | _link_pattern = re.compile(r'^IGD\.WD1\.LINE([0-9]+)$') |
| 124 | _eth_pattern = re.compile('^IGD\.LD1\.ETH([0-9]+)$') | 126 | _eth_pattern = re.compile(r'^IGD\.LD1\.ETH([0-9]+)$') |
| 125 | def prometheus(self): | 127 | def prometheus(self): |
| 126 | metrics = '' | 128 | metrics = '' |
| 127 | 129 | ||
| 130 | metrics += _format_prom_metrics('info', 'gauge', [({ | ||
| 131 | "version_date": self.attrs['DEVINFO']['IGD']['VerDate'], | ||
| 132 | "software_version": self.attrs['DEVINFO']['IGD']['SoftwareVer'], | ||
| 133 | "model_name": self.attrs['DEVINFO']['IGD']['ModelName'], | ||
| 134 | "model_firmware_version": self.attrs['DEVINFO']['IGD']['ModelFirmwareVer'], | ||
| 135 | "hardware_version": self.attrs['DEVINFO']['IGD']['HardwareVer'], | ||
| 136 | "serial_number": self.attrs['DEVINFO']['IGD']['SerialNumber'], | ||
| 137 | "boot_version": self.attrs['DEVINFO']['IGD']['BootVer'], | ||
| 138 | }, 1)], 'Metadata about a given ZTE device') | ||
| 139 | |||
| 128 | uptime_seconds = timeparse(self.attrs['SYSTEMYIME']['IGD']['systemTime']) | 140 | uptime_seconds = timeparse(self.attrs['SYSTEMYIME']['IGD']['systemTime']) |
| 129 | metrics += _format_prom_metrics('uptime_seconds', 'gauge', [({}, uptime_seconds)], 'Seconds device has been running') | 141 | metrics += _format_prom_metrics('uptime_seconds', 'gauge', [({}, uptime_seconds)], 'Seconds device has been running') |
| 130 | 142 | ||
| @@ -133,34 +145,44 @@ class ZTEMetrics: | |||
| 133 | link_match = self._link_pattern.match(link) | 145 | link_match = self._link_pattern.match(link) |
| 134 | link_number = link_match.group(1) | 146 | link_number = link_match.group(1) |
| 135 | 147 | ||
| 136 | if 'crc_errors_count' not in link_metrics: | 148 | link_is_up = self.attrs['DSLINTERFACE'][link]['Status'] == 'Up' |
| 137 | link_metrics['crc_errors_count'] = {'type': 'counter', 'metrics': []} | 149 | |
| 138 | link_metrics['crc_errors_count']['metrics'] += [({"direction": "up", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['UpCrc_errors']))] | 150 | if link_is_up: |
| 139 | link_metrics['crc_errors_count']['metrics'] += [({"direction": "down", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['DownCrc_errors']))] | 151 | if 'crc_errors_count' not in link_metrics: |
| 140 | 152 | link_metrics['crc_errors_count'] = {'type': 'counter', 'metrics': []} | |
| 141 | if 'noise_margin_db' not in link_metrics: | 153 | link_metrics['crc_errors_count']['metrics'] += [({"direction": "up", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['UpCrc_errors']))] |
| 142 | link_metrics['noise_margin_db'] = {'type': 'gauge', 'metrics': []} | 154 | link_metrics['crc_errors_count']['metrics'] += [({"direction": "down", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['DownCrc_errors']))] |
| 143 | link_metrics['noise_margin_db']['metrics'] += [({"direction": "up", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Upstream_noise_margin']))] | 155 | |
| 144 | link_metrics['noise_margin_db']['metrics'] += [({"direction": "down", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Downstream_noise_margin']))] | 156 | if 'noise_margin_db' not in link_metrics: |
| 145 | 157 | link_metrics['noise_margin_db'] = {'type': 'gauge', 'metrics': []} | |
| 146 | if 'attenuation_db' not in link_metrics: | 158 | link_metrics['noise_margin_db']['metrics'] += [({"direction": "up", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Upstream_noise_margin']) / 10)] |
| 147 | link_metrics['attenuation_db'] = {'type': 'gauge', 'metrics': []} | 159 | link_metrics['noise_margin_db']['metrics'] += [({"direction": "down", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Downstream_noise_margin']) / 10)] |
| 148 | link_metrics['attenuation_db']['metrics'] += [({"direction": "up", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Upstream_attenuation']))] | 160 | |
| 149 | link_metrics['attenuation_db']['metrics'] += [({"direction": "down", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Downstream_attenuation']))] | 161 | if 'attenuation_db' not in link_metrics: |
| 150 | 162 | link_metrics['attenuation_db'] = {'type': 'gauge', 'metrics': []} | |
| 151 | if 'max_rate_kbps' not in link_metrics: | 163 | link_metrics['attenuation_db']['metrics'] += [({"direction": "up", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Upstream_attenuation']) / 10)] |
| 152 | link_metrics['max_rate_kbps'] = {'type': 'gauge', 'metrics': []} | 164 | link_metrics['attenuation_db']['metrics'] += [({"direction": "down", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Downstream_attenuation']) / 10)] |
| 153 | link_metrics['max_rate_kbps']['metrics'] += [({"direction": "up", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Upstream_max_rate']))] | 165 | |
| 154 | link_metrics['max_rate_kbps']['metrics'] += [({"direction": "down", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Downstream_max_rate']))] | 166 | if 'max_rate_kbps' not in link_metrics: |
| 155 | 167 | link_metrics['max_rate_kbps'] = {'type': 'gauge', 'metrics': []} | |
| 156 | if 'current_rate_kbps' not in link_metrics: | 168 | link_metrics['max_rate_kbps']['metrics'] += [({"direction": "up", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Upstream_max_rate']))] |
| 157 | link_metrics['current_rate_kbps'] = {'type': 'gauge', 'metrics': []} | 169 | link_metrics['max_rate_kbps']['metrics'] += [({"direction": "down", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Downstream_max_rate']))] |
| 158 | link_metrics['current_rate_kbps']['metrics'] += [({"direction": "up", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Upstream_current_rate']))] | 170 | |
| 159 | link_metrics['current_rate_kbps']['metrics'] += [({"direction": "down", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Downstream_current_rate']))] | 171 | if 'current_rate_kbps' not in link_metrics: |
| 160 | 172 | link_metrics['current_rate_kbps'] = {'type': 'gauge', 'metrics': []} | |
| 161 | if 'dsl_uptime_seconds' not in link_metrics: | 173 | link_metrics['current_rate_kbps']['metrics'] += [({"direction": "up", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Upstream_current_rate']))] |
| 162 | link_metrics['dsl_uptime_seconds'] = {'type': 'gauge', 'metrics': []} | 174 | link_metrics['current_rate_kbps']['metrics'] += [({"direction": "down", "link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Downstream_current_rate']))] |
| 163 | link_metrics['dsl_uptime_seconds']['metrics'] += [({"link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Showtime_start']))] | 175 | |
| 176 | if 'uptime_seconds' not in link_metrics: | ||
| 177 | link_metrics['uptime_seconds'] = {'type': 'gauge', 'metrics': []} | ||
| 178 | link_metrics['uptime_seconds']['metrics'] += [({"link": link_number}, int(self.attrs['DSLINTERFACE'][link]['Showtime_start']) if link_is_up else 0)] | ||
| 179 | |||
| 180 | if 'status' not in link_metrics: | ||
| 181 | link_metrics['status'] = {'type': 'gauge', 'metrics': []} | ||
| 182 | up_status, *status = self.attrs['DSLINTERFACE'][link]['Status'].split(',') | ||
| 183 | down_status = up_status if not status else status[0] | ||
| 184 | link_metrics['status']['metrics'] += [({"link": link_number, "direction": "up", "status": up_status}, 1)] | ||
| 185 | link_metrics['status']['metrics'] += [({"link": link_number, "direction": "down", "status": down_status}, 1)] | ||
| 164 | if link_metrics: | 186 | if link_metrics: |
| 165 | for metric_name in link_metrics: | 187 | for metric_name in link_metrics: |
| 166 | metrics += _format_prom_metrics(f'dsl_{metric_name}', link_metrics[metric_name]['type'], link_metrics[metric_name]['metrics']) | 188 | metrics += _format_prom_metrics(f'dsl_{metric_name}', link_metrics[metric_name]['type'], link_metrics[metric_name]['metrics']) |
| @@ -203,7 +225,7 @@ class ZTEMetricsServer(BaseHTTPRequestHandler): | |||
| 203 | self.send_response(200) | 225 | self.send_response(200) |
| 204 | self.send_header("Content-type", "text/plain") | 226 | self.send_header("Content-type", "text/plain") |
| 205 | self.end_headers() | 227 | self.end_headers() |
| 206 | 228 | ||
| 207 | self.wfile.write(zte_metrics.prometheus()) | 229 | self.wfile.write(zte_metrics.prometheus()) |
| 208 | case _: | 230 | case _: |
| 209 | self.send_response(404) | 231 | self.send_response(404) |
