94 lines
2.7 KiB
Python
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)
|