commit d68d700d68740491a21304c6115bb9f13001a3f9
Author: ctucx <c@ctu.cx>
Date: Sun, 19 Jan 2020 19:54:48 +0100
Author: ctucx <c@ctu.cx>
Date: Sun, 19 Jan 2020 19:54:48 +0100
init
6 files changed, 241 insertions(+), 0 deletions(-)
A
|
210
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +fb_exporter
diff --git a/README.md b/README.md @@ -0,0 +1,3 @@ +# fb_exporter + +fixme+ \ No newline at end of file
diff --git a/client.sh b/client.sh @@ -0,0 +1,10 @@ +#!/bin/sh +export BB=/wrapper/ctucx/busybox + +while true; do + /usr/bin/ctlmgr_ctl u inetstat > /tmp/inetstat + /usr/bin/ctlmgr_ctl u mobiled > /tmp/mobiled + echo -ne "POST /update/inetstat?penis123 HTTP/1.1\r\nConnection: Close\r\nContent-Length: $($BB wc -c /tmp/inetstat | $BB cut -d' ' -f1)\r\n\r\n$(cat /tmp/inetstat)\r\n" | $BB nc taurus.ctu.cx 1234 + echo -ne "POST /update/mobiled?penis123 HTTP/1.1\r\nConnection: Close\r\nContent-Length: $($BB wc -c /tmp/mobiled | $BB cut -d' ' -f1)\r\n\r\n$(cat /tmp/mobiled)\r\n" | $BB nc taurus.ctu.cx 1234 + sleep 20 +done+ \ No newline at end of file
diff --git a/fb_exporter.nimble b/fb_exporter.nimble @@ -0,0 +1,14 @@ +# Package + +version = "0.1.0" +author = "ctucx" +description = "A new awesome nimble package" +license = "GPL-2.0" +srcDir = "src" +bin = @["fb_exporter"] + + + +# Dependencies + +requires "nim >= 1.0.4"
diff --git a/nim.cfg b/nim.cfg @@ -0,0 +1 @@ +--passL:"-static -no-pie"
diff --git a/src/fb_exporter.nim b/src/fb_exporter.nim @@ -0,0 +1,210 @@ +import asynchttpserver +import asyncdispatch +import json +import strutils +import times + +# config +var httpPort {.threadvar.}: uint16 +var authToken {.threadvar.}: string + +# state +var mobiled_lastUpdated:int64 = 0 +var mobiled_data {.threadvar.}: JsonNode + +var inetstat_lastUpdated:int64 = 0 +var inetstat_data {.threadvar.}: JsonNode + + +# main +proc isInt*(s: string): bool = + try: + discard s.parseInt() + result = true + except: + discard + +proc isFloat*(s: string): bool = + try: + discard s.parseFloat() + result = true + except: + discard + + +proc parse_ctlmgr(n: string): JsonNode = + var input = n.split("\n") + + input.del(0) + + var last_group = "" + + var data = newJObject() + + for i in items(input): + let line = strip(i) + if line == "": continue + + if endsWith(line, "/"): + last_group = replace(line, "/", "") + continue + + let entry = line.split("=") + + var value = "" + + if entry.len > 1: + value = entry[1] + + if last_group == "": + if isInt(value): + data.add(entry[0], newJInt(parseInt(value))) + elif isFloat(value): + data.add(entry[0], newJFloat(parseFloat(value))) + else: + data.add(entry[0], %(value)) + else: + if not data.hasKey(last_group): + data.add(last_group, newJObject()) + + if isInt(value): + data[last_group].add(entry[0], newJInt(parseInt(value))) + elif isFloat(value): + data[last_group].add(entry[0], newJFloat(parseFloat(value))) + else: + data[last_group].add(entry[0], %(value)) + return data + +proc processHttpClient(req: Request) {.async.} = + if req.reqMethod == HttpGet: + + if inetstat_data != nil or mobiled_data != nil: + if req.url.path == "/metrics": + var res = "" + + var total_transmit = 0 + var total_receive = 0 + var month_transmit = 0 + var month_receive = 0 + var today_transmit = 0 + var today_receive = 0 + + var upstream = 0 + var downstream = 0 + + var cell0_technology = "" + var cell0_quality = 0 + var cell0_band = 0 + var cell0_distance = 0 + + var cell1_technology = "" + var cell1_quality = 0 + var cell1_band = 0 + var cell1_distance = 0 + + if inetstat_lastUpdated != 0: + if inetstat_data.hasKey("Total0"): + #total + if inetstat_data["Total0"].hasKey("BytesSentHigh") and inetstat_data["Total0"].hasKey("BytesSentLow"): + total_transmit = inetstat_data["Total0"]["BytesSentHigh"].getInt() shl 32 + inetstat_data["Total0"]["BytesSentLow"].getInt() + if inetstat_data["Total0"].hasKey("BytesReceivedHigh") and inetstat_data["Total0"].hasKey("BytesReceivedLow"): + total_receive = inetstat_data["Total0"]["BytesReceivedHigh"].getInt() shl 32 + inetstat_data["Total0"]["BytesReceivedLow"].getInt() + + #month + if inetstat_data["ThisMonth0"].hasKey("BytesSentHigh") and inetstat_data["ThisMonth0"].hasKey("BytesSentLow"): + month_transmit = inetstat_data["ThisMonth0"]["BytesSentHigh"].getInt() shl 32 + inetstat_data["ThisMonth0"]["BytesSentLow"].getInt() + if inetstat_data["ThisMonth0"].hasKey("BytesReceivedHigh") and inetstat_data["ThisMonth0"].hasKey("BytesReceivedLow"): + month_receive = inetstat_data["Total0"]["BytesReceivedHigh"].getInt() shl 32 + inetstat_data["Total0"]["BytesReceivedLow"].getInt() + + #today + if inetstat_data["Today0"].hasKey("BytesSentHigh") and inetstat_data["Today0"].hasKey("BytesSentLow"): + today_transmit = inetstat_data["Today0"]["BytesSentHigh"].getInt() shl 32 + inetstat_data["Today0"]["BytesSentLow"].getInt() + if inetstat_data["Today0"].hasKey("BytesReceivedHigh") and inetstat_data["Today0"].hasKey("BytesReceivedLow"): + today_receive = inetstat_data["Today0"]["BytesReceivedHigh"].getInt() shl 32 + inetstat_data["Today0"]["BytesReceivedLow"].getInt() + + #total + res &= "fritzbox_network_transmit_bytes_total " & $(total_transmit) & " " & $(inetstat_lastUpdated * 1000) & "\n" + res &= "fritzbox_network_receive_bytes_total " & $(total_receive) & " " & $(inetstat_lastUpdated * 1000) & "\n" + + #month + res &= "fritzbox_network_transmit_bytes_month " & $(month_transmit) & " " & $(inetstat_lastUpdated * 1000) & "\n" + res &= "fritzbox_network_receive_bytes_month " & $(month_receive) & " " & $(inetstat_lastUpdated * 1000) & "\n" + + #today + res &= "fritzbox_network_transmit_bytes_today " & $(today_transmit) & " " & $(inetstat_lastUpdated * 1000) & "\n" + res &= "fritzbox_network_receive_bytes_today " & $(today_receive) & " " & $(inetstat_lastUpdated * 1000) & "\n" + + if mobiled_lastUpdated != 0: + if mobiled_data.hasKey("ue0"): + if mobiled_data["ue0"].hasKey("conn_rate_rx"): downstream = mobiled_data["ue0"]["conn_rate_rx"].getInt() + if mobiled_data["ue0"].hasKey("conn_rate_tx"): upstream = mobiled_data["ue0"]["conn_rate_tx"].getInt() + + if mobiled_data["ue0"].hasKey("conn_cell"): + let cells = mobiled_data["ue0"]["conn_cell"].getStr.split(",") + + var cell0 = "" + var cell1 = "" + + if cells[0] != "" and mobiled_data.hasKey("cell"&cells[0]): cell0 = "cell"&cells[0] + if cells[1] != "" and mobiled_data.hasKey("cell"&cells[1]): cell1 = "cell"&cells[1] + + if cell0 != "": + if mobiled_data[cell0].hasKey("technology"): cell0_technology = mobiled_data[cell0]["technology"].getStr() + if mobiled_data[cell0].hasKey("quality"): cell0_quality = mobiled_data[cell0]["quality"].getInt() + if mobiled_data[cell0].hasKey("band"): cell0_band = mobiled_data[cell0]["band"].getInt() + if mobiled_data[cell0].hasKey("distance"): cell0_distance = mobiled_data[cell0]["distance"].getInt() + + if cell1 != "": + if mobiled_data[cell1].hasKey("technology"): cell1_technology = mobiled_data[cell1]["technology"].getStr() + if mobiled_data[cell1].hasKey("quality"): cell1_quality = mobiled_data[cell1]["quality"].getInt() + if mobiled_data[cell1].hasKey("band"): cell1_band = mobiled_data[cell1]["band"].getInt() + if mobiled_data[cell1].hasKey("distance"): cell1_distance = mobiled_data[cell1]["distance"].getInt() + + + + res &= "fritzbox_network_downstram " & $(downstream) & " " & $(mobiled_lastUpdated * 1000) & "\n" + res &= "fritzbox_network_upstream " & $(upstream) & " " & $(mobiled_lastUpdated * 1000) & "\n" + + if cell0_band != 0: res &= "fritzbox_network_band{cell=\"0\"} " & $(cell0_band) & " " & $(mobiled_lastUpdated * 1000) & "\n" + if cell0_quality != 0: res &= "fritzbox_network_quality{cell=\"0\"} " & $(cell0_quality) & " " & $(mobiled_lastUpdated * 1000) & "\n" + if cell0_distance != 0: res &= "fritzbox_network_distance{cell=\"0\"} " & $(cell0_distance/1000) & " " & $(mobiled_lastUpdated * 1000) & "\n" + + if cell1_band != 0: res &= "fritzbox_network_band{cell=\"1\"} " & $(cell1_band) & " " & $(mobiled_lastUpdated * 1000) & "\n" + if cell1_quality != 0: res &= "fritzbox_network_quality{cell=\"1\"} " & $(cell1_quality) & " " & $(mobiled_lastUpdated * 1000) & "\n" + if cell1_distance != 0: res &= "fritzbox_network_distance{cell=\"1\"} " & $(cell1_distance/1000) & " " & $(mobiled_lastUpdated * 1000) & "\n" + + await req.respond(Http200, res) + elif req.url.path == "/inetstat.json": + await req.respond(Http200, $(%* inetstat_data)) + elif req.url.path == "/mobiled.json": + await req.respond(Http200, $(%* mobiled_data)) + else: + await req.respond(Http404, "404 Not found") + else: + await req.respond(Http500, "500 No data yet") + + elif req.reqMethod == HttpPost: + if req.url.query == authToken: + if req.url.path == "/update/inetstat": + inetstat_data = parse_ctlmgr(req.body) + inetstat_lastUpdated = toUnix(getTime()) + await req.respond(Http200, "Noted, thanks") + elif req.url.path == "/update/mobiled": + mobiled_data = parse_ctlmgr(req.body) + mobiled_lastUpdated = toUnix(getTime()) + await req.respond(Http200, "Noted, thanks") + else: + await req.respond(Http404, "404 Not found") + else: + await req.respond(Http401, "401 Unauthorized") + + else: + await req.respond(Http405, "405 Method Not Allowed") + +proc serveHttp*() {.async.} = + httpPort = 1234 + authToken = "penis123" + var httpServer = newAsyncHttpServer() + await httpServer.serve(Port(httpPort), processHttpClient) + +waitFor serveHttp()