nwaku/apps/networkmonitor/networkmonitor_metrics.nim

109 lines
3.2 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, tables, sequtils],
chronicles,
chronicles/topics_registry,
chronos,
json_serialization,
metrics,
metrics/chronos_httpserver,
presto/route,
presto/server,
stew/results,
stew/shims/net
logScope:
topics = "networkmonitor_metrics"
# On top of our custom metrics, the following are reused from nim-eth
#routing_table_nodes{state=""}
#routing_table_nodes{state="seen"}
#discovery_message_requests_outgoing_total{response=""}
#discovery_message_requests_outgoing_total{response="no_response"}
declarePublicGauge networkmonitor_peer_type_as_per_enr,
"Number of peers supporting each capability according to the ENR",
labels = ["capability"]
declarePublicGauge networkmonitor_peer_type_as_per_protocol,
"Number of peers supporting each protocol, after a successful connection) ",
labels = ["protocols"]
declarePublicGauge networkmonitor_peer_user_agents,
"Number of peers with each user agent", labels = ["user_agent"]
declarePublicHistogram networkmonitor_peer_ping,
"Histogram tracking ping durations for discovered peers",
buckets =
[100.0, 200.0, 300.0, 400.0, 500.0, 600.0, 700.0, 800.0, 900.0, 1000.0, 2000.0, Inf]
declarePublicGauge networkmonitor_peer_count,
"Number of discovered peers", labels = ["connected"]
declarePublicGauge networkmonitor_peer_country_count,
"Number of peers per country", labels = ["country"]
type
CustomPeerInfo* = object # populated after discovery
lastTimeDiscovered*: int64
discovered*: int64
peerId*: string
enr*: string
ip*: string
enrCapabilities*: seq[string]
country*: string
city*: string
# only after ok connection
lastTimeConnected*: int64
retries*: int64
supportedProtocols*: seq[string]
userAgent*: string
lastPingDuration*: Duration
avgPingDuration*: Duration
# only after a ok/nok connection
connError*: string
CustomPeerInfoRef* = ref CustomPeerInfo
# Stores information about all discovered/connected peers
CustomPeersTableRef* = TableRef[string, CustomPeerInfoRef]
# stores the content topic and the count of rx messages
ContentTopicMessageTableRef* = TableRef[string, int]
proc installHandler*(
router: var RestRouter,
allPeers: CustomPeersTableRef,
numMessagesPerContentTopic: ContentTopicMessageTableRef,
) =
router.api(MethodGet, "/allpeersinfo") do() -> RestApiResponse:
let values = toSeq(allPeers.values())
return RestApiResponse.response(values.toJson(), contentType = "application/json")
router.api(MethodGet, "/contenttopics") do() -> RestApiResponse:
# TODO: toJson() includes the hash
return RestApiResponse.response(
$(%numMessagesPerContentTopic), contentType = "application/json"
)
proc startMetricsServer*(serverIp: IpAddress, serverPort: Port): Result[void, string] =
info "Starting metrics HTTP server", serverIp, serverPort
try:
startMetricsHttpServer($serverIp, serverPort)
except Exception as e:
error(
"Failed to start metrics HTTP server",
serverIp = serverIp,
serverPort = serverPort,
msg = e.msg,
)
info "Metrics HTTP server started", serverIp, serverPort
ok()