Skip to content

Commit

Permalink
initial sample
Browse files Browse the repository at this point in the history
  • Loading branch information
atoulme committed Aug 12, 2021
1 parent 7086a70 commit 2365caa
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 5 deletions.
65 changes: 65 additions & 0 deletions examples/jsonrpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<!--
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.
-->
# JSON-RPC proxy

The JSON-RPC proxy allows you to cache requests to a JSON-RPC endpoint.

This example showcases how to use the proxy with a public service.

## Requirements

This example requires Docker, Docker Compose 1.25, Java 11 and Gradle > 6.

## Steps

### Check out this repository

`$> git clone https://github.com/apache/incubator-tuweni`

### Build the image

You need to install the Gradle wrapper the first time you make a checkout:

`$> gradle setup`

You can now run gradle to build the docker image:

`$> ./gradlew dist::buildBinImage`

The build should end with similar lines:
```bash
---> be57b46c612c
Successfully built be57b46c612c
Successfully tagged apache-tuweni/tuweni:2.1.0-SNAPSHOT
Created image with ID 'be57b46c612c'.

BUILD SUCCESSFUL in 1m 13s
256 actionable tasks: 2 executed, 254 up-to-date
```

### Run the example

Make sure the image you just tagged matches the one in the `docker_compose.yml` file.

Run Docker:

```bash
docker-compose up
```



25 changes: 25 additions & 0 deletions examples/jsonrpc/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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.
endpointUrl="https://rpc.xdaichain.com/" # service URL
port=8545
networkInterface="0.0.0.0"
cacheEnabled=true
cachedMethods=[""] # All methods are cached
cacheStoragePath="/var/jsonrpccache" # Cache location
allowedMethods=[""] # All methods are enabled
metricsGrpcPushEnabled=true
metricsPrometheusEnabled=false
metricsGrpcTimeout=2000
metricsGrpcEndpoint="http://otelcollector:4317"
45 changes: 45 additions & 0 deletions examples/jsonrpc/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 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.
version: "3"
services:
jsonrpc:
container_name: jsonrpc
image: apache-tuweni/tuweni:2.1.0-SNAPSHOT
volumes:
- ./config.toml:/etc/config.toml
- ./logback.xml:/usr/tuweni/bin/logback.xml
entrypoint: /usr/tuweni/bin/jsonrpc
command: /etc/config.toml
environment:
- JAVA_OPTS="-Dlogback.configurationFile=/usr/tuweni/bin/logback.xml"
ports:
- 8545:8545
otelcollector:
container_name: otelcollector
image: otel/opentelemetry-collector-contrib:0.31.0
command: ["--config=/etc/otel-collector-config.yml", "--log-level=DEBUG"]
volumes:
- ./otel-collector-config.yml:/etc/otel-collector-config.yml
metricsviewer:
image: docker.io/tmio/metrics-ui
container_name: metricsviewer
ports:
- 8080:8080
# Zipkin
zipkin:
container_name: zipkin
image: openzipkin/zipkin
ports:
- 9411:9411
30 changes: 30 additions & 0 deletions examples/jsonrpc/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
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.
-->
<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="io.opentelemetry" level="trace" additivity="true">
<appender-ref ref="STDOUT" />
</logger>

<root level="trace">
<appender-ref ref="STDOUT" />
</root>
</configuration>
53 changes: 53 additions & 0 deletions examples/jsonrpc/otel-collector-config.yml
Original file line number Diff line number Diff line change
@@ -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.

receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317

exporters:
otlp:
endpoint: "metricsviewer:4317"
insecure: true
zipkin:
endpoint: "http://zipkin:9411/api/v2/spans"
logging:
loglevel: debug
sampling_initial: 5
sampling_thereafter: 200
processors:
batch:

extensions:
health_check:
endpoint: 0.0.0.0:13133
pprof:
endpoint: :1888
zpages:
endpoint: :55679

service:
extensions: [pprof, zpages, health_check]
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlp, logging]
traces:
receivers: [ otlp ]
processors: [ batch ]
exporters: [ zipkin, logging ]
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ object JSONRPCApp {
port = config.metricsPort(),
networkInterface = config.metricsNetworkInterface(),
enableGrpcPush = config.metricsGrpcPushEnabled(),
enablePrometheus = config.metricsPrometheusEnabled()
enablePrometheus = config.metricsPrometheusEnabled(),
grpcEndpoint = config.metricsGrpcEndpoint(),
grpcTimeout = config.metricsGrpcTimeout(),
)
val vertx = Vertx.vertx(VertxOptions().setTracingOptions(OpenTelemetryOptions(metricsService.openTelemetry)))
val app = JSONRPCApplication(vertx, config, metricsService)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class JSONRPCConfig(val filePath: Path) {
.addBoolean("cacheEnabled", false, "Enable caching", null)
.addString("cacheStoragePath", "", "Location of cache storage", null)
.addInteger("maxConcurrentRequests", 30, "Maximum concurrent requests", null)
.addString("metricsGrpcEndpoint", "http://localhost:4317", "Metrics GRPC push endpoint", null)
.addLong("metricsGrpcTimeout", 2000, "Metrics GRPC push timeout", null)
.toSchema()
}

Expand Down Expand Up @@ -87,4 +89,6 @@ class JSONRPCConfig(val filePath: Path) {
fun cacheEnabled() = config.getBoolean("cacheEnabled")
fun cacheStoragePath() = config.getString("cacheStoragePath")
fun maxConcurrentRequests() = config.getInteger("maxConcurrentRequests")
fun metricsGrpcEndpoint() = config.getString("metricsGrpcEndpoint")
fun metricsGrpcTimeout() = config.getLong("metricsGrpcTimeout")
}
2 changes: 1 addition & 1 deletion jsonrpc-app/src/main/resources/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</encoder>
</appender>

<root level="trace">
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>
1 change: 1 addition & 0 deletions metrics/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dependencies {
implementation 'io.prometheus:simpleclient_httpserver'

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core'
implementation 'org.slf4j:slf4j-api'

testImplementation project(':junit')
testImplementation 'org.bouncycastle:bcprov-jdk15on'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ import io.opentelemetry.sdk.trace.export.BatchSpanProcessor
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes
import io.prometheus.client.CollectorRegistry
import io.prometheus.client.exporter.HTTPServer
import org.slf4j.LoggerFactory
import java.net.InetSocketAddress
import java.util.concurrent.TimeUnit

class MetricsService(
jobName: String,
Expand All @@ -38,16 +40,23 @@ class MetricsService(
networkInterface: String = "0.0.0.0",
enablePrometheus: Boolean = true,
enableGrpcPush: Boolean = true,
grpcEndpoint: String = "localhost:4317",
grpcTimeout: Long = 2000,
) {

companion object {
private val logger = LoggerFactory.getLogger(MetricsService::class.java)
}

private val server: HTTPServer?
val meterSdkProvider: SdkMeterProvider
val openTelemetry: OpenTelemetrySdk
private val spanProcessor: BatchSpanProcessor
private val periodicReader: IntervalMetricReader?

init {
val exporter = OtlpGrpcMetricExporter.getDefault()
val exporter = OtlpGrpcMetricExporter.builder().setEndpoint(grpcEndpoint).setTimeout(grpcTimeout, TimeUnit.MILLISECONDS).build()
logger.info("Starting metrics service")
val resource = Resource.getDefault()
.merge(
Resource.create(
Expand All @@ -56,21 +65,25 @@ class MetricsService(
)
meterSdkProvider = SdkMeterProvider.builder().setResource(resource).build()
if (enableGrpcPush) {
logger.info("Starting GRPC push metrics service")
val builder = IntervalMetricReader.builder()
.setExportIntervalMillis(reportingIntervalMillis)
.setMetricProducers(setOf(meterSdkProvider))
.setMetricExporter(exporter)
periodicReader = builder.buildAndStart()
periodicReader.start()
} else {
periodicReader = null
}
spanProcessor = BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder().build()).build()
spanProcessor = BatchSpanProcessor.builder(
OtlpGrpcSpanExporter.builder().setEndpoint(grpcEndpoint)
.setTimeout(grpcTimeout, TimeUnit.MILLISECONDS).build()
).build()
openTelemetry = OpenTelemetrySdk.builder()
.setTracerProvider(SdkTracerProvider.builder().addSpanProcessor(spanProcessor).build())
.build()

if (enablePrometheus) {
logger.info("Starting Prometheus metrics service")
val prometheusRegistry = CollectorRegistry(true)
PrometheusCollector.builder()
.setMetricProducer(meterSdkProvider)
Expand Down

0 comments on commit 2365caa

Please sign in to comment.