prometheus-display/exporter/exporter.py
2020-02-10 08:50:05 +03:00

94 lines
2.7 KiB
Python

import os
import sys
import json
import aiohttp
import logging
from collections import namedtuple
from functools import reduce
from aiohttp import web
PORT = os.getenv("PORT", 9115)
UP_HELP = "# HELP state_up State Up/Down status."
UP_TYPE = "# TYPE state_up gauge"
UP_FORMAT = "state_up %d"
CONNECTED_HELP = "# HELP state_connected Connected status."
CONNECTED_TYPE = "# TYPE state_connected gauge"
CONNECTED_FORMAT = "state_connected{display_id=\"%d\"} %d"
LAST_DURATION_HELP = "# HELP state_last_duration Last duration."
LAST_DURATION_TYPE = "# TYPE state_last_duration gauge"
LAST_DURATION_FORMAT = "state_last_duration{display_id=\"%d\"} %d"
LAST_FORECASTS_COUNT_HELP = "# HELP state_last_forecasts_count Last forecasts count."
LAST_FORECASTS_COUNT_TYPE = "# TYPE state_last_forecasts_count gauge"
LAST_FORECASTS_COUNT_FORMAT = "state_last_forecasts_count{display_id=\"%d\"} %d"
Metrics = namedtuple("Metrics", "connected duration forecasts")
def reducer(metrics, state):
display_id = int(state["DisplayId"])
forecasts = -1
if state["Connected"]:
forecasts = int(state["LastForecastsCount"])
metrics.connected.append(CONNECTED_FORMAT % (display_id, int(state["Connected"])))
metrics.duration.append(LAST_DURATION_FORMAT % (display_id, int(state["LastDuration"])))
metrics.forecasts.append(LAST_FORECASTS_COUNT_FORMAT % (display_id, forecasts))
return metrics
def format_metrics(up, metrics):
if up:
return "\n".join([
UP_HELP,
UP_TYPE,
UP_FORMAT % int(up),
CONNECTED_HELP,
CONNECTED_TYPE,
"\n".join(metrics.connected),
LAST_DURATION_HELP,
LAST_DURATION_TYPE,
"\n".join(metrics.duration),
LAST_FORECASTS_COUNT_HELP,
LAST_FORECASTS_COUNT_TYPE,
"\n".join(metrics.forecasts),
])
return "\n".join([UP_HELP, UP_TYPE, UP_FORMAT % int(up)])
async def persistent_session(app):
app["PERSISTENT_SESSION"] = aiohttp.ClientSession()
yield
await app["PERSISTENT_SESSION"].close()
async def fetch(session, url):
async with session.get(url) as response:
data = await response.read()
return json.loads(data)
async def handle(request):
try:
target = request.query["target"]
session = request.app["PERSISTENT_SESSION"]
data = await fetch(session, target)
states = data["GetDisplaysStatesResult"]["DisplayState"]
metrics = reduce(reducer, states, Metrics([], [], []))
return web.Response(text=format_metrics(True, metrics))
except:
return web.Response(text=format_metrics(False, None))
logging.basicConfig(stream=sys.stdout)
app = web.Application()
app.router.add_get('/probe', handle)
app.cleanup_ctx.append(persistent_session)
if __name__ == '__main__':
web.run_app(app, port=PORT)