You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuweni.apache.org by to...@apache.org on 2021/08/03 06:51:01 UTC
[incubator-tuweni] branch main updated: Add client version stats
This is an automated email from the ASF dual-hosted git repository.
toulmean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git
The following commit(s) were added to refs/heads/main by this push:
new fb4ccf6 Add client version stats
new eb826d0 Merge pull request #334 from atoulme/add_client_version_stats
fb4ccf6 is described below
commit fb4ccf64c8d824629f6fedc9c800127b7207662c
Author: Antoine Toulme <an...@lunar-ocean.com>
AuthorDate: Mon Aug 2 23:18:53 2021 -0700
Add client version stats
---
.../tuweni/eth/crawler/RelationalPeerRepository.kt | 13 +++++-
.../rest/{ClientVersion.kt => ClientIdInfo.kt} | 38 +++++++++++++---
.../tuweni/eth/crawler/rest/ClientsService.kt | 12 ++++-
.../tuweni/eth/crawler/rest/ClientIdInfoTest.kt | 53 ++++++++++++++++++++++
4 files changed, 106 insertions(+), 10 deletions(-)
diff --git a/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/RelationalPeerRepository.kt b/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/RelationalPeerRepository.kt
index a1c166e..1c769df 100644
--- a/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/RelationalPeerRepository.kt
+++ b/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/RelationalPeerRepository.kt
@@ -32,7 +32,7 @@ import org.apache.tuweni.devp2p.Peer
import org.apache.tuweni.devp2p.PeerRepository
import org.apache.tuweni.devp2p.eth.Status
import org.apache.tuweni.devp2p.parseEnodeUri
-import org.apache.tuweni.eth.crawler.rest.ClientVersion
+import org.apache.tuweni.eth.crawler.rest.ClientIdInfo
import org.apache.tuweni.rlpx.wire.WireConnection
import org.slf4j.LoggerFactory
import java.net.URI
@@ -228,6 +228,7 @@ open class RelationalPeerRepository(
private var clientIds: List<ClientInfo>? = null
private var londonStats: ClientReadyStats? = null
+ private var clientsStats: Map<String, Map<String, Long>>? = null
private val started = AtomicBoolean(false)
fun start() {
@@ -241,18 +242,24 @@ open class RelationalPeerRepository(
clientIds = newClientIds
var londonReady = 0
var total = 0
+ val newClientsStats = mutableMapOf<String, MutableMap<String, Long>>()
newClientIds.forEach { newClientCount ->
total += newClientCount.count
- val clientVersion = ClientVersion(newClientCount.clientId)
+ val clientVersion = ClientIdInfo(newClientCount.clientId)
+ val versionStats = newClientsStats.computeIfAbsent(clientVersion.name) { mutableMapOf() }
+ val statsCount = versionStats[clientVersion.version] ?: 0
+ versionStats[clientVersion.version] = statsCount + newClientCount.count
londonClientVersions[clientVersion.name().toLowerCase()]?.let { londonVersion ->
if (clientVersion >= londonVersion) {
londonReady += newClientCount.count
}
}
}
+ clientsStats = newClientsStats
londonStats = ClientReadyStats(total, londonReady)
totalClientsGauge.record(total.toLong())
clientCalculationsCounter.add(1)
+
delay(clientsStatsDelay)
}
}
@@ -266,6 +273,8 @@ open class RelationalPeerRepository(
internal fun getClientIds(): List<ClientInfo> = clientIds ?: listOf()
+ internal fun getClientStats(): Map<String, Map<String, Long>> = clientsStats ?: mapOf()
+
internal fun getClientIdsInternal(): List<ClientInfo> {
dataSource.connection.use { conn ->
val sql = "select clients.clientId, count(clients.clientId) from (select nodeinfo.clientId, nodeInfo.createdAt from nodeinfo inner join (select identity, max(createdAt) as maxCreatedAt from nodeinfo group by identity) maxSeen on nodeinfo.identity = maxSeen.identity and nodeinfo.createdAt = maxSeen.maxCreatedAt) as clients where clients.createdAt > ? group by clients.clientId"
diff --git a/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/ClientVersion.kt b/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/ClientIdInfo.kt
similarity index 55%
rename from eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/ClientVersion.kt
rename to eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/ClientIdInfo.kt
index 2e73f3e..6246779 100644
--- a/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/ClientVersion.kt
+++ b/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/ClientIdInfo.kt
@@ -16,17 +16,41 @@
*/
package org.apache.tuweni.eth.crawler.rest
-data class ClientVersion(val clientId: String) : Comparable<String> {
+data class ClientIdInfo(val clientId: String) : Comparable<String> {
- val segments = clientId.split("/")
+ val name: String
+ val label: String
+ val version: String
+ val os: String
+ val compiler: String
+ init {
+ val segments = clientId.split("/")
+ if (segments.size == 4) {
+ name = segments[0]
+ label = ""
+ version = segments[1]
+ os = segments[2]
+ compiler = segments[3]
+ } else if (segments.size == 5) {
+ name = segments[0]
+ label = segments[1]
+ version = segments[2]
+ os = segments[3]
+ compiler = segments[4]
+ } else {
+ name = segments[0]
+ version = ""
+ label = ""
+ os = ""
+ compiler = ""
+ }
+ }
- fun name() = segments[0]
+ fun name() = name
- fun version() = segments.firstOrNull() {
- it.startsWith("v")
- }
+ fun version() = version
override fun compareTo(other: String): Int {
- return version()?.compareTo(other) ?: 1
+ return version().compareTo(other)
}
}
diff --git a/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/ClientsService.kt b/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/ClientsService.kt
index 7aea9c4..076d04a 100644
--- a/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/ClientsService.kt
+++ b/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/ClientsService.kt
@@ -54,10 +54,20 @@ class ClientsService {
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("london/stats")
- fun getClientStats(): String {
+ fun getLondonStats(): String {
val repo = context!!.getAttribute("repo") as RelationalPeerRepository
val peers = repo.getLondonStats()
val result = mapper.writeValueAsString(peers)
return result
}
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("stats")
+ fun getClientStats(): String {
+ val repo = context!!.getAttribute("repo") as RelationalPeerRepository
+ val stats = repo.getClientStats()
+ val result = mapper.writeValueAsString(stats)
+ return result
+ }
}
diff --git a/eth-crawler/src/test/kotlin/org/apache/tuweni/eth/crawler/rest/ClientIdInfoTest.kt b/eth-crawler/src/test/kotlin/org/apache/tuweni/eth/crawler/rest/ClientIdInfoTest.kt
new file mode 100644
index 0000000..4cc3b94
--- /dev/null
+++ b/eth-crawler/src/test/kotlin/org/apache/tuweni/eth/crawler/rest/ClientIdInfoTest.kt
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuweni.eth.crawler.rest
+
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
+
+class ClientIdInfoTest {
+
+ @Test
+ fun testNoLabel() {
+ val clientInfo = ClientIdInfo("Parity-Ethereum/v2.7.2-stable-2662d19-20200206/x86_64-unknown-linux-gnu/rustc1.41.0")
+ assertEquals("Parity-Ethereum", clientInfo.name)
+ assertEquals("", clientInfo.label)
+ assertEquals("v2.7.2-stable-2662d19-20200206", clientInfo.version)
+ assertEquals("x86_64-unknown-linux-gnu", clientInfo.os)
+ assertEquals("rustc1.41.0", clientInfo.compiler)
+ }
+
+ @Test
+ fun testWithLabel() {
+ val clientInfo = ClientIdInfo("OpenEthereum/Bob Ross/v3.0.1-stable-8ca8089-20200601/x86_64-unknown-linux-gnu/rustc1.43.1")
+ assertEquals("OpenEthereum", clientInfo.name)
+ assertEquals("Bob Ross", clientInfo.label)
+ assertEquals("v3.0.1-stable-8ca8089-20200601", clientInfo.version)
+ assertEquals("x86_64-unknown-linux-gnu", clientInfo.os)
+ assertEquals("rustc1.43.1", clientInfo.compiler)
+ }
+
+ @Test
+ fun testMalformed() {
+ val clientInfo = ClientIdInfo("Foo Bar 1.23")
+ assertEquals("Foo Bar 1.23", clientInfo.name)
+ assertEquals("", clientInfo.label)
+ assertEquals("", clientInfo.version)
+ assertEquals("", clientInfo.os)
+ assertEquals("", clientInfo.compiler)
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tuweni.apache.org
For additional commands, e-mail: commits-help@tuweni.apache.org