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/07/23 20:54:40 UTC
[incubator-tuweni] branch main updated: Add metering handler
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 4842d54 Add metering handler
new 5fd5759 Merge pull request #313 from atoulme/add_metering_handler
4842d54 is described below
commit 4842d545e7100a6ac6a0ed66d0d536baa21209cc
Author: Antoine Toulme <an...@lunar-ocean.com>
AuthorDate: Fri Jul 23 13:02:58 2021 -0700
Add metering handler
---
jsonrpc/build.gradle | 3 ++
.../tuweni/jsonrpc/methods/MethodsHandler.kt | 17 +++++-
.../tuweni/jsonrpc/methods/MethodsHandlerTest.kt | 61 ++++++++++++++++++++++
3 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/jsonrpc/build.gradle b/jsonrpc/build.gradle
index f23b45f..af246fc 100644
--- a/jsonrpc/build.gradle
+++ b/jsonrpc/build.gradle
@@ -17,6 +17,8 @@ dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation "com.google.guava:guava"
implementation "org.jetbrains.kotlin:kotlin-stdlib"
+ implementation 'io.opentelemetry:opentelemetry-api-metrics'
+ implementation 'io.opentelemetry:opentelemetry-sdk-metrics'
implementation 'io.vertx:vertx-core'
implementation 'io.vertx:vertx-web-client'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core'
@@ -32,6 +34,7 @@ dependencies {
testImplementation 'org.bouncycastle:bcprov-jdk15on'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.junit.jupiter:junit-jupiter-params'
+ testImplementation 'io.opentelemetry:opentelemetry-sdk'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
diff --git a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandler.kt b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandler.kt
index c9b419c..0f9e5c6 100644
--- a/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandler.kt
+++ b/jsonrpc/src/main/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandler.kt
@@ -16,6 +16,8 @@
*/
package org.apache.tuweni.jsonrpc.methods
+import io.opentelemetry.api.metrics.LongCounter
+import io.opentelemetry.api.metrics.common.Labels
import org.apache.tuweni.eth.JSONRPCRequest
import org.apache.tuweni.eth.JSONRPCResponse
import org.apache.tuweni.eth.methodNotFound
@@ -32,7 +34,20 @@ class MethodsRouter(val methodsMap: Map<String, (JSONRPCRequest) -> JSONRPCRespo
}
}
+class MeteredHandler(private val successCounter: LongCounter, private val failCounter: LongCounter, private val delegateHandler: (JSONRPCRequest) -> JSONRPCResponse) {
+
+ fun handleRequest(request: JSONRPCRequest): JSONRPCResponse {
+ val resp = delegateHandler(request)
+ val labels = Labels.of("method", request.method)
+ if (resp.error != null) {
+ failCounter.add(1, labels)
+ } else {
+ successCounter.add(1, labels)
+ }
+ return resp
+ }
+}
+
// TODO DelegateHandler - choose from a number of handlers to see which to delegate to.
-// TODO MeteredHandler - count number of responses, error responses
// TODO FilterHandler - filter incoming requests per allowlist
// TODO CachingHandler - cache some incoming requests
diff --git a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandlerTest.kt b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandlerTest.kt
index eede7ea..82fd680 100644
--- a/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandlerTest.kt
+++ b/jsonrpc/src/test/kotlin/org/apache/tuweni/jsonrpc/methods/MethodsHandlerTest.kt
@@ -16,6 +16,10 @@
*/
package org.apache.tuweni.jsonrpc.methods
+import io.opentelemetry.sdk.metrics.SdkMeterProvider
+import io.opentelemetry.sdk.metrics.export.IntervalMetricReader
+import io.opentelemetry.sdk.metrics.export.MetricProducer
+import io.opentelemetry.sdk.metrics.testing.InMemoryMetricExporter
import org.apache.tuweni.eth.JSONRPCRequest
import org.apache.tuweni.eth.JSONRPCResponse
import org.apache.tuweni.eth.methodNotFound
@@ -23,6 +27,7 @@ import org.apache.tuweni.junit.BouncyCastleExtension
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
+import java.util.Collections
@ExtendWith(BouncyCastleExtension::class)
class MethodsHandlerTest {
@@ -38,4 +43,60 @@ class MethodsHandlerTest {
val methodsRouter = MethodsRouter(mapOf(Pair("web3_sha3", ::sha3)))
assertEquals(JSONRPCResponse(1, result = "0xd4fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1"), methodsRouter.handleRequest(JSONRPCRequest(1, "web3_sha3", arrayOf("0xdeadbeef"))))
}
+
+ @Test
+ fun testCountSuccess() {
+ val exporter = InMemoryMetricExporter.create()
+ val meterSdk = SdkMeterProvider.builder().build()
+ val meter = meterSdk.get("handler")
+ val intervalMetricReader =
+ IntervalMetricReader.builder()
+ .setMetricExporter(exporter)
+ .setMetricProducers(Collections.singletonList(meterSdk) as Collection<MetricProducer>)
+ .setExportIntervalMillis(1000)
+ .build()
+ intervalMetricReader.start()
+ val successCounter = meter.longCounterBuilder("success").build()
+ val failCounter = meter.longCounterBuilder("fail").build()
+ val meteredHandler = MeteredHandler(successCounter, failCounter) {
+ JSONRPCResponse(1)
+ }
+ meteredHandler.handleRequest(JSONRPCRequest(1, "foo", emptyArray()))
+ Thread.sleep(1200)
+ var metricValue = 0L
+ for (metric in exporter.finishedMetricItems) {
+ if (metric.name == "success") {
+ metricValue = metric.longSumData.points.first().value
+ }
+ }
+ assertEquals(1L, metricValue)
+ }
+
+ @Test
+ fun testFailMeter() {
+ val exporter = InMemoryMetricExporter.create()
+ val meterSdk = SdkMeterProvider.builder().build()
+ val meter = meterSdk.get("handler")
+ val intervalMetricReader =
+ IntervalMetricReader.builder()
+ .setMetricExporter(exporter)
+ .setMetricProducers(Collections.singletonList(meterSdk) as Collection<MetricProducer>)
+ .setExportIntervalMillis(1000)
+ .build()
+ intervalMetricReader.start()
+ val successCounter = meter.longCounterBuilder("success").build()
+ val failCounter = meter.longCounterBuilder("fail").build()
+ val meteredHandler = MeteredHandler(successCounter, failCounter) {
+ JSONRPCResponse(1, error = "foo")
+ }
+ meteredHandler.handleRequest(JSONRPCRequest(1, "foo", emptyArray()))
+ Thread.sleep(1200)
+ var metricValue = 0L
+ for (metric in exporter.finishedMetricItems) {
+ if (metric.name == "fail") {
+ metricValue = metric.longSumData.points.first().value
+ }
+ }
+ assertEquals(1L, metricValue)
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tuweni.apache.org
For additional commands, e-mail: commits-help@tuweni.apache.org