def test_enum(self): i = Enum('ee', 'An enum', ['a', 'b'], registry=self.registry, states=['foo', 'bar']) i.labels('c', 'd').state('bar') self.assertEqual( b'# HELP ee An enum\n# TYPE ee gauge\nee{a="c",b="d",ee="foo"} 0.0\nee{a="c",b="d",ee="bar"} 1.0\n', generate_latest(self.registry))
def test_enum(self): i = Enum('ee', 'An enum', ['a', 'b'], registry=self.registry, states=['foo', 'bar']) i.labels('c', 'd').state('bar') self.assertEqual(b"""# HELP ee An enum # TYPE ee stateset ee{a="c",b="d",ee="foo"} 0.0 ee{a="c",b="d",ee="bar"} 1.0 # EOF """, generate_latest(self.registry))
def test_enum(self): i = Enum('ee', 'An enum', ['a', 'b'], registry=self.registry, states=['foo', 'bar']) i.labels('c', 'd').state('bar') self.assertEqual( json.loads( """{"ee": {"samples": [{"sample_name": "ee", "labels": {"a": "c", "b": "d", "ee": "foo"}, "value": "0.0", "timestamp": null, "exemplar": {}}, {"sample_name": "ee", "labels": {"a": "c", "b": "d", "ee": "bar"}, "value": "1.0", "timestamp": null, "exemplar": {}}], "help": "An enum","type": "stateset"}}"""), json.loads(self.json_exporter.generate_latest_json()))
def enum(self, name: str = None, desc: str = None, states: List[str] = None, labels: Dict[str, str] = None) -> object: """ A wrapped instance of Enum from the prometheus_client. Use enum to track the state of a function call :param name: the name of the enum metric :param desc: the description for the metric :param states: the states that the enum metric can have :param labels: a dict containing the labels for the metric """ if states is None or not isinstance(states, (List, Tuple)): raise ValueError(f"Enum requires a list of states,\ cannot use value of type: {type(states).__name__}" ) labels = labels or {} e = Enum(name, desc, tuple(labels.keys()), registry=self.registry, states=states) if len(labels) > 0: e = e.labels(list(labels.values())) return e
def getServiceStates(self, registry, **kwargs): """Get all Services states.""" serviceState = Enum( 'service_state', 'Description of enum', labelnames=['servicename'], states=['OK', 'UNKNOWN', 'FAILED', 'KEYBOARDINTERRUPT'], registry=registry) services = self.dbI[kwargs['sitename']].get('servicestates') # {'servicestate': u'OK', 'hostname': u'4df8c7b989d1', # 'servicename': u'LookUpService', 'id': 1, 'updatedate': 1601047007} timenow = int(getUTCnow()) for service in services: state = 'UNKNOWN' if int(timenow - service['updatedate']) < 120: # If we are not getting service state for 2 mins, leave state as unknown state = service['servicestate'] serviceState.labels( servicename=service['servicename']).state(state)
def pushData(sensorId, battery, realtimeData, configuration, plant, influxDbClient): flower = {} flower["plant"] = ("Plant", str(plant["name"])) flower["location"] = ("Location", str(plant["location"])) if battery is not None: flower["battery"] = ("Battery", battery) if realtimeData.battery is not None: flower["battery"] = ("Battery", int(realtimeData.battery)) if realtimeData.temperature is not None: flower["air_temperature"] = ("Temperature", float(realtimeData.temperature)) flower["air_temperature_status"] = [ "Temperature Status", "good", ["good", "too_low", "too_high"] ] if realtimeData.temperature < plant["temperature_C_threshold_lower"]: flower["air_temperature_status"][1] = "too_low" elif realtimeData.temperature > plant["temperature_C_threshold_upper"]: flower["air_temperature_status"][1] = "too_high" if realtimeData.conductivity is not None: flower["fertilizer"] = ("Fertilizer", float(realtimeData.conductivity)) flower["fertilizer_status"] = [ "Fertilizer Status", "good", ["good", "too_low", "too_high"] ] if realtimeData.conductivity < plant["fertility_us_cm_threshold_lower"]: flower["fertilizer_status"][1] = "too_low" elif realtimeData.conductivity > plant[ "fertility_us_cm_threshold_upper"]: flower["fertilizer_status"][1] = "too_high" if realtimeData.light is not None: flower["light"] = ("Light", float(realtimeData.light)) flower["light_status"] = [ "Light Status", "good", ["good", "too_low", "too_high"] ] if realtimeData.light < plant["light_lux_threshold_lower"]: flower["light_status"][1] = "too_low" elif realtimeData.light > plant["light_lux_threshold_upper"]: flower["light_status"][1] = "too_high" if realtimeData.moisture is not None: flower["watering"] = ("Moisture", float(realtimeData.moisture)) flower["watering_status"] = [ "Moisture Status", "good", ["good", "too_low", "too_high"] ] if realtimeData.moisture < plant["moisture_threshold_lower"]: flower["watering_status"][1] = "too_low" elif realtimeData.moisture > plant["moisture_threshold_upper"]: flower["watering_status"][1] = "too_high" now = datetime.utcnow() lastUtc = ("Updated", now.strftime("%Y-%m-%dT%H:%M:%SZ") ) #2017-11-13T17:44:11Z if configuration["mqtt"]["enabled"]: print("Pushing Mqtt", sensorId, ":", configuration["mqtt"]["prefix"], flower) try: broadcastMqtt(configuration["mqtt"]["client"], configuration["mqtt"]["server"], configuration["mqtt"]["port"], configuration["mqtt"]["prefix"], sensorId + "/update", json.dumps(flower)) except Exception as ex: print("Error on mqtt broadcast", ex) if configuration["prometheuspush"]["enabled"]: registry = CollectorRegistry() for key in flower.keys(): if type(flower[key][1]) is str: if len(flower[key]) == 3: e = Enum(configuration["prometheuspush"]["prefix"] + '_' + key + '_total', flower[key][0], ['sensorid'], states=flower[key][2], registry=registry) e.labels(sensorid=sensorId).state(flower[key][1]) else: g = Gauge(configuration["prometheuspush"]["prefix"] + '_' + key + '_total', flower[key][0], ['sensorid'], registry=registry) g.labels(sensorid=sensorId).set(flower[key][1]) print("Pushing Prometheus", sensorId, ":", configuration["prometheuspush"]["prefix"] + '_' + key + '_total', "=", flower[key]) try: push_to_gateway(configuration["prometheuspush"]["server"] + ":" + configuration["prometheuspush"]["port"], job=configuration["prometheuspush"]["client"] + "_" + sensorId, registry=registry) except Exception as ex: print("Error on prometheus push", ex) if configuration["influxdb"]["enabled"]: influxDbJson = [{ "measurement": configuration["influxdb"]["prefix"], "tags": { "sensor": sensorId, }, "time": lastUtc[1], "fields": {} }] for key in flower.keys(): influxDbJson[0]["fields"][key] = flower[key][1] print("Pushing InfluxDb", influxDbJson) try: influxDbClient.write_points( influxDbJson, retention_policy=configuration["influxdb"]["policy"]) except Exception as ex: print("Error on influxdb write_points", ex)
def push_job_information(self): ''' Process Bareos job data and send it to the prometheus pushgateway ''' registry = CollectorRegistry() TIME_BUCKETS=(6, 60, 600, 1800, 3600, 10800, 18000, 28800, 86400) bareos_job_status = Enum('bareos_job_status', 'Backup Status', states=self.job_status.values(), labelnames=['instance', 'jobid'], registry=registry) # see https://github.com/bareos/bareos/blob/master/core/src/include/job_level.h bareos_job_level = Enum('bareos_job_level', 'Backup Level', states=self.job_levels.values(), labelnames=['instance', 'jobid'], registry=registry) bareos_job_running_time = Histogram('bareos_job_running_time', 'Job running time', labelnames=['instance', 'jobid'], registry=registry, buckets=TIME_BUCKETS) bareos_job_files = Gauge('bareos_job_files', 'Backed up files', labelnames=['instance', 'jobid'], registry=registry) bareos_job_bytes = Gauge('bareos_job_bytes', 'Backed up bytes', labelnames=['instance', 'jobid'], registry=registry) bareos_job_throughput = Gauge('bareos_job_throughtput', 'Backup throughtput', registry=registry, labelnames=['instance', 'jobid']) # see https://github.com/bareos/bareos/blob/master/core/src/include/job_types.h bareos_job_type = Enum('bareos_job_type', 'Job Type', states=self.job_types.values(), registry=registry, labelnames=['instance', 'jobid']) bareos_job_client = Info('bareos_job_client', 'Client', registry=registry, labelnames=['instance', 'jobid']) bareos_job_priority = Gauge('bareos_job_priority', 'Job Priority', registry=registry, labelnames=['instance', 'jobid']) bareos_job_name = '_'.join(self.jobName.split('.')[:-3]) bareos_job_id = self.jobId if (self.jobStatus == 'E' or self.jobStatus == 'f' or self.jobStatus == 'A') and self.report_failed == False: return bareos_job_status.labels(instance=bareos_job_name, jobid=bareos_job_id).state(self.job_status[self.jobStatus]) bareos_job_running_time.labels(instance=bareos_job_name, jobid=bareos_job_id).observe(self.jobRunningTime) bareos_job_files.labels(instance=bareos_job_name, jobid=bareos_job_id).set(self.jobFiles) bareos_job_bytes.labels(instance=bareos_job_name, jobid=bareos_job_id).set(self.jobBytes) bareos_job_throughput.labels(instance=bareos_job_name, jobid=bareos_job_id).set(self.throughput) bareos_job_priority.labels(instance=bareos_job_name, jobid=bareos_job_id).set(self.Priority) bareos_job_level.labels(instance=bareos_job_name, jobid=bareos_job_id).state(self.job_levels[self.jobLevel]) bareos_job_type.labels(instance=bareos_job_name, jobid=bareos_job_id).state(self.job_types[chr(self.jobType)]) bareos_job_client.labels(instance=bareos_job_name, jobid=bareos_job_id).info({'client': self.jobClient}) if self.use_tls == True or self.use_tls == 'yes': gateway = "https://{}:{}".format(self.gateway_host,self.gateway_port) else: gateway = "{}:{}".format(self.gateway_host,self.gateway_port) bareosdir.DebugMessage(100, "Submitting metrics to {}\n".format(gateway)) try: if self.use_basic_auth: push_to_gateway('{}'.format(gateway), job='bareos', registry=registry, handler=self.authentication_handler) else: push_to_gateway('{}'.format(gateway), job='bareos', registry=registry) except Exception as excp: bareosdir.DebugMessage(100, "Error: Submitting metrics to pushgateway '{}' failed.\n".format(gateway)) bareosdir.DebugMessage(100, "python error was: {}\n".format(excp)) bareosdir.JobMessage(bareosdir.M_INFO, "Failed to submit metrics to pushgateway\n")
json.dumps(flower)) except Exception, ex: print "Error on mqtt broadcast", ex if configuration["prometheuspush"]["enabled"]: registry = CollectorRegistry() for key in flower.keys(): if type(flower[key][1]) is str: if len(flower[key]) == 3: e = Enum(configuration["prometheuspush"]["prefix"] + '_' + key + '_total', flower[key][0], ['sensorid'], states=flower[key][2], registry=registry) e.labels(sensorid=sensorId).state(flower[key][1]) else: g = Gauge(configuration["prometheuspush"]["prefix"] + '_' + key + '_total', flower[key][0], ['sensorid'], registry=registry) g.labels(sensorid=sensorId).set(flower[key][1]) print "Pushing Prometheus", sensorId, ":", configuration["prometheuspush"]["prefix"] + '_' + key + '_total', "=", flower[key] try: push_to_gateway(configuration["prometheuspush"]["server"] + ":" + configuration["prometheuspush"]["port"], job=configuration["prometheuspush"]["client"] + "_" + sensorId, registry=registry) except Exception, ex: print "Error on prometheus push", ex
class Jevois(Device): options = {"objects":"","objectidentified":True,"objectlocation":True,"objectsize":False} objectLocationX = Gauge("object_location_x", "Identified object's x position", ["device_id","device_type","station"]) objectLocationY = Gauge("object_location_y", "Identified object's y position", ["device_id","device_type","station"]) objectLocationZ = Gauge("object_location_z", "Identified object's Z position", ["device_id","device_type","station"]) objectSize = Gauge("object_size","Identified object's size", ["device_id","device_type","station"]) def connect(self): try: self.serial = serial.Serial(self.port, 115200, timeout=0) self.__initialize() except Exception as e: raise Exception(str(e)) def __initialize(self): if self.isEnabled("objectidentified"): if self.section["objects"] is not None: self.objects = [" "] # remove extension part and add to the objects list for obj in self.section["objects"].split(): self.objects.append(obj.split(".")[0]) self.objectIdentified = Enum("object_id_"+self.port, "Object Identified", ["device_id","device_type","station"], states=self.objects) else: raise Exception("The \"objects\" list is necessary for monitoring identified objects") def fetch(self): line = self.serial.readline().rstrip().decode() tok = line.split() # in case of no identified object (empty message) or malformed line (as a message with Normal serstyle has 6 fields) skip fetching if len(tok) < 6: if self.isEnabled("objectidentified"): self.objectIdentified.labels(device_id=self.id, device_type=self.type, station=self.host).state(" ") Jevois.objectLocationX.labels(device_id=self.id, device_type=self.type, station=self.host).set(0) Jevois.objectLocationY.labels(device_id=self.id, device_type=self.type, station=self.host).set(0) Jevois.objectLocationZ.labels(device_id=self.id, device_type=self.type, station=self.host).set(0) Jevois.objectSize.labels(device_id=self.id, device_type=self.type, station=self.host).set(0) self.serial.flushInput() return serstyle = tok[0][0] dimension = tok[0][1] # If the serstyle is not Normal (thus it is not supported by the module) if (serstyle != "N"): raise Exception("Unsupported serstyle (" + serstyle + ")") if dimension == "1" and len(tok) != 4: raise Exception("Malformed line (expected 4 fields but received " + str(len(tok)) + ")") if dimension == "2" and len(tok) != 6: raise Exception("Malformed line (expected 6 fields but received " + str(len(tok)) + ")") if dimension == "3" and len(tok) != 8: raise Exception("Malformed line (expected 8 fields but received " + str(len(tok)) + ")") if self.isEnabled("objectidentified"): if len(self.objects) > 1: obj = tok[1].split(".")[0] if obj in self.objects: self.objectIdentified.labels(device_id=self.id, device_type=self.type, station=self.host).state(obj) else: self.objectIdentified.labels(device_id=self.id, device_type=self.type, station=self.host).state(" ") else: raise Exception("The \"objects\" list exists but is empty") if self.isEnabled("objectlocation"): Jevois.objectLocationX.labels(device_id=self.id, device_type=self.type, station=self.host).set(float(tok[2])) if int(dimension) > 1: Jevois.objectLocationY.labels(device_id=self.id, device_type=self.type, station=self.host).set(float(tok[3])) if int(dimension) == 3: Jevois.objectLocationZ.labels(device_id=self.id, device_type=self.type, station=self.host).set(float(tok[4])) if self.isEnabled("objectsize"): if dimension == "1": Jevois.objectSize.labels(device_id=self.id, device_type=self.type, station=self.host).set(float(tok[3])) elif dimension == "2": Jevois.objectSize.labels(device_id=self.id, device_type=self.type, station=self.host).set(abs(float(tok[4])*float(tok[5]))) elif dimension == "3": Jevois.objectSize.labels(device_id=self.id, device_type=self.type, station=self.host).set(abs(float(tok[5])*float(tok[6])*float(tok[7]))) self.serial.flushInput() def disconnect(self): self.serial.close()
def getGardenCallback(self, err, res): if err: print err else: if configuration["influxdb"]["enabled"]: influxDbClient = InfluxDBClient( configuration["influxdb"]["server"], configuration["influxdb"]["port"], configuration["influxdb-username"], configuration["influxdb"]["password"], configuration["influxdb"]["database"]) try: influxDbClient.create_database( configuration["influxdb"]["database"]) except InfluxDBClientError, ex: print "InfluxDBClientError", ex influxDbClient.create_retention_policy( configuration["influxdb"]["policy"], 'INF', 3, default=True) for location in res["locations"]: #print json.dumps(location, indent=2, sort_keys=True) sensorId = location["sensor"]["sensor_identifier"][-4:].lower() flower = {} #flower["sensor_name"] = location["sensor"]["sensor_identifier"] if location["battery"]["gauge_values"][ "current_value"] is not None: flower["battery"] = ( "Battery", int(location["battery"]["gauge_values"] ["current_value"])) if location["air_temperature"]["gauge_values"][ "current_value"] is not None: flower["air_temperature"] = ( "Temperature", float(location["air_temperature"]["gauge_values"] ["current_value"])) flower["air_temperature_status"] = [ "Temperature Status", str(location["air_temperature"] ["instruction_key"]).replace( "air_temperature_", ""), ["good", "too_low", "too_high"] ] if location["fertilizer"]["gauge_values"][ "current_value"] is not None: flower["fertilizer"] = ( "Fertilizer", float(location["fertilizer"]["gauge_values"] ["current_value"])) flower["fertilizer_status"] = [ "Fertilizer Status", str(location["fertilizer"]["instruction_key"]).replace( "fertilizer_", ""), ["good", "too_low", "too_high"] ] if location["light"]["gauge_values"][ "current_value"] is not None: flower["light"] = ("Light", float(location["light"]["gauge_values"] ["current_value"])) flower["light_status"] = [ "Light Status", str(location["light"]["instruction_key"]).replace( "light_", ""), ["good", "too_low", "too_high"] ] if location["watering"]["soil_moisture"]["gauge_values"][ "current_value"] is not None: flower["watering"] = ( "Moisture", float(location["watering"]["soil_moisture"] ["gauge_values"]["current_value"])) flower["watering_status"] = [ "Moisture Status", str(location["watering"]["soil_moisture"] ["instruction_key"]).replace("soil_moisture_", ""), ["good", "too_low", "too_high"] ] lastUtc = ("Updated", str(location["last_sample_utc"])) if configuration["mqtt"]["enabled"]: print "Pushing Mqtt", sensorId, ":", configuration["mqtt"][ "prefix"], flower try: broadcastMqtt(configuration["mqtt"]["client"], configuration["mqtt"]["server"], configuration["mqtt"]["port"], configuration["mqtt"]["prefix"], sensorId + "/update", json.dumps(taflowerg)) except Exception, ex: print "Error on mqtt broadcast", ex if configuration["prometheuspush"]["enabled"]: registry = CollectorRegistry() for key in flower.keys(): print "Pushing", sensorId, ":", configuration[ "prometheuspush"][ "prefix"] + '_' + key + '_total', "=", flower[ key] if flower[key][1] is None: continue elif type(flower[key][1]) is str: e = Enum( configuration["prometheuspush"]["prefix"] + '_' + key + '_total', flower[key][0], ['sensorid'], states=flower[key][2], registry=registry) e.labels(sensorid=sensorId).state(flower[key][1]) else: g = Gauge( configuration["prometheuspush"]["prefix"] + '_' + key + '_total', flower[key][0], ['sensorid'], registry=registry) g.labels(sensorid=sensorId).set(flower[key][1]) print "Pushing", sensorId, ":", configuration[ "prometheuspush"][ "prefix"] + '_' + key + '_total', "=", flower[key] try: push_to_gateway( configuration["prometheuspush"]["server"] + ":" + configuration["prometheuspush"]["port"], job=configuration["prometheuspush"]["client"] + "_" + sensorId, registry=registry) except: print "Prometheus not available" if configuration["influxdb"]["enabled"]: influxDbJson = [{ "measurement": configuration["influxdb"]["prefix"], "tags": { "sensor": sensorId, }, "time": lastUtc[1], "fields": {} }] for key in flower.keys(): influxDbJson[0]["fields"][key] = flower[key][1] print "Pushing", influxDbJson try: influxDbClient.write_points( influxDbJson, retention_policy=configuration["influxdb"] ["policy"]) except: print "Influxdb not available"