import times, posix, utils import asyncHttpServer proc prometheusResponse* (request: Request, state: JsonNode) {.async.} = var res = "" if state["inetstat"]["lastUpdated"].getInt == 0 and state["mobiled"]["lastUpdated"].getInt == 0: await request.respond(Http500, "500 No data yet", newHttpHeaders([("Content-Type","text/plain")])) if state["inetstat"]["lastUpdated"].getInt != 0: let data = state["inetstat"]["data"] let lastUpdated = state["inetstat"]["lastUpdated"].getInt if data.hasKey("Total0"): #total res &= "fritzbox_network_transmit_bytes_total " & $(data.getTxTraffic("Total0")) & " " & $(lastUpdated * 1000) & "\n" res &= "fritzbox_network_receive_bytes_total " & $(data.getRxTraffic("Total0")) & " " & $(lastUpdated * 1000) & "\n" #month res &= "fritzbox_network_transmit_bytes_month " & $(data.getTxTraffic("ThisMonth0")) & " " & $(lastUpdated * 1000) & "\n" res &= "fritzbox_network_receive_bytes_month " & $(data.getRxTraffic("ThisMonth0")) & " " & $(lastUpdated * 1000) & "\n" #today res &= "fritzbox_network_transmit_bytes_today " & $(data.getTxTraffic("Today0")) & " " & $(lastUpdated * 1000) & "\n" res &= "fritzbox_network_receive_bytes_today " & $(data.getRxTraffic("Today0")) & " " & $(lastUpdated * 1000) & "\n" if state["mobiled"]["lastUpdated"].getInt != 0: let data = state["mobiled"]["data"] let lastUpdated = state["mobiled"]["lastUpdated"].getInt() if data.hasKey("ue0"): if data["ue0"].hasKey("temperature") and data["ue0"]["temperature"].getInt != 0: res &= "fritzbox_temperature " & $(data["ue0"]["temperature"].getInt/1000) & " " & $(lastUpdated * 1000) & "\n" if data["ue0"].hasKey("conn_rate_rx"): let downstream = data["ue0"]["conn_rate_rx"].getInt() res &= "fritzbox_network_downstream " & $(downstream) & " " & $(lastUpdated * 1000) & "\n" if data["ue0"].hasKey("conn_rate_tx"): let upstream = data["ue0"]["conn_rate_tx"].getInt() res &= "fritzbox_network_upstream " & $(upstream) & " " & $(lastUpdated * 1000) & "\n" if data["ue0"].hasKey("conn_cell"): template parseCell(data: JsonNode, num: int) = let cells = data["ue0"]["conn_cell"].getStr.split(",") if cells[num] != "" and data.hasKey("cell"&cells[num]): let cell = "cell"&cells[num] if data[cell].hasKey("cell_type"): let cell_technology = data[cell]["cell_type"].getStr let tech_id = %* { "umts": 3, "lte": 4 } res &= "fritzbox_cell_techology{cell=\"" & $num & "\"} " & $(tech_id[cell_technology].getInt) & " " & $(lastUpdated * 1000) & "\n" if data[cell].hasKey("quality"): let cell_quality = data[cell]["quality"].getInt res &= "fritzbox_network_quality{cell=\"" & $num & "\"} " & $(cell_quality) & " " & $(lastUpdated * 1000) & "\n" if data[cell].hasKey("band"): let cell_band = data[cell]["band"].getInt res &= "fritzbox_network_band{cell=\"" & $num & "\"} " & $(cell_band) & " " & $(lastUpdated * 1000) & "\n" if data[cell].hasKey("distance"): let cell_distance = data[cell]["distance"].getInt res &= "fritzbox_network_distance{cell=\"" & $num & "\"} " & $(cell_distance/1000) & " " & $(lastUpdated * 1000) & "\n" if data[cell].hasKey("usage"): let cell_usage = data[cell]["usage"].getInt res &= "fritzbox_network_usage{cell=\"" & $num & "\"} " & $(cell_usage) & " " & $(lastUpdated * 1000) & "\n" if data[cell].hasKey("bandwidth"): let bandwidth = data[cell]["bandwidth"].getInt res &= "fritzbox_network_bandwidth{cell=\"" & $num & "\"} " & $(bandwidth) & " " & $(lastUpdated * 1000) & "\n" if data[cell].hasKey("cell_id"): let cell_id = fromHex[int](split(data[cell]["cell_id"].getStr, "-")[0]) res &= "fritzbox_network_cell_id{cell=\"" & $num & "\"} " & $(cell_id) & " " & $(lastUpdated * 1000) & "\n" if data[cell].hasKey("physical_id"): let physical_id = data[cell]["physical_id"].getInt res &= "fritzbox_network_physical_id{cell=\"" & $num & "\"} " & $(physical_id) & " " & $(lastUpdated * 1000) & "\n" data.parseCell(0) data.parseCell(1) await request.respond(Http200, res, newHttpHeaders([("Content-Type","text/plain")])) proc main = # for gcsafe setControlCHook(CtrlCHook) onSignal(SIGTERM): echo "Got SIGTERM! \nStopping Server now!" quit() let authToken = "penis123" var server = newServer("0.0.0.0", 1234) # launch on http://localhost:5000 var state = %* { "inetstat": { "data": {}, "lastUpdated": 0, }, "mobiled": { "data": {}, "lastUpdated": 0, } } server.pages: equals("/"): await request.respond(Http200, "Hello, nothing to see here", newHttpHeaders([("Content-Type","text/plain")])) equals("/metrics"): await request.prometheusResponse(state) equals("/inetstat.json"): if state["inetstat"]["lastUpdated"].getInt != 0: await request.respondJson(Http200, "success", "", state["inetstat"]["data"]) else: await request.respondJson(Http404, "error", "no data yet", newJObject()) equals("/mobiled.json"): if state["mobiled"]["lastUpdated"].getInt != 0: await request.respondJson(Http200, "success", "", state["mobiled"]["data"]) else: await request.respondJson(Http404, "error", "no data yet", newJObject()) startsWith("/update/"): if request.reqMethod == HttpPost: if request.url.query == authToken: if url == "inetstat": state["inetstat"]["data"] = parseCtlMgr(request.body) state["inetstat"]["lastUpdated"] = %toUnix(getTime()) await request.respond(Http200, "Noted, thanks", newHttpHeaders([("Content-Type","text/plain")])) elif url == "mobiled": state["mobiled"]["data"] = parseCtlMgr(request.body) state["mobiled"]["lastUpdated"] = %toUnix(getTime()) await request.respond(Http200, "Noted, thanks", newHttpHeaders([("Content-Type","text/plain")])) else: await request.respond(Http404, "404 Not found", newHttpHeaders([("Content-Type","text/plain")])) else: await request.respond(Http401, "401 Unauthorized", newHttpHeaders([("Content-Type","text/plain")])) else: await request.respond(Http404, "404 Not found", newHttpHeaders([("Content-Type","text/plain")])) server.start() main()