def metrics(self) -> tp.Iterator[Metric]: """ Generate implementation specific Metrics from Samples :return: yields Metrics """ # Retrieve sample sample = self.retrieve() if sample is not None: # Extract info labels from Sample sample_info_dict = self.sample_info_metric_dict(sample) # Try extracting Metric from each Channel for channel in sample.channels: yield from self.channel_metric(channel, sample.meter_id, self.meter_name, sample.time.timestamp()) else: sample_info_dict = {} # Create Info Metric reader_info_dict = self.reader_info_metric_dict() info_dict = {**sample_info_dict, **reader_info_dict} info_metric = InfoMetricFamily( METRICS_PREFIX + "meter", "Additional information about this Meter", value=info_dict) yield info_metric
def __init__(self): self.info = InfoMetricFamily('mtp_app', 'Details of a money-to-prisoners app', value=dict( app=settings.APP, environment=settings.ENVIRONMENT, git_commit=settings.APP_GIT_COMMIT, build_tag=settings.APP_BUILD_TAG, build_date=settings.APP_BUILD_DATE, ))
def __init__(self): self.info = InfoMetricFamily( 'mtp_app', 'Details of a money-to-prisoners app', value=dict( app=getattr(settings, 'APP', None) or 'unknown', environment=getattr(settings, 'ENVIRONMENT', None) or 'local', git_commit=getattr(settings, 'APP_GIT_COMMIT', None) or 'unknown', build_tag=getattr(settings, 'APP_BUILD_TAG', None) or 'unknown', build_date=getattr(settings, 'APP_BUILD_DATE', None) or 'unknown', ))
def collect_metrics_from_page(driver): result = parse_page(driver) for key, value in result.items(): metric = MAP_METRICS.get(key) if metric is not None: name = 'wemportal_' + metric['name'] t = metric.get('type', 'gauge') if t is 'gauge': value = parse_value(value, metric.get('strip')) yield GaugeMetricFamily(name, key, value=value) if t is 'counter': value = parse_value(value, metric.get('strip')) yield CounterMetricFamily(name, key, value=value) if t is 'info': yield InfoMetricFamily(name, key, value={'value': value})
def collect(self): for statistic in self._available_statistics: try: metadata = get_metrics_metadata(statistic) name = self.metric_name(statistic) logging.info("Collecting metric %s.", statistic) metric_value = self.collect_metric( metric_type=metadata['type'], metric_key=statistic) if metadata['type'] == MetricType.COUNTER: metric = CounterMetricFamily( name=name, documentation=metadata['description'], labels=["node", "host"], unit=metadata['unit']) metric.add_metric(labels=[self._node, self._hostname], value=metric_value) yield metric elif metadata['type'] == MetricType.GAUGE: metric = GaugeMetricFamily( name=name, documentation=metadata['description'], labels=["node", "host"], unit=metadata['unit']) metric.add_metric(labels=[self._node, self._hostname], value=metric_value) yield metric elif metadata['type'] == MetricType.INFO: metric = InfoMetricFamily( name=name, documentation=metadata['description'], labels=["node", "host"]) metric.add_metric( labels=[self._node, self._hostname], value={sanitize(statistic): metric_value}) yield metric except KeyError as e: logging.warning("Key do not exists: %s.", e.args[0]) except QdbError as e: logging.error("Connection error with Quasar DB Server", exc_info=True) raise SystemExit
def extract(self, raw_xmls: Dict[int, bytes]) -> Iterable[Metric]: assert len(raw_xmls) == 3 # parse GlobalSettings root = etree.fromstring(raw_xmls[GET.GLOBALSETTINGS], parser=self._parsers[GET.GLOBALSETTINGS]) firmware_version = root.find("SwVersion").text cm_provision_mode = root.find("CmProvisionMode").text gw_provision_mode = root.find("GwProvisionMode").text operator_id = root.find("OperatorId").text # `cm_provision_mode` is known to be None in case `provisioning_status` is "DS scanning". We need to set it to # some string, otherwise the InfoMetricFamily call fails with AttributeError. if cm_provision_mode is None: cm_provision_mode = "Unknown" # parse cm_system_info root = etree.fromstring(raw_xmls[GET.CM_SYSTEM_INFO], parser=self._parsers[GET.CM_SYSTEM_INFO]) docsis_mode = root.find("cm_docsis_mode").text hardware_version = root.find("cm_hardware_version").text uptime_as_str = root.find("cm_system_uptime").text # parse cmstatus root = etree.fromstring(raw_xmls[GET.CMSTATUS], parser=self._parsers[GET.CMSTATUS]) cable_modem_status = root.find("cm_comment").text provisioning_status = root.find("provisioning_st").text yield InfoMetricFamily( "connectbox_device", "Assorted device information", value={ "hardware_version": hardware_version, "firmware_version": firmware_version, "docsis_mode": docsis_mode, "cm_provision_mode": cm_provision_mode, "gw_provision_mode": gw_provision_mode, "cable_modem_status": cable_modem_status, "operator_id": operator_id, }, ) # return an enum-style metric for the provisioning status try: enum_provisioning_status = ProvisioningStatus(provisioning_status) except ValueError: self._logger.warning( f"Unknown provisioning status '{provisioning_status}'. Please open an issue on Github." ) enum_provisioning_status = ProvisioningStatus.UNKNOWN yield StateSetMetricFamily( "connectbox_provisioning_status", "Provisioning status description", value={ state.value: state == enum_provisioning_status for state in ProvisioningStatus }, ) # uptime is reported in a format like "36day(s)15h:24m:58s" which needs parsing uptime_pattern = r"(\d+)day\(s\)(\d+)h:(\d+)m:(\d+)s" m = re.fullmatch(uptime_pattern, uptime_as_str) if m is not None: uptime_timedelta = timedelta(days=int(m[1]), hours=int(m[2]), minutes=int(m[3]), seconds=int(m[4])) uptime_seconds = uptime_timedelta.total_seconds() else: self._logger.warning( f"Unexpected duration format '{uptime_as_str}', please open an issue on github." ) uptime_seconds = -1 yield GaugeMetricFamily( "connectbox_uptime", "Device uptime in seconds", unit="seconds", value=uptime_seconds, )
def collect(self): for m in self._sources: url = 'http://' + m.host + '/read_json.php?device=map' if m.login and m.password: auth = (m.login, m.password) else: auth = None try: r = requests.get(url=url, auth=auth, timeout=m.timeout) except requests.RequestException: _logger.error("Connect to MAP error: " + m.host) continue try: j = r.json() except JSONDecodeError: _logger.error("JSON decode error (possible no MAP connected): " + m.host) continue _logger.debug('Got response from ' + m.host + ' Firmware: ' + j['fw']) i = InfoMetricFamily('map', 'MAP information for.', value={'name': m.name, 'hostname': m.host, 'firmware': j['fw']}) yield i f = MapMetricFactory(m) yield f.gauge('map_mode', j['_MODE'], 'Режим работы МАП') yield f.gauge('map_status_charge', j['_Status_Char'], 'Cтатус заряда (по протоколу МикроАрт)') yield f.gauge('map_battery_voltage', j['_Uacc'], 'Напряжение АКБ, Вольт') yield f.gauge('map_battery_charge_end_voltage_with_temp', j['_Uch_T'], 'Напряжение окончания заряда АКБ с коррекцией по текущей температуре') yield f.gauge('map_battery_charge_buffer_voltage_with_temp', j['_Ubuf_T'], 'Напряжение окончания заряда АКБ для буферного напряжения АКБ') yield f.gauge('map_battery_current_coarse', j['_Iacc'], 'Ток АКБ, А (грубое значение)') yield f.gauge('map_battery_current_fine', j['_IAcc_med_A_u16'], 'Ток АКБ, А (точное значение, до 0.1)') yield f.gauge('map_battery_current_average', j['_I_acc_avg'], 'Cредний ток по АКБ') yield f.gauge('map_battery_power', j['_PLoad'], 'Мощность по АКБ, Вт. Из ячейки МАП') yield f.gauge('map_battery_power_calculated', j['_PLoad_calc'], 'Расчетная мощность по АКБ. P(t)=I(t)*U(t). (Знак минус – ток из АКБ. Знак + ток на АКБ (заряд))') yield f.gauge('map_battery_power_overload', j['_F_Acc_Over'], 'Состояние перегрузки по АКБ (см. Протокол)') yield f.gauge('map_network_power_overload', j['_F_Net_Over'], 'Состояние перегрузки по сети 220 (см. Протокол)') yield f.gauge('map_network_voltage', j['_UNET'], 'Напряжение сети (вход МАП), Вольт') yield f.gauge('map_network_current_coarse', j['_INET'], 'Ток по входу МАП, А (грубое значение)') yield f.gauge('map_network_current_fine', j['_INET_16_4'], 'Ток по входу МАП, А (точное значение, до 0.1)') yield f.counter('map_network_current_direction', float(j['_E_NET_SIGN'])/100.0, 'Счетчик, учитывающий знак направления тока энергии по входу МАП кВтч') yield f.gauge('map_network_power', j['_PNET'], 'Мощность по входу МАП, ВА') yield f.gauge('map_network_power_calculated', j['_PNET_calc'], 'Мощность по входу МАП, ВА (расчетное значение)') yield f.gauge('map_network_frequency', j['_TFNET'], 'Частота сети по входу МАП, Гц') yield f.gauge('map_output_frequency', j['_ThFMAP'], 'Частота по выходу МАП, Гц') yield f.gauge('map_output_voltage_average', j['_UOUTmed'], 'Усредненное значение напряжения на выходе МАП, Вольт') yield f.gauge('map_temperature_external', j['_Temp_Grad0'], 'Температура от внешнего датчика температуры (который наклеен на АКБ)') yield f.gauge('map_temperature_tor', j['_Temp_Grad1'], 'Температура датчика тора (в модели DOMINATOR)') yield f.gauge('map_temperature_transistors', j['_Temp_Grad2'], 'Температура от датчика температуры транзисторов') yield f.counter('map_power_from_network', float(j['_E_NET'])/100.0, 'Потребленная энергия от сети кВтч') yield f.counter('map_power_from_battery', float(j['_E_ACC'])/100.0, 'Потребленная энергия от АКБ на генерацию МАП кВтч') yield f.counter('map_power_to_battery', float(j['_E_ACC_CHARGE'])/100.0, 'Энергия на заряд АКБ от сети кВтч') yield f.gauge('map_cooler_speed', j['_CoolerSpeed'], 'Скорость вращения охлаждающего вентилятора') yield f.gauge('map__I_acc_3ph', j['_I_acc_3ph'], 'Общий ток потребления/заряда по АКБ для 3-ф системы, А') yield f.gauge('map_battery_current_phase1', j['_I_ph1'], 'Ток потребления/заряда по АКБ для 3-ф системы: Фаза 1') yield f.gauge('map_battery_current_phase2', j['_I_ph2'], 'Ток потребления/заряда по АКБ для 3-ф системы: Фаза 2') yield f.gauge('map_battery_current_phase3', j['_I_ph3'], 'Ток потребления/заряда по АКБ для 3-ф системы: Фаза 3') yield f.gauge('map__P_mppt_avg', j['_P_mppt_avg'], 'Общая мощность от MPPT контроллеров, Вт') yield f.gauge('map__P_acc_3ph', j['_P_acc_3ph'], 'Мощность от АКБ: Все фазы (Знак минус – ток из АКБ. Знак + ток на АКБ (заряд))') yield f.gauge('map_battery_power_phase1', j['_P_ph1'], 'Мощность от АКБ: Фаза 1 (Знак минус – ток из АКБ. Знак + ток на АКБ (заряд))') yield f.gauge('map_battery_power_phase2', j['_P_ph2'], 'Мощность от АКБ: Фаза 2 (Знак минус – ток из АКБ. Знак + ток на АКБ (заряд))') yield f.gauge('map_battery_power_phase3', j['_P_ph3'], 'Мощность от АКБ: Фаза 3 (Знак минус – ток из АКБ. Знак + ток на АКБ (заряд))') yield f.counter('map_E_NET_B', j['_E_NET_B'], 'XXXXXXXXXX') yield f.counter('map_E_ACC_B', j['_E_ACC_B'], 'XXXXXXXXXX') yield f.counter('map_E_ACC_CHARGE_B', j['_E_ACC_CHARGE_B'], 'XXXXXXXXXX') yield f.counter('map_E_NET_SIGN_B', j['_E_NET_SIGN_B'], 'XXXXXXXXX')