logos-messaging-nim/tools/networkmonitor/networkmonitor_utils.nim
Alvaro Revuelta 172fa9bf38 chore(networkmonitor): tool to discover and provide metrics on peers (#1290)
* chore(networkmonitor): initial prototype

* chore(networkmonitor): add cli, metrics and PoC

* feat(utils): add supportsCapability function + tests

* feat(utils): add supportedCapabilites function

* chore(networkmonitor): add metrics with enr/ip/capabilities

* chore(networkmonitor): refactor + tests

* chore(networkmonitor): add discovered timestamp

* chore(networkmonitor): add metrics on connected nodes

* chore(networkmonitor): new flags + utils file + readme

* chore(networkmonitor): add user-agent metrics

* chore(networkmonitor): connect only to randomly discovered peers

* chore(networkmonitor): get location of peer using ip

* chore(networkmonitor): expose peer metrics with simple rest server

* chore(networkmonitor): update README

* chore(networkmonitor): fix wakunode2 to waku_node

* chore(networkmonitor): fix import order

* chore(networkmonitor): fix comments + refactor + pushraises

* chore(networkmonitor): refactor + handle exceptions

* chore(networkmonitor): fix makefile after rebase

* chore(networkmonitor): address review comments 1

* chore(networkmonitor): add nim.cfg
2022-11-10 10:29:34 +01:00

53 lines
1.5 KiB
Nim
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:
{.push raises: [].}
import
std/[json,httpclient],
chronicles,
chronicles/topics_registry,
chronos,
stew/results
type
NodeLocation = object
country*: string
city*: string
lat*: string
long*: string
isp*: string
proc flatten*[T](a: seq[seq[T]]): seq[T] =
var aFlat = newSeq[T](0)
for subseq in a:
aFlat &= subseq
return aFlat
# using an external api retrieves some data associated with the ip
# TODO: use a cache
# TODO: use nim-presto's HTTP asynchronous client
proc ipToLocation*(ip: string,
client: Httpclient):
Future[Result[NodeLocation, string]] {.async.} =
# naive mechanism to avoid hitting the rate limit
# IP-API endpoints are now limited to 45 HTTP requests per minute
await sleepAsync(1400)
try:
let content = client.getContent("http://ip-api.com/json/" & ip)
let jsonContent = parseJson(content)
if $jsonContent["status"].getStr() != "success":
error "query failed", result=jsonContent
return err("query failed: " & $jsonContent)
return ok(NodeLocation(
country: jsonContent["country"].getStr(),
city: jsonContent["city"].getStr(),
lat: jsonContent["lat"].getStr(),
long: jsonContent["lon"].getStr(),
isp: jsonContent["isp"].getStr()
))
except:
error "failed to get the location for IP", ip=ip, error=getCurrentExceptionMsg()
return err("failed to get the location for IP '" & ip & "':" & getCurrentExceptionMsg())