Add metrics to the Portal wire protocol (#1006)

This commit is contained in:
Kim De Mey 2022-03-23 16:32:59 +01:00 committed by GitHub
parent 727a3ee7b1
commit bde07054d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 55 additions and 2 deletions

View File

@ -13,7 +13,7 @@
import import
std/[sequtils, sets, algorithm], std/[sequtils, sets, algorithm],
stew/[results, byteutils], chronicles, chronos, nimcrypto/hash, bearssl, stew/[results, byteutils], chronicles, chronos, nimcrypto/hash, bearssl,
ssz_serialization, ssz_serialization, metrics,
eth/rlp, eth/p2p/discoveryv5/[protocol, node, enr, routing_table, random2, eth/rlp, eth/p2p/discoveryv5/[protocol, node, enr, routing_table, random2,
nodes_verification, lru], nodes_verification, lru],
../../content_db, ../../content_db,
@ -22,6 +22,40 @@ import
export messages, routing_table export messages, routing_table
declareCounter portal_message_requests_incoming,
"Portal wire protocol incoming message requests",
labels = ["protocol_id", "message_type"]
declareCounter portal_message_decoding_failures,
"Portal wire protocol message decoding failures",
labels = ["protocol_id"]
declareCounter portal_message_requests_outgoing,
"Portal wire protocol outgoing message requests",
labels = ["protocol_id", "message_type"]
declareCounter portal_message_response_incoming,
"Portal wire protocol incoming message responses",
labels = ["protocol_id", "message_type"]
const requestBuckets = [1.0, 3.0, 5.0, 7.0, 9.0, Inf]
declareHistogram portal_lookup_node_requests,
"Portal wire protocol amount of requests per node lookup",
labels = ["protocol_id"], buckets = requestBuckets
declareHistogram portal_lookup_content_requests,
"Portal wire protocol amount of requests per node lookup",
labels = ["protocol_id"], buckets = requestBuckets
declareCounter portal_lookup_content_failures,
"Portal wire protocol content lookup failures",
labels = ["protocol_id"]
const contentKeysBuckets = [0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, Inf]
declareHistogram portal_content_keys_offered,
"Portal wire protocol amount of content keys per offer message send",
labels = ["protocol_id"], buckets = contentKeysBuckets
declareHistogram portal_content_keys_accepted,
"Portal wire protocol amount of content keys per accept message received",
labels = ["protocol_id"], buckets = contentKeysBuckets
logScope: logScope:
topics = "portal_wire" topics = "portal_wire"
@ -229,6 +263,9 @@ proc messageHandler(protocol: TalkProtocol, request: seq[byte],
if node.isSome(): if node.isSome():
discard p.routingTable.addNode(node.get()) discard p.routingTable.addNode(node.get())
portal_message_requests_incoming.inc(
labelValues = [$p.protocolId, $message.kind])
case message.kind case message.kind
of MessageKind.ping: of MessageKind.ping:
p.handlePing(message.ping, srcId) p.handlePing(message.ping, srcId)
@ -244,6 +281,7 @@ proc messageHandler(protocol: TalkProtocol, request: seq[byte],
debug "Invalid Portal wire message type over talkreq", kind = message.kind debug "Invalid Portal wire message type over talkreq", kind = message.kind
@[] @[]
else: else:
portal_message_decoding_failures.inc(labelValues = [$p.protocolId])
debug "Packet decoding error", error = decoded.error, srcId, srcUdpAddress debug "Packet decoding error", error = decoded.error, srcId, srcUdpAddress
@[] @[]
@ -296,6 +334,8 @@ proc reqResponse[Request: SomeMessage, Response: SomeMessage](
protocolId = p.protocolId protocolId = p.protocolId
trace "Send message request", dstId = dst.id, kind = messageKind(Request) trace "Send message request", dstId = dst.id, kind = messageKind(Request)
portal_message_requests_outgoing.inc(
labelValues = [$p.protocolId, $messageKind(Request)])
let talkresp = let talkresp =
await talkreq(p.baseProtocol, dst, @(p.protocolId), encodeMessage(request)) await talkreq(p.baseProtocol, dst, @(p.protocolId), encodeMessage(request))
@ -314,6 +354,9 @@ proc reqResponse[Request: SomeMessage, Response: SomeMessage](
if messageResponse.isOk(): if messageResponse.isOk():
trace "Received message response", srcId = dst.id, trace "Received message response", srcId = dst.id,
srcAddress = dst.address, kind = messageKind(Response) srcAddress = dst.address, kind = messageKind(Response)
portal_message_response_incoming.inc(
labelValues = [$p.protocolId, $messageKind(Response)])
p.routingTable.setJustSeen(dst) p.routingTable.setJustSeen(dst)
else: else:
debug "Error receiving message response", error = messageResponse.error, debug "Error receiving message response", error = messageResponse.error,
@ -452,6 +495,7 @@ proc findContent*(p: PortalProtocol, dst: Node, contentKey: ByteList):
proc offer*(p: PortalProtocol, dst: Node, contentKeys: ContentKeysList): proc offer*(p: PortalProtocol, dst: Node, contentKeys: ContentKeysList):
Future[PortalResult[void]] {.async.} = Future[PortalResult[void]] {.async.} =
let acceptMessageResponse = await p.offerImpl(dst, contentKeys) let acceptMessageResponse = await p.offerImpl(dst, contentKeys)
portal_content_keys_offered.observe(contentKeys.len().int64)
if acceptMessageResponse.isOk(): if acceptMessageResponse.isOk():
let m = acceptMessageResponse.get() let m = acceptMessageResponse.get()
@ -462,7 +506,9 @@ proc offer*(p: PortalProtocol, dst: Node, contentKeys: ContentKeysList):
if b: if b:
requestedContentKeys.add(contentKeys[i]) requestedContentKeys.add(contentKeys[i])
if requestedContentKeys.len() == 0: let contentKeysAmount = requestedContentKeys.len()
portal_content_keys_accepted.observe(contentKeysAmount.int64)
if contentKeysAmount == 0:
# Don't open an uTP stream if no content was requested # Don't open an uTP stream if no content was requested
return ok() return ok()
@ -576,6 +622,7 @@ proc lookup*(p: PortalProtocol, target: NodeId): Future[seq[Node]] {.async.} =
seen.incl(node.id) seen.incl(node.id)
var pendingQueries = newSeqOfCap[Future[seq[Node]]](alpha) var pendingQueries = newSeqOfCap[Future[seq[Node]]](alpha)
var requestAmount = 0'i64
while true: while true:
var i = 0 var i = 0
@ -585,6 +632,7 @@ proc lookup*(p: PortalProtocol, target: NodeId): Future[seq[Node]] {.async.} =
let n = closestNodes[i] let n = closestNodes[i]
if not asked.containsOrIncl(n.id): if not asked.containsOrIncl(n.id):
pendingQueries.add(p.lookupWorker(n, target)) pendingQueries.add(p.lookupWorker(n, target))
requestAmount.inc()
inc i inc i
trace "Pending lookup queries", total = pendingQueries.len trace "Pending lookup queries", total = pendingQueries.len
@ -615,6 +663,7 @@ proc lookup*(p: PortalProtocol, target: NodeId): Future[seq[Node]] {.async.} =
if closestNodes.len > BUCKET_SIZE: if closestNodes.len > BUCKET_SIZE:
closestNodes.del(closestNodes.high()) closestNodes.del(closestNodes.high())
portal_lookup_node_requests.observe(requestAmount)
p.lastLookup = now(chronos.Moment) p.lastLookup = now(chronos.Moment)
return closestNodes return closestNodes
@ -637,6 +686,7 @@ proc contentLookup*(p: PortalProtocol, target: ByteList, targetId: UInt256):
seen.incl(node.id) seen.incl(node.id)
var pendingQueries = newSeqOfCap[Future[PortalResult[FoundContent]]](alpha) var pendingQueries = newSeqOfCap[Future[PortalResult[FoundContent]]](alpha)
var requestAmount = 0'i64
while true: while true:
var i = 0 var i = 0
@ -646,6 +696,7 @@ proc contentLookup*(p: PortalProtocol, target: ByteList, targetId: UInt256):
let n = closestNodes[i] let n = closestNodes[i]
if not asked.containsOrIncl(n.id): if not asked.containsOrIncl(n.id):
pendingQueries.add(p.findContent(n, target)) pendingQueries.add(p.findContent(n, target))
requestAmount.inc()
inc i inc i
trace "Pending lookup queries", total = pendingQueries.len trace "Pending lookup queries", total = pendingQueries.len
@ -686,12 +737,14 @@ proc contentLookup*(p: PortalProtocol, target: ByteList, targetId: UInt256):
for f in pendingQueries: for f in pendingQueries:
f.cancel() f.cancel()
portal_lookup_content_requests.observe(requestAmount)
return some(content.content) return some(content.content)
else: else:
# TODO: Should we do something with the node that failed responding our # TODO: Should we do something with the node that failed responding our
# query? # query?
discard discard
portal_lookup_content_failures.inc()
return none[seq[byte]]() return none[seq[byte]]()
proc query*(p: PortalProtocol, target: NodeId, k = BUCKET_SIZE): Future[seq[Node]] proc query*(p: PortalProtocol, target: NodeId, k = BUCKET_SIZE): Future[seq[Node]]