Example #1
0
 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))
Example #2
0
    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))
Example #3
0
 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
Example #5
0
 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)
Example #6
0
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)
Example #7
0
    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
Example #9
0
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"