bmspy/bmspy/prometheus.py

91 lines
3.3 KiB
Python

import prometheus_client
def prometheus_export(daemonize=True, filename=None):
global debug
if not can_export_prometheus:
raise ModuleNotFoundError("Unable to export to Prometheus. Is prometheus-client installed?")
data = dict()
# Initialize data structure, to fill in help values
while bool(data) is False:
data = collect_data()
time.sleep(1)
registry = prometheus_client.CollectorRegistry(auto_describe=True)
# Set up the metric data structure for Prometheus
metric = prometheus_create_metric(registry, data)
# Populate the metric data structure this period
prometheus_populate_metric(metric, data)
if daemonize:
prometheus_client.start_http_server(9999, registry=registry)
while True:
# Delay, collect new data, and start again
time.sleep(DAEMON_UPDATE_PERIOD)
# Reset data, so it is re-populated correctly
data = dict()
while bool(data) is False:
data = collect_data()
time.sleep(1)
prometheus_populate_metric(metric, data)
prometheus_client.generate_latest(registry)
else:
if filename is None:
print("Invalid filename supplied");
return False
prometheus_client.write_to_textfile(filename, registry=registry)
return True
def prometheus_create_metric(registry, data):
metric = dict()
for name, contains in data.items():
helpmsg = ''
if contains.get('help') is not None:
helpmsg = contains.get('help')
if contains.get('units'):
helpmsg += ' (' + contains.get('units') + ')'
if contains.get('value') is not None:
metric[name] = prometheus_client.Gauge(name, helpmsg, registry=registry)
# Has multiple values, each a different label
elif contains.get('values') is not None:
if contains.get('label') is None:
print("ERROR: no label for {0} specified".format(name))
label = contains.get('label')
metric[name] = prometheus_client.Gauge(name, helpmsg, [label], registry=registry)
elif contains.get('info') is not None:
metric[name] = prometheus_client.Info(name, helpmsg, registry=registry)
else:
pass
return metric
def prometheus_populate_metric(metric, data):
for name, contains in data.items():
if contains.get('value') is not None:
value = contains.get('value')
metric[name].set(value)
# doesn't have a value, but has [1-4]:
if contains.get('values') is not None and isinstance(contains.get('values'), dict):
for idx, label_value in contains.get('values').items():
metric[name].labels(idx).set(label_value)
if contains.get('info'):
value = contains.get('info')
metric[name].info({name: value})
else:
pass
# TODO fork bms daemon if need be?
def main():
print("TODO. At present, run from bmspy directly.")
# influxdb_export(bucket=args.influx_bucket, \
# url=args.influx_url, \
# org=args.influx_org, \
# token=args.influx_token, \
# daemonize=True)
if __name__ == "__main__":
main()