From b6737dc3408866d8ab9f9683d8d649121da37dfb Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Tue, 27 Aug 2024 14:33:36 -0600 Subject: [PATCH 01/12] wip: change to enums Signed-off-by: Matt Peterson --- .../ConsumerStreamResponseObserver.java | 6 ++++ .../block/server/metrics/CounterMetrics.java | 29 +++++++++++++++++++ .../block/server/metrics/MetricsService.java | 3 ++ .../server/metrics/MetricsServiceImpl.java | 24 +++++++++++++-- 4 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java diff --git a/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java b/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java index 3860bcde..119ef0d5 100644 --- a/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java +++ b/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java @@ -24,6 +24,8 @@ import com.hedera.block.server.config.BlockNodeContext; import com.hedera.block.server.data.ObjectEvent; import com.hedera.block.server.mediator.SubscriptionHandler; +import com.hedera.block.server.metrics.CounterMetrics; +import com.hedera.block.server.metrics.MetricsService; import com.hedera.hapi.block.SubscribeStreamResponse; import com.hedera.hapi.block.stream.BlockItem; import com.hedera.pbj.runtime.OneOf; @@ -45,6 +47,7 @@ public class ConsumerStreamResponseObserver private final Logger LOGGER = System.getLogger(getClass().getName()); + private final MetricsService metricsService; private final StreamObserver subscribeStreamResponseObserver; private final SubscriptionHandler> subscriptionHandler; @@ -98,6 +101,7 @@ public ConsumerStreamResponseObserver( .getConfigData(ConsumerConfig.class) .timeoutThresholdMillis(); this.subscriptionHandler = subscriptionHandler; + this.metricsService = context.metricsService(); // The ServerCallStreamObserver can be configured with Runnable handlers to // be executed when a downstream consumer closes the connection. The handlers @@ -163,6 +167,8 @@ public void onEvent( // Refresh the producer liveness and pass the BlockItem to the downstream observer. producerLivenessMillis = currentMillis; + metricsService.getCounter(CounterMetrics.LIVE_BLOCK_ITEMS_CONSUMED).increment(); + final SubscribeStreamResponse subscribeStreamResponse = event.get(); final ResponseSender responseSender = getResponseSender(subscribeStreamResponse); responseSender.send(subscribeStreamResponse); diff --git a/server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java b/server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java new file mode 100644 index 00000000..52a265f4 --- /dev/null +++ b/server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed 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 com.hedera.block.server.metrics; + +public enum CounterMetrics { + LIVE_BLOCK_ITEMS, + BLOCKS_PERSISTED, + LIVE_BLOCK_ITEMS_CONSUMED, + SINGLE_BLOCKS_RETRIEVED; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } +} diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java index 6269a74e..eccb93d9 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java @@ -22,6 +22,9 @@ /** Use member variables of this class to update metric data for the Hedera Block Node. */ public interface MetricsService { + + Counter getCounter(CounterMetrics key); + /** * Update the counter of live block items transiting via the live stream. * diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java index a05052df..65a229b8 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java @@ -20,6 +20,7 @@ import com.swirlds.metrics.api.LongGauge; import com.swirlds.metrics.api.Metrics; import edu.umd.cs.findbugs.annotations.NonNull; +import java.util.EnumMap; import javax.inject.Inject; /** @@ -33,8 +34,14 @@ public class MetricsServiceImpl implements MetricsService { private static final String CATEGORY = "hedera_block_node"; // Live BlockItem Counter - private static final Counter.Config LIVE_BLOCK_ITEM_COUNTER = - new Counter.Config(CATEGORY, "live_block_items").withDescription("Live BlockItems"); + private static final Counter.Config liveBlockItemCounter = + new Counter.Config(CATEGORY, CounterMetrics.LIVE_BLOCK_ITEMS.toString()) + .withDescription("Live BlockItems"); + + // Live BlockItem Consumed Counter + private static final Counter.Config liveBlockItemsConsumed = + new Counter.Config(CATEGORY, CounterMetrics.LIVE_BLOCK_ITEMS_CONSUMED.toString()) + .withDescription("Live Block Items Consumed"); // Block Persistence Counter private static final Counter.Config BLOCK_PERSISTENCE_COUNTER = @@ -64,6 +71,12 @@ public final Counter liveBlockItems() { return liveBlockItems; } + @Override + @NonNull + public final Counter getCounter(CounterMetrics key) { + return counters.get(key); + } + /** Update the counter of blocks persisted to storage. */ @Override @NonNull @@ -85,6 +98,8 @@ public final LongGauge subscribers() { return subscribers; } + private final EnumMap counters = new EnumMap<>(CounterMetrics.class); + /** * Create singleton instance of metrics service to be used throughout the application. * @@ -92,7 +107,10 @@ public final LongGauge subscribers() { */ @Inject public MetricsServiceImpl(@NonNull final Metrics metrics) { - this.liveBlockItems = metrics.getOrCreate(LIVE_BLOCK_ITEM_COUNTER); + this.counters.put( + CounterMetrics.LIVE_BLOCK_ITEMS, metrics.getOrCreate(liveBlockItemsConsumed)); + + this.liveBlockItems = metrics.getOrCreate(liveBlockItemCounter); this.blocksPersisted = metrics.getOrCreate(BLOCK_PERSISTENCE_COUNTER); this.singleBlocksRetrieved = metrics.getOrCreate(SINGLE_BLOCK_RETRIEVED_COUNTER); this.subscribers = metrics.getOrCreate(SUBSCRIBER_GAUGE); From f5b85d80e8b20d3566615027aa48ade7c721b7fb Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Wed, 28 Aug 2024 13:05:26 -0600 Subject: [PATCH 02/12] wip: refactoring Signed-off-by: Matt Peterson --- .../metrics/dashboards/block-node-server.json | 174 +++++++++++++++++- .../block/server/BlockStreamService.java | 6 +- .../ConsumerStreamResponseObserver.java | 4 +- .../mediator/LiveStreamMediatorImpl.java | 19 +- .../server/metrics/BlockNodeMetricNames.java | 78 ++++++++ .../block/server/metrics/CounterMetrics.java | 20 +- .../block/server/metrics/GaugeMetrics.java | 28 +++ .../block/server/metrics/MetricsService.java | 41 +---- .../server/metrics/MetricsServiceImpl.java | 108 +++++------ .../storage/write/BlockAsDirWriter.java | 8 +- .../BlockStreamServiceIntegrationTest.java | 3 +- .../mediator/LiveStreamMediatorImplTest.java | 15 +- .../server/metrics/MetricsServiceTest.java | 126 +++++++------ .../ProducerBlockItemObserverTest.java | 3 +- 14 files changed, 430 insertions(+), 203 deletions(-) create mode 100644 server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java create mode 100644 server/src/main/java/com/hedera/block/server/metrics/GaugeMetrics.java diff --git a/server/docker/metrics/dashboards/block-node-server.json b/server/docker/metrics/dashboards/block-node-server.json index f32013ac..9b662595 100644 --- a/server/docker/metrics/dashboards/block-node-server.json +++ b/server/docker/metrics/dashboards/block-node-server.json @@ -80,7 +80,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.1.3", + "pluginVersion": "11.1.4", "targets": [ { "datasource": { @@ -223,11 +223,171 @@ "overrides": [] }, "gridPos": { - "h": 7, + "h": 6, "w": 6, "x": 0, "y": 8 }, + "id": 11, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.1.4", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "hedera_block_node_live_block_items_consumed_total", + "instant": false, + "legendFormat": "BlockItems Consumed", + "range": true, + "refId": "A" + } + ], + "title": "Live Block Items Consumed Counter", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 18, + "x": 6, + "y": 8 + }, + "id": 10, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "rate( hedera_block_node_live_block_items_consumed_total [$__rate_interval])", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Live Block Items Consumed", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 14 + }, "id": 6, "options": { "colorMode": "value", @@ -246,7 +406,7 @@ "textMode": "auto", "wideLayout": true }, - "pluginVersion": "11.1.3", + "pluginVersion": "11.1.4", "targets": [ { "datasource": { @@ -332,7 +492,7 @@ "h": 7, "w": 18, "x": 6, - "y": 8 + "y": 14 }, "id": 8, "options": { @@ -403,7 +563,7 @@ "h": 9, "w": 9, "x": 0, - "y": 15 + "y": 21 }, "id": 4, "options": { @@ -421,7 +581,7 @@ "showThresholdMarkers": true, "sizing": "auto" }, - "pluginVersion": "11.1.3", + "pluginVersion": "11.1.4", "targets": [ { "datasource": { @@ -503,7 +663,7 @@ "h": 9, "w": 15, "x": 9, - "y": 15 + "y": 21 }, "id": 5, "options": { diff --git a/server/src/main/java/com/hedera/block/server/BlockStreamService.java b/server/src/main/java/com/hedera/block/server/BlockStreamService.java index 8f16dd8b..d5691a23 100644 --- a/server/src/main/java/com/hedera/block/server/BlockStreamService.java +++ b/server/src/main/java/com/hedera/block/server/BlockStreamService.java @@ -22,6 +22,7 @@ import static com.hedera.block.server.Constants.SINGLE_BLOCK_METHOD_NAME; import static com.hedera.block.server.Translator.fromPbj; import static com.hedera.block.server.Translator.toPbj; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.SingleBlocksRetrieved; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.ERROR; @@ -65,6 +66,7 @@ public class BlockStreamService implements GrpcService { private final ServiceStatus serviceStatus; private final BlockReader blockReader; private final BlockNodeContext blockNodeContext; + private final MetricsService metricsService; /** * Constructor for the BlockStreamService class. It initializes the BlockStreamService with the @@ -89,6 +91,7 @@ public class BlockStreamService implements GrpcService { this.blockReader = blockReader; this.serviceStatus = serviceStatus; this.blockNodeContext = blockNodeContext; + this.metricsService = blockNodeContext.metricsService(); } /** @@ -201,8 +204,7 @@ private void singleBlock( singleBlockResponseStreamObserver.onNext( fromPbjSingleBlockSuccessResponse(blockOpt.get())); - final MetricsService metricsService = blockNodeContext.metricsService(); - metricsService.singleBlocksRetrieved().increment(); + metricsService.increment(SingleBlocksRetrieved); } else { LOGGER.log(DEBUG, "Block number {0} not found", blockNumber); singleBlockResponseStreamObserver.onNext(buildSingleBlockNotFoundResponse()); diff --git a/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java b/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java index 119ef0d5..6457f3f9 100644 --- a/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java +++ b/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java @@ -17,6 +17,7 @@ package com.hedera.block.server.consumer; import static com.hedera.block.server.Translator.fromPbj; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItemsConsumed; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.ERROR; @@ -24,7 +25,6 @@ import com.hedera.block.server.config.BlockNodeContext; import com.hedera.block.server.data.ObjectEvent; import com.hedera.block.server.mediator.SubscriptionHandler; -import com.hedera.block.server.metrics.CounterMetrics; import com.hedera.block.server.metrics.MetricsService; import com.hedera.hapi.block.SubscribeStreamResponse; import com.hedera.hapi.block.stream.BlockItem; @@ -167,7 +167,7 @@ public void onEvent( // Refresh the producer liveness and pass the BlockItem to the downstream observer. producerLivenessMillis = currentMillis; - metricsService.getCounter(CounterMetrics.LIVE_BLOCK_ITEMS_CONSUMED).increment(); + metricsService.increment(LiveBlockItemsConsumed); final SubscribeStreamResponse subscribeStreamResponse = event.get(); final ResponseSender responseSender = getResponseSender(subscribeStreamResponse); diff --git a/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java b/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java index 7feee6c3..8b30da6b 100644 --- a/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java +++ b/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java @@ -16,6 +16,8 @@ package com.hedera.block.server.mediator; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Gauge.Subscribers; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.ERROR; @@ -34,7 +36,6 @@ import com.lmax.disruptor.RingBuffer; import com.lmax.disruptor.dsl.Disruptor; import com.lmax.disruptor.util.DaemonThreadFactory; -import com.swirlds.metrics.api.LongGauge; import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; import java.util.Map; @@ -62,7 +63,6 @@ class LiveStreamMediatorImpl private final BlockWriter blockWriter; private final ServiceStatus serviceStatus; - private final BlockNodeContext blockNodeContext; private final MetricsService metricsService; /** @@ -97,7 +97,6 @@ class LiveStreamMediatorImpl this.ringBuffer = disruptor.start(); this.executor = Executors.newCachedThreadPool(DaemonThreadFactory.INSTANCE); this.serviceStatus = serviceStatus; - this.blockNodeContext = blockNodeContext; this.metricsService = blockNodeContext.metricsService(); } @@ -121,7 +120,7 @@ public void publish(@NonNull final BlockItem blockItem) throws IOException { ringBuffer.publishEvent((event, sequence) -> event.set(subscribeStreamResponse)); // Increment the block item counter - metricsService.liveBlockItems().increment(); + metricsService.increment(LiveBlockItems); try { // Persist the BlockItem @@ -169,7 +168,8 @@ public void subscribe( // Keep track of the subscriber subscribers.put(handler, batchEventProcessor); - updateSubscriberMetrics(); + // update the subscriber metrics + metricsService.set(Subscribers, subscribers.size()); } @Override @@ -190,7 +190,8 @@ public void unsubscribe( ringBuffer.removeGatingSequence(batchEventProcessor.getSequence()); } - updateSubscriberMetrics(); + // update the subscriber metrics + metricsService.set(Subscribers, subscribers.size()); } @Override @@ -208,10 +209,4 @@ private static SubscribeStreamResponse buildEndStreamResponse() { .status(SubscribeStreamResponseCode.READ_STREAM_SUCCESS) .build(); } - - private void updateSubscriberMetrics() { - @NonNull final MetricsService metricsService = blockNodeContext.metricsService(); - @NonNull final LongGauge longGauge = metricsService.subscribers(); - longGauge.set(subscribers.size()); - } } diff --git a/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java b/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java new file mode 100644 index 00000000..a6901fcc --- /dev/null +++ b/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed 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 com.hedera.block.server.metrics; + +import edu.umd.cs.findbugs.annotations.NonNull; + +public class BlockNodeMetricNames { + public enum Counter implements MetricMetadata { + LiveBlockItems("live_block_items", "Live BlockItems"), + BlocksPersisted("blocks_persisted", "Blocks Persisted"), + LiveBlockItemsConsumed("live_block_items_consumed", "Live Block Items Consumed"), + SingleBlocksRetrieved("single_blocks_retrieved", "Single Blocks Retrieved"); + + private final String grafanaLabel; + private final String description; + + Counter(String grafanaLabel, String description) { + this.grafanaLabel = grafanaLabel; + this.description = description; + } + + @Override + @NonNull + public String grafanaLabel() { + return grafanaLabel; + } + + @Override + @NonNull + public String description() { + return description; + } + } + + public enum Gauge implements MetricMetadata { + Subscribers("subscribers", "Subscribers"); + + private final String grafanaLabel; + private final String description; + + Gauge(String grafanaLabel, String description) { + this.grafanaLabel = grafanaLabel; + this.description = description; + } + + @Override + @NonNull + public String grafanaLabel() { + return grafanaLabel; + } + + @Override + @NonNull + public String description() { + return description; + } + } + + public interface MetricMetadata { + String grafanaLabel(); + + String description(); + } +} diff --git a/server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java b/server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java index 52a265f4..406f022a 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java +++ b/server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java @@ -16,14 +16,16 @@ package com.hedera.block.server.metrics; -public enum CounterMetrics { - LIVE_BLOCK_ITEMS, - BLOCKS_PERSISTED, - LIVE_BLOCK_ITEMS_CONSUMED, - SINGLE_BLOCKS_RETRIEVED; +import edu.umd.cs.findbugs.annotations.NonNull; - @Override - public String toString() { - return super.toString().toLowerCase(); - } +public interface CounterMetrics { + void increment(@NonNull BlockNodeMetricNames.Counter key); + + long count(@NonNull BlockNodeMetricNames.Counter key); + + @NonNull + String name(@NonNull BlockNodeMetricNames.Counter key); + + @NonNull + String description(@NonNull BlockNodeMetricNames.Counter key); } diff --git a/server/src/main/java/com/hedera/block/server/metrics/GaugeMetrics.java b/server/src/main/java/com/hedera/block/server/metrics/GaugeMetrics.java new file mode 100644 index 00000000..896b5bf7 --- /dev/null +++ b/server/src/main/java/com/hedera/block/server/metrics/GaugeMetrics.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed 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 com.hedera.block.server.metrics; + +import edu.umd.cs.findbugs.annotations.NonNull; + +public interface GaugeMetrics { + void set(@NonNull BlockNodeMetricNames.Gauge key, long value); + + long count(@NonNull BlockNodeMetricNames.Gauge key); + + @NonNull + String name(@NonNull BlockNodeMetricNames.Gauge key); +} diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java index eccb93d9..71c4fc88 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java @@ -16,44 +16,5 @@ package com.hedera.block.server.metrics; -import com.swirlds.metrics.api.Counter; -import com.swirlds.metrics.api.LongGauge; -import edu.umd.cs.findbugs.annotations.NonNull; - /** Use member variables of this class to update metric data for the Hedera Block Node. */ -public interface MetricsService { - - Counter getCounter(CounterMetrics key); - - /** - * Update the counter of live block items transiting via the live stream. - * - * @return use this metric to increase the counter of block items received - */ - @NonNull - Counter liveBlockItems(); - - /** - * Update the counter of blocks persisted to storage. - * - * @return use this counter to increase the amount of blocks persisted to disk - */ - @NonNull - Counter blocksPersisted(); - - /** - * Update the counter of single blocks retrieved from storage. - * - * @return use this metric to increase the counter of single blocks retrieved - */ - @NonNull - Counter singleBlocksRetrieved(); - - /** - * Update the gauge of subscribers currently consuming to the live stream. - * - * @return Use this to increase or decrease the amount of current subscribers to the live stream - */ - @NonNull - LongGauge subscribers(); -} +public interface MetricsService extends CounterMetrics, GaugeMetrics {} diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java index 65a229b8..680aa070 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java @@ -33,86 +33,72 @@ public class MetricsServiceImpl implements MetricsService { private static final String CATEGORY = "hedera_block_node"; - // Live BlockItem Counter - private static final Counter.Config liveBlockItemCounter = - new Counter.Config(CATEGORY, CounterMetrics.LIVE_BLOCK_ITEMS.toString()) - .withDescription("Live BlockItems"); + private final EnumMap counters = + new EnumMap<>(BlockNodeMetricNames.Counter.class); + private final EnumMap gauges = + new EnumMap<>(BlockNodeMetricNames.Gauge.class); - // Live BlockItem Consumed Counter - private static final Counter.Config liveBlockItemsConsumed = - new Counter.Config(CATEGORY, CounterMetrics.LIVE_BLOCK_ITEMS_CONSUMED.toString()) - .withDescription("Live Block Items Consumed"); - - // Block Persistence Counter - private static final Counter.Config BLOCK_PERSISTENCE_COUNTER = - new Counter.Config(CATEGORY, "blocks_persisted").withDescription("Blocks Persisted"); - - // Subscriber Gauge - private static final LongGauge.Config SUBSCRIBER_GAUGE = - new LongGauge.Config(CATEGORY, "subscribers").withDescription("Subscribers"); - - // Single Block Retrieved Counter - private static final Counter.Config SINGLE_BLOCK_RETRIEVED_COUNTER = - new Counter.Config(CATEGORY, "single_blocks_retrieved") - .withDescription("Single Blocks Retrieved"); - - private final Counter liveBlockItems; - - private final Counter blocksPersisted; - - private final Counter singleBlocksRetrieved; - - private final LongGauge subscribers; + /** + * Create singleton instance of metrics service to be used throughout the application. + * + * @param metrics the metrics instance + */ + @Inject + public MetricsServiceImpl(@NonNull final Metrics metrics) { + // Initialize the counters + for (BlockNodeMetricNames.Counter counter : BlockNodeMetricNames.Counter.values()) { + counters.put( + counter, + metrics.getOrCreate( + new Counter.Config(CATEGORY, counter.grafanaLabel()) + .withDescription(counter.description()))); + } + + // Initialize the gauges + for (BlockNodeMetricNames.Gauge gauge : BlockNodeMetricNames.Gauge.values()) { + gauges.put( + gauge, + metrics.getOrCreate( + new LongGauge.Config(CATEGORY, gauge.grafanaLabel()) + .withDescription(gauge.description()))); + } + } - /** Update the counter of live block items transiting via the live stream. */ @Override - @NonNull - public final Counter liveBlockItems() { - return liveBlockItems; + public void increment(@NonNull BlockNodeMetricNames.Counter key) { + counters.get(key).increment(); } @Override - @NonNull - public final Counter getCounter(CounterMetrics key) { - return counters.get(key); + public long count(@NonNull BlockNodeMetricNames.Counter key) { + return counters.get(key).get(); } - /** Update the counter of blocks persisted to storage. */ @Override @NonNull - public final Counter blocksPersisted() { - return blocksPersisted; + public String name(@NonNull BlockNodeMetricNames.Counter key) { + return counters.get(key).getName(); } - /** Update the counter of single blocks retrieved from storage. */ @Override @NonNull - public final Counter singleBlocksRetrieved() { - return singleBlocksRetrieved; + public String description(@NonNull BlockNodeMetricNames.Counter key) { + return counters.get(key).getDescription(); } - /** Update the gauge of subscribers currently consuming to the live stream. */ @Override - @NonNull - public final LongGauge subscribers() { - return subscribers; + public void set(@NonNull BlockNodeMetricNames.Gauge key, long value) { + gauges.get(key).set(value); } - private final EnumMap counters = new EnumMap<>(CounterMetrics.class); - - /** - * Create singleton instance of metrics service to be used throughout the application. - * - * @param metrics the metrics instance - */ - @Inject - public MetricsServiceImpl(@NonNull final Metrics metrics) { - this.counters.put( - CounterMetrics.LIVE_BLOCK_ITEMS, metrics.getOrCreate(liveBlockItemsConsumed)); + @Override + public long count(@NonNull BlockNodeMetricNames.Gauge key) { + return gauges.get(key).get(); + } - this.liveBlockItems = metrics.getOrCreate(liveBlockItemCounter); - this.blocksPersisted = metrics.getOrCreate(BLOCK_PERSISTENCE_COUNTER); - this.singleBlocksRetrieved = metrics.getOrCreate(SINGLE_BLOCK_RETRIEVED_COUNTER); - this.subscribers = metrics.getOrCreate(SUBSCRIBER_GAUGE); + @Override + @NonNull + public String name(@NonNull BlockNodeMetricNames.Gauge key) { + return gauges.get(key).getName(); } } diff --git a/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java b/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java index 91d7580a..6418409b 100644 --- a/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java +++ b/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java @@ -17,6 +17,7 @@ package com.hedera.block.server.persistence.storage.write; import static com.hedera.block.server.Constants.BLOCK_FILE_EXTENSION; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.BlocksPersisted; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.ERROR; @@ -55,7 +56,7 @@ class BlockAsDirWriter implements BlockWriter { private Path currentBlockDir; private final FileAttribute> filePerms; private final BlockRemover blockRemover; - private final BlockNodeContext blockNodeContext; + private final MetricsService metricsService; /** * Use the corresponding builder to construct a new BlockAsDirWriter with the given parameters. @@ -86,7 +87,7 @@ class BlockAsDirWriter implements BlockWriter { // Initialize the block node root directory if it does not exist FileUtils.createPathIfNotExists(blockNodeRootPath, INFO, filePerms); - this.blockNodeContext = blockNodeContext; + this.metricsService = blockNodeContext.metricsService(); } /** @@ -162,8 +163,7 @@ private void resetState(@NonNull final BlockItem blockItem) throws IOException { blockNodeFileNameIndex = 0; // Increment the block counter - final MetricsService metricsService = blockNodeContext.metricsService(); - metricsService.blocksPersisted().increment(); + metricsService.increment(BlocksPersisted); } private void repairPermissions(@NonNull final Path path) throws IOException { diff --git a/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java b/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java index 6f668682..2ccd9c90 100644 --- a/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java @@ -17,6 +17,7 @@ package com.hedera.block.server; import static com.hedera.block.server.Translator.fromPbj; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; import static com.hedera.block.server.producer.Util.getFakeHash; import static com.hedera.block.server.util.PersistTestUtils.generateBlockItems; import static java.lang.System.Logger; @@ -230,7 +231,7 @@ public void testSubscribeBlockStream() throws IOException { streamObserver.onNext(fromPbj(publishStreamRequest)); // Verify the counter was incremented - assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); + assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); verify(blockWriter, timeout(testTimeout).times(1)).write(blockItems.getFirst()); diff --git a/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java b/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java index 06b63ea7..4420c25f 100644 --- a/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java +++ b/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java @@ -17,6 +17,7 @@ package com.hedera.block.server.mediator; import static com.hedera.block.server.Translator.fromPbj; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; import static com.hedera.block.server.util.PersistTestUtils.generateBlockItems; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -131,7 +132,7 @@ public void testUnsubscribeEach() throws InterruptedException, IOException { "Expected the mediator to have unsubscribed observer3"); // Confirm the counter was never incremented - assertEquals(0, blockNodeContext.metricsService().liveBlockItems().get()); + assertEquals(0, blockNodeContext.metricsService().count(LiveBlockItems)); } @Test @@ -148,7 +149,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) streamMediator.publish(blockItem); // Verify the counter was incremented - assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); + assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); // Confirm the BlockStorage write method was // called despite the absence of subscribers @@ -201,7 +202,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) // Acting as a producer, notify the mediator of a new block streamMediator.publish(blockItem); - assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); + assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); // Confirm each subscriber was notified of the new block verify(streamObserver1, timeout(testTimeout).times(1)) @@ -248,7 +249,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) streamMediator.unsubscribe(concreteObserver3); // Confirm the counter was never incremented - assertEquals(0, blockNodeContext.metricsService().liveBlockItems().get()); + assertEquals(0, blockNodeContext.metricsService().count(LiveBlockItems)); } @Test @@ -277,7 +278,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) testConsumerBlockItemObserver.getOnCancel().run(); // Verify the block item incremented the counter - assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); + assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); // Verify the event made it to the consumer verify(serverCallStreamObserver, timeout(testTimeout).times(1)).setOnCancelHandler(any()); @@ -313,7 +314,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) testConsumerBlockItemObserver.getOnClose().run(); // Verify the block item incremented the counter - assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); + assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); // Verify the event made it to the consumer verify(serverCallStreamObserver, timeout(testTimeout).times(1)).setOnCancelHandler(any()); @@ -348,7 +349,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) streamMediator.publish(secondBlockItem); // Confirm the counter was incremented only once - assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); + assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); // Confirm the BlockPersistenceHandler write method was only called // once despite the second block being published. diff --git a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java index d198d293..7e44b1b2 100644 --- a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java +++ b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java @@ -16,69 +16,81 @@ package com.hedera.block.server.metrics; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; +import static org.junit.jupiter.api.Assertions.assertEquals; -import com.swirlds.metrics.api.Counter; -import com.swirlds.metrics.api.LongGauge; +import com.hedera.block.server.config.BlockNodeContext; +import com.hedera.block.server.util.TestConfigUtil; +import com.swirlds.config.api.Configuration; import com.swirlds.metrics.api.Metrics; +import java.io.IOException; import org.junit.jupiter.api.Test; -class MetricsServiceTest { +public class MetricsServiceTest { @Test - void MetricsService_initializesLiveBlockItemsCounter() { - Metrics metrics = mock(Metrics.class); - Counter liveBlockItems = mock(Counter.class); - when(metrics.getOrCreate(any(Counter.Config.class))).thenReturn(liveBlockItems); - - MetricsService service = new MetricsServiceImpl(metrics); - - assertEquals(liveBlockItems, service.liveBlockItems()); - - service.liveBlockItems().increment(); - verify(liveBlockItems, times(1)).increment(); - } - - @Test - void MetricsService_initializesBlocksPersistedCounter() { - Metrics metrics = mock(Metrics.class); - Counter blocksPersisted = mock(Counter.class); - when(metrics.getOrCreate(any(Counter.Config.class))).thenReturn(blocksPersisted); - - MetricsService service = new MetricsServiceImpl(metrics); - - assertEquals(blocksPersisted, service.blocksPersisted()); - - service.blocksPersisted().increment(); - verify(blocksPersisted, times(1)).increment(); - } - - @Test - void MetricsService_initializesSingleBlocksRetrievedCounter() { - Metrics metrics = mock(Metrics.class); - Counter singleBlocksRetrieved = mock(Counter.class); - when(metrics.getOrCreate(any(Counter.Config.class))).thenReturn(singleBlocksRetrieved); - - MetricsService service = new MetricsServiceImpl(metrics); - - assertEquals(singleBlocksRetrieved, service.singleBlocksRetrieved()); - - service.singleBlocksRetrieved().increment(); - verify(singleBlocksRetrieved, times(1)).increment(); + void MetricsService_initializesLiveBlockItemsCounter() throws IOException { + + final BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); + final Configuration configuration = context.configuration(); + final Metrics providedMetrics = MetricsInjectionModule.provideMetrics(configuration); + final MetricsService service = + MetricsInjectionModule.bindMetricsService(new MetricsServiceImpl(providedMetrics)); + + for (int i = 0; i < 10; i++) { + metricsService.increment(LiveBlockItems); + } + + assertEquals(LiveBlockItems.grafanaLabel(), metricsService.name(LiveBlockItems)); + assertEquals(LiveBlockItems.description(), metricsService.description(LiveBlockItems)); + assertEquals(10, metricsService.count(LiveBlockItems)); + // + // assertEquals(liveBlockItems, service.liveBlockItems()); + + // service.liveBlockItems().increment(); + // verify(liveBlockItems, times(1)).increment(); } - @Test - void MetricsService_initializesSubscribersGauge() { - Metrics metrics = mock(Metrics.class); - LongGauge subscribers = mock(LongGauge.class); - when(metrics.getOrCreate(any(LongGauge.Config.class))).thenReturn(subscribers); - - MetricsService service = new MetricsServiceImpl(metrics); - - assertEquals(subscribers, service.subscribers()); - - service.subscribers().set(5); - verify(subscribers, times(1)).set(5); - } + // @Test + // void MetricsService_initializesBlocksPersistedCounter() { + // Metrics metrics = mock(Metrics.class); + // Counter blocksPersisted = mock(Counter.class); + // when(metrics.getOrCreate(any(Counter.Config.class))).thenReturn(blocksPersisted); + // + // MetricsService service = new MetricsServiceImpl(metrics); + // + // assertEquals(blocksPersisted, service.blocksPersisted()); + // + // service.blocksPersisted().increment(); + // verify(blocksPersisted, times(1)).increment(); + // } + // + // @Test + // void MetricsService_initializesSingleBlocksRetrievedCounter() { + // Metrics metrics = mock(Metrics.class); + // Counter singleBlocksRetrieved = mock(Counter.class); + // + // when(metrics.getOrCreate(any(Counter.Config.class))).thenReturn(singleBlocksRetrieved); + // + // MetricsService service = new MetricsServiceImpl(metrics); + // + // assertEquals(singleBlocksRetrieved, service.singleBlocksRetrieved()); + // + // service.singleBlocksRetrieved().increment(); + // verify(singleBlocksRetrieved, times(1)).increment(); + // } + // + // @Test + // void MetricsService_initializesSubscribersGauge() { + // Metrics metrics = mock(Metrics.class); + // LongGauge subscribers = mock(LongGauge.class); + // when(metrics.getOrCreate(any(LongGauge.Config.class))).thenReturn(subscribers); + // + // MetricsService service = new MetricsServiceImpl(metrics); + // + // assertEquals(subscribers, service.subscribers()); + // + // service.subscribers().set(5); + // verify(subscribers, times(1)).set(5); + // } } diff --git a/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java b/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java index 9c6e7bca..8b4385c1 100644 --- a/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java +++ b/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java @@ -17,6 +17,7 @@ package com.hedera.block.server.producer; import static com.hedera.block.server.Translator.fromPbj; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; import static com.hedera.block.server.producer.Util.getFakeHash; import static com.hedera.block.server.util.PersistTestUtils.generateBlockItems; import static com.hedera.block.server.util.PersistTestUtils.reverseByteArray; @@ -179,7 +180,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) producerBlockItemObserver.onNext(fromPbj(publishStreamRequest)); // Confirm the block item counter was incremented - assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); + assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); // Confirm each subscriber was notified of the new block verify(streamObserver1, timeout(testTimeout).times(1)) From d2ed3754b0386b1628007d456ae1071618c8800d Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Wed, 28 Aug 2024 13:21:00 -0600 Subject: [PATCH 03/12] wip Signed-off-by: Matt Peterson --- .../block/server/metrics/MetricsServiceTest.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java index 7e44b1b2..2c3590b1 100644 --- a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java +++ b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java @@ -26,16 +26,23 @@ import java.io.IOException; import org.junit.jupiter.api.Test; +import javax.inject.Inject; + public class MetricsServiceTest { + @Inject + private MetricsService metricsService; + @Test void MetricsService_initializesLiveBlockItemsCounter() throws IOException { final BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); final Configuration configuration = context.configuration(); final Metrics providedMetrics = MetricsInjectionModule.provideMetrics(configuration); - final MetricsService service = - MetricsInjectionModule.bindMetricsService(new MetricsServiceImpl(providedMetrics)); + +// final MetricsService service = +// MetricsInjectionModule.bindMetricsService(new MetricsServiceImpl(providedMetrics)); + for (int i = 0; i < 10; i++) { metricsService.increment(LiveBlockItems); From a9f91e6712b104828673f7d22b226d275b8e9124 Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Wed, 28 Aug 2024 13:21:21 -0600 Subject: [PATCH 04/12] wip Signed-off-by: Matt Peterson --- .../block/server/metrics/MetricsServiceTest.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java index 2c3590b1..8340badf 100644 --- a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java +++ b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java @@ -24,14 +24,12 @@ import com.swirlds.config.api.Configuration; import com.swirlds.metrics.api.Metrics; import java.io.IOException; -import org.junit.jupiter.api.Test; - import javax.inject.Inject; +import org.junit.jupiter.api.Test; public class MetricsServiceTest { - @Inject - private MetricsService metricsService; + @Inject private MetricsService metricsService; @Test void MetricsService_initializesLiveBlockItemsCounter() throws IOException { @@ -40,9 +38,9 @@ void MetricsService_initializesLiveBlockItemsCounter() throws IOException { final Configuration configuration = context.configuration(); final Metrics providedMetrics = MetricsInjectionModule.provideMetrics(configuration); -// final MetricsService service = -// MetricsInjectionModule.bindMetricsService(new MetricsServiceImpl(providedMetrics)); - + // final MetricsService service = + // MetricsInjectionModule.bindMetricsService(new + // MetricsServiceImpl(providedMetrics)); for (int i = 0; i < 10; i++) { metricsService.increment(LiveBlockItems); From 153ba437f0a4171f7147aed6d7af90ae8e6fc432 Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Wed, 28 Aug 2024 14:30:19 -0600 Subject: [PATCH 05/12] fix: one test is working with dagger injection Signed-off-by: Matt Peterson --- server/build.gradle.kts | 1 + .../server/metrics/MetricsServiceTest.java | 40 ++++++++++++------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/server/build.gradle.kts b/server/build.gradle.kts index 75b890ef..7bd25553 100644 --- a/server/build.gradle.kts +++ b/server/build.gradle.kts @@ -32,6 +32,7 @@ mainModuleInfo { } testModuleInfo { + annotationProcessor("dagger.compiler") requires("org.junit.jupiter.api") requires("org.mockito") requires("org.mockito.junit.jupiter") diff --git a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java index 8340badf..026412d7 100644 --- a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java +++ b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java @@ -22,26 +22,43 @@ import com.hedera.block.server.config.BlockNodeContext; import com.hedera.block.server.util.TestConfigUtil; import com.swirlds.config.api.Configuration; -import com.swirlds.metrics.api.Metrics; +import dagger.BindsInstance; +import dagger.Component; import java.io.IOException; -import javax.inject.Inject; +import javax.inject.Singleton; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class MetricsServiceTest { - @Inject private MetricsService metricsService; + @Singleton + @Component(modules = {MetricsInjectionModule.class}) + public interface TestComponent { - @Test - void MetricsService_initializesLiveBlockItemsCounter() throws IOException { + MetricsService getMetricsService(); + + @Component.Factory + interface Factory { + TestComponent create(@BindsInstance Configuration configuration); + } + } + + MetricsService metricsService; + + @BeforeEach + public void setUp() throws IOException { final BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); final Configuration configuration = context.configuration(); - final Metrics providedMetrics = MetricsInjectionModule.provideMetrics(configuration); + final TestComponent testComponent = + DaggerMetricsServiceTest_TestComponent.factory().create(configuration); + this.metricsService = testComponent.getMetricsService(); + } - // final MetricsService service = - // MetricsInjectionModule.bindMetricsService(new - // MetricsServiceImpl(providedMetrics)); + @Test + void MetricsService_initializesLiveBlockItemsCounter() throws IOException { + // increment the counter for (int i = 0; i < 10; i++) { metricsService.increment(LiveBlockItems); } @@ -49,11 +66,6 @@ void MetricsService_initializesLiveBlockItemsCounter() throws IOException { assertEquals(LiveBlockItems.grafanaLabel(), metricsService.name(LiveBlockItems)); assertEquals(LiveBlockItems.description(), metricsService.description(LiveBlockItems)); assertEquals(10, metricsService.count(LiveBlockItems)); - // - // assertEquals(liveBlockItems, service.liveBlockItems()); - - // service.liveBlockItems().increment(); - // verify(liveBlockItems, times(1)).increment(); } // @Test From 15efd3343b66c3f343bcce38987e5f6eb8aa23bd Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Thu, 29 Aug 2024 07:54:49 -0600 Subject: [PATCH 06/12] fix: refactor Signed-off-by: Matt Peterson --- .../block/server/BlockStreamService.java | 2 +- .../ConsumerStreamResponseObserver.java | 3 +- .../mediator/LiveStreamMediatorImpl.java | 6 +- .../server/metrics/BlockNodeMetricNames.java | 6 +- .../block/server/metrics/CounterMetrics.java | 31 ---- .../block/server/metrics/GaugeMetrics.java | 28 ---- .../block/server/metrics/MetricsService.java | 10 +- .../server/metrics/MetricsServiceImpl.java | 36 +---- .../storage/write/BlockAsDirWriter.java | 2 +- .../BlockStreamServiceIntegrationTest.java | 2 +- .../mediator/LiveStreamMediatorImplTest.java | 14 +- .../server/metrics/MetricsServiceTest.java | 132 +++++++++++------- .../ProducerBlockItemObserverTest.java | 2 +- 13 files changed, 112 insertions(+), 162 deletions(-) delete mode 100644 server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java delete mode 100644 server/src/main/java/com/hedera/block/server/metrics/GaugeMetrics.java diff --git a/server/src/main/java/com/hedera/block/server/BlockStreamService.java b/server/src/main/java/com/hedera/block/server/BlockStreamService.java index d5691a23..7d8b87b0 100644 --- a/server/src/main/java/com/hedera/block/server/BlockStreamService.java +++ b/server/src/main/java/com/hedera/block/server/BlockStreamService.java @@ -204,7 +204,7 @@ private void singleBlock( singleBlockResponseStreamObserver.onNext( fromPbjSingleBlockSuccessResponse(blockOpt.get())); - metricsService.increment(SingleBlocksRetrieved); + metricsService.get(SingleBlocksRetrieved).increment(); } else { LOGGER.log(DEBUG, "Block number {0} not found", blockNumber); singleBlockResponseStreamObserver.onNext(buildSingleBlockNotFoundResponse()); diff --git a/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java b/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java index 6457f3f9..32d351f1 100644 --- a/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java +++ b/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java @@ -167,7 +167,8 @@ public void onEvent( // Refresh the producer liveness and pass the BlockItem to the downstream observer. producerLivenessMillis = currentMillis; - metricsService.increment(LiveBlockItemsConsumed); + // Increment counter + metricsService.get(LiveBlockItemsConsumed).increment(); final SubscribeStreamResponse subscribeStreamResponse = event.get(); final ResponseSender responseSender = getResponseSender(subscribeStreamResponse); diff --git a/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java b/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java index 8b30da6b..02478630 100644 --- a/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java +++ b/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java @@ -120,7 +120,7 @@ public void publish(@NonNull final BlockItem blockItem) throws IOException { ringBuffer.publishEvent((event, sequence) -> event.set(subscribeStreamResponse)); // Increment the block item counter - metricsService.increment(LiveBlockItems); + metricsService.get(LiveBlockItems).increment(); try { // Persist the BlockItem @@ -169,7 +169,7 @@ public void subscribe( subscribers.put(handler, batchEventProcessor); // update the subscriber metrics - metricsService.set(Subscribers, subscribers.size()); + metricsService.get(Subscribers).set(subscribers.size()); } @Override @@ -191,7 +191,7 @@ public void unsubscribe( } // update the subscriber metrics - metricsService.set(Subscribers, subscribers.size()); + metricsService.get(Subscribers).set(subscribers.size()); } @Override diff --git a/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java b/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java index a6901fcc..e763f913 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java +++ b/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java @@ -18,7 +18,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; -public class BlockNodeMetricNames { +public final class BlockNodeMetricNames { + private BlockNodeMetricNames() {} + public enum Counter implements MetricMetadata { LiveBlockItems("live_block_items", "Live BlockItems"), BlocksPersisted("blocks_persisted", "Blocks Persisted"), @@ -70,7 +72,7 @@ public String description() { } } - public interface MetricMetadata { + private interface MetricMetadata { String grafanaLabel(); String description(); diff --git a/server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java b/server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java deleted file mode 100644 index 406f022a..00000000 --- a/server/src/main/java/com/hedera/block/server/metrics/CounterMetrics.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * Licensed 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 com.hedera.block.server.metrics; - -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface CounterMetrics { - void increment(@NonNull BlockNodeMetricNames.Counter key); - - long count(@NonNull BlockNodeMetricNames.Counter key); - - @NonNull - String name(@NonNull BlockNodeMetricNames.Counter key); - - @NonNull - String description(@NonNull BlockNodeMetricNames.Counter key); -} diff --git a/server/src/main/java/com/hedera/block/server/metrics/GaugeMetrics.java b/server/src/main/java/com/hedera/block/server/metrics/GaugeMetrics.java deleted file mode 100644 index 896b5bf7..00000000 --- a/server/src/main/java/com/hedera/block/server/metrics/GaugeMetrics.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * Licensed 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 com.hedera.block.server.metrics; - -import edu.umd.cs.findbugs.annotations.NonNull; - -public interface GaugeMetrics { - void set(@NonNull BlockNodeMetricNames.Gauge key, long value); - - long count(@NonNull BlockNodeMetricNames.Gauge key); - - @NonNull - String name(@NonNull BlockNodeMetricNames.Gauge key); -} diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java index 71c4fc88..8cce37f8 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java @@ -16,5 +16,13 @@ package com.hedera.block.server.metrics; +import com.swirlds.metrics.api.Counter; +import com.swirlds.metrics.api.LongGauge; +import edu.umd.cs.findbugs.annotations.NonNull; + /** Use member variables of this class to update metric data for the Hedera Block Node. */ -public interface MetricsService extends CounterMetrics, GaugeMetrics {} +public interface MetricsService { + Counter get(@NonNull BlockNodeMetricNames.Counter key); + + LongGauge get(@NonNull BlockNodeMetricNames.Gauge key); +} diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java index 680aa070..9207acc0 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java @@ -64,41 +64,15 @@ public MetricsServiceImpl(@NonNull final Metrics metrics) { } } - @Override - public void increment(@NonNull BlockNodeMetricNames.Counter key) { - counters.get(key).increment(); - } - - @Override - public long count(@NonNull BlockNodeMetricNames.Counter key) { - return counters.get(key).get(); - } - - @Override - @NonNull - public String name(@NonNull BlockNodeMetricNames.Counter key) { - return counters.get(key).getName(); - } - - @Override @NonNull - public String description(@NonNull BlockNodeMetricNames.Counter key) { - return counters.get(key).getDescription(); - } - @Override - public void set(@NonNull BlockNodeMetricNames.Gauge key, long value) { - gauges.get(key).set(value); + public Counter get(@NonNull BlockNodeMetricNames.Counter key) { + return counters.get(key); } - @Override - public long count(@NonNull BlockNodeMetricNames.Gauge key) { - return gauges.get(key).get(); - } - - @Override @NonNull - public String name(@NonNull BlockNodeMetricNames.Gauge key) { - return gauges.get(key).getName(); + @Override + public LongGauge get(@NonNull BlockNodeMetricNames.Gauge key) { + return gauges.get(key); } } diff --git a/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java b/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java index 6418409b..d097a4d7 100644 --- a/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java +++ b/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java @@ -163,7 +163,7 @@ private void resetState(@NonNull final BlockItem blockItem) throws IOException { blockNodeFileNameIndex = 0; // Increment the block counter - metricsService.increment(BlocksPersisted); + metricsService.get(BlocksPersisted).increment(); } private void repairPermissions(@NonNull final Path path) throws IOException { diff --git a/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java b/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java index 2ccd9c90..52a0415e 100644 --- a/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java @@ -231,7 +231,7 @@ public void testSubscribeBlockStream() throws IOException { streamObserver.onNext(fromPbj(publishStreamRequest)); // Verify the counter was incremented - assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); + assertEquals(1, blockNodeContext.metricsService().get(LiveBlockItems).get()); verify(blockWriter, timeout(testTimeout).times(1)).write(blockItems.getFirst()); diff --git a/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java b/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java index 4420c25f..356687bf 100644 --- a/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java +++ b/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java @@ -132,7 +132,7 @@ public void testUnsubscribeEach() throws InterruptedException, IOException { "Expected the mediator to have unsubscribed observer3"); // Confirm the counter was never incremented - assertEquals(0, blockNodeContext.metricsService().count(LiveBlockItems)); + assertEquals(0, blockNodeContext.metricsService().get(LiveBlockItems).get()); } @Test @@ -149,7 +149,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) streamMediator.publish(blockItem); // Verify the counter was incremented - assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); + assertEquals(1, blockNodeContext.metricsService().get(LiveBlockItems).get()); // Confirm the BlockStorage write method was // called despite the absence of subscribers @@ -202,7 +202,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) // Acting as a producer, notify the mediator of a new block streamMediator.publish(blockItem); - assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); + assertEquals(1, blockNodeContext.metricsService().get(LiveBlockItems).get()); // Confirm each subscriber was notified of the new block verify(streamObserver1, timeout(testTimeout).times(1)) @@ -249,7 +249,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) streamMediator.unsubscribe(concreteObserver3); // Confirm the counter was never incremented - assertEquals(0, blockNodeContext.metricsService().count(LiveBlockItems)); + assertEquals(0, blockNodeContext.metricsService().get(LiveBlockItems).get()); } @Test @@ -278,7 +278,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) testConsumerBlockItemObserver.getOnCancel().run(); // Verify the block item incremented the counter - assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); + assertEquals(1, blockNodeContext.metricsService().get(LiveBlockItems).get()); // Verify the event made it to the consumer verify(serverCallStreamObserver, timeout(testTimeout).times(1)).setOnCancelHandler(any()); @@ -314,7 +314,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) testConsumerBlockItemObserver.getOnClose().run(); // Verify the block item incremented the counter - assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); + assertEquals(1, blockNodeContext.metricsService().get(LiveBlockItems).get()); // Verify the event made it to the consumer verify(serverCallStreamObserver, timeout(testTimeout).times(1)).setOnCancelHandler(any()); @@ -349,7 +349,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) streamMediator.publish(secondBlockItem); // Confirm the counter was incremented only once - assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); + assertEquals(1, blockNodeContext.metricsService().get(LiveBlockItems).get()); // Confirm the BlockPersistenceHandler write method was only called // once despite the second block being published. diff --git a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java index 026412d7..ebdd0381 100644 --- a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java +++ b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java @@ -16,7 +16,11 @@ package com.hedera.block.server.metrics; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.BlocksPersisted; import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItemsConsumed; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.SingleBlocksRetrieved; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Gauge.Subscribers; import static org.junit.jupiter.api.Assertions.assertEquals; import com.hedera.block.server.config.BlockNodeContext; @@ -33,81 +37,101 @@ public class MetricsServiceTest { @Singleton @Component(modules = {MetricsInjectionModule.class}) - public interface TestComponent { + public interface MetricsServiceTestComponent { MetricsService getMetricsService(); @Component.Factory interface Factory { - TestComponent create(@BindsInstance Configuration configuration); + MetricsServiceTestComponent create(@BindsInstance Configuration configuration); } } - MetricsService metricsService; + private MetricsService metricsService; @BeforeEach public void setUp() throws IOException { - final BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); final Configuration configuration = context.configuration(); - final TestComponent testComponent = - DaggerMetricsServiceTest_TestComponent.factory().create(configuration); + final MetricsServiceTestComponent testComponent = + DaggerMetricsServiceTest_MetricsServiceTestComponent.factory() + .create(configuration); this.metricsService = testComponent.getMetricsService(); } @Test - void MetricsService_initializesLiveBlockItemsCounter() throws IOException { + void MetricsService_verifyLiveBlockItemsCounter() { + + for (int i = 0; i < 10; i++) { + metricsService.get(LiveBlockItems).increment(); + } + + assertEquals(LiveBlockItems.grafanaLabel(), metricsService.get(LiveBlockItems).getName()); + assertEquals( + LiveBlockItems.description(), metricsService.get(LiveBlockItems).getDescription()); + assertEquals(10, metricsService.get(LiveBlockItems).get()); + } + + @Test + void MetricsService_verifyBlocksPersistedCounter() { + + for (int i = 0; i < 10; i++) { + metricsService.get(BlocksPersisted).increment(); + } + + assertEquals(BlocksPersisted.grafanaLabel(), metricsService.get(BlocksPersisted).getName()); + assertEquals( + BlocksPersisted.description(), + metricsService.get(BlocksPersisted).getDescription()); + assertEquals(10, metricsService.get(BlocksPersisted).get()); + } + + @Test + void MetricsService_verifySingleBlocksRetrievedCounter() { + + for (int i = 0; i < 10; i++) { + metricsService.get(SingleBlocksRetrieved).increment(); + } + + assertEquals( + SingleBlocksRetrieved.grafanaLabel(), + metricsService.get(SingleBlocksRetrieved).getName()); + assertEquals( + SingleBlocksRetrieved.description(), + metricsService.get(SingleBlocksRetrieved).getDescription()); + assertEquals(10, metricsService.get(SingleBlocksRetrieved).get()); + } + + @Test + void MetricsService_verifyLiveBlockItemsConsumedCounter() { - // increment the counter for (int i = 0; i < 10; i++) { - metricsService.increment(LiveBlockItems); + metricsService.get(LiveBlockItemsConsumed).increment(); } - assertEquals(LiveBlockItems.grafanaLabel(), metricsService.name(LiveBlockItems)); - assertEquals(LiveBlockItems.description(), metricsService.description(LiveBlockItems)); - assertEquals(10, metricsService.count(LiveBlockItems)); + assertEquals( + LiveBlockItemsConsumed.grafanaLabel(), + metricsService.get(LiveBlockItemsConsumed).getName()); + assertEquals( + LiveBlockItemsConsumed.description(), + metricsService.get(LiveBlockItemsConsumed).getDescription()); + assertEquals(10, metricsService.get(LiveBlockItemsConsumed).get()); } - // @Test - // void MetricsService_initializesBlocksPersistedCounter() { - // Metrics metrics = mock(Metrics.class); - // Counter blocksPersisted = mock(Counter.class); - // when(metrics.getOrCreate(any(Counter.Config.class))).thenReturn(blocksPersisted); - // - // MetricsService service = new MetricsServiceImpl(metrics); - // - // assertEquals(blocksPersisted, service.blocksPersisted()); - // - // service.blocksPersisted().increment(); - // verify(blocksPersisted, times(1)).increment(); - // } - // - // @Test - // void MetricsService_initializesSingleBlocksRetrievedCounter() { - // Metrics metrics = mock(Metrics.class); - // Counter singleBlocksRetrieved = mock(Counter.class); - // - // when(metrics.getOrCreate(any(Counter.Config.class))).thenReturn(singleBlocksRetrieved); - // - // MetricsService service = new MetricsServiceImpl(metrics); - // - // assertEquals(singleBlocksRetrieved, service.singleBlocksRetrieved()); - // - // service.singleBlocksRetrieved().increment(); - // verify(singleBlocksRetrieved, times(1)).increment(); - // } - // - // @Test - // void MetricsService_initializesSubscribersGauge() { - // Metrics metrics = mock(Metrics.class); - // LongGauge subscribers = mock(LongGauge.class); - // when(metrics.getOrCreate(any(LongGauge.Config.class))).thenReturn(subscribers); - // - // MetricsService service = new MetricsServiceImpl(metrics); - // - // assertEquals(subscribers, service.subscribers()); - // - // service.subscribers().set(5); - // verify(subscribers, times(1)).set(5); - // } + @Test + void MetricsService_verifySubscribersGauge() { + + assertEquals(Subscribers.grafanaLabel(), metricsService.get(Subscribers).getName()); + assertEquals(Subscribers.description(), metricsService.get(Subscribers).getDescription()); + + // Set the subscribers to various values and verify + metricsService.get(Subscribers).set(10); + assertEquals(10, metricsService.get(Subscribers).get()); + + metricsService.get(Subscribers).set(3); + assertEquals(3, metricsService.get(Subscribers).get()); + + metricsService.get(Subscribers).set(0); + assertEquals(0, metricsService.get(Subscribers).get()); + } } diff --git a/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java b/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java index 8b4385c1..bac879f4 100644 --- a/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java +++ b/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java @@ -180,7 +180,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) producerBlockItemObserver.onNext(fromPbj(publishStreamRequest)); // Confirm the block item counter was incremented - assertEquals(1, blockNodeContext.metricsService().count(LiveBlockItems)); + assertEquals(1, blockNodeContext.metricsService().get(LiveBlockItems).get()); // Confirm each subscriber was notified of the new block verify(streamObserver1, timeout(testTimeout).times(1)) From ad8bfb269993a8eab1b52cf07bc589054d9f1cd9 Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Thu, 29 Aug 2024 08:08:50 -0600 Subject: [PATCH 07/12] fix: latest dashboard Signed-off-by: Matt Peterson --- server/docker/metrics/dashboards/block-node-server.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/server/docker/metrics/dashboards/block-node-server.json b/server/docker/metrics/dashboards/block-node-server.json index 9b662595..4a7e0807 100644 --- a/server/docker/metrics/dashboards/block-node-server.json +++ b/server/docker/metrics/dashboards/block-node-server.json @@ -543,8 +543,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "yellow", @@ -646,8 +645,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -710,6 +708,6 @@ "timezone": "browser", "title": "Block-Node Server Dashboard", "uid": "edu86nutnxts0c", - "version": 1, + "version": 8, "weekStart": "" } From 5e437b36a44b1c65bbd17a3ffe4dca8cc26f6f77 Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Thu, 29 Aug 2024 11:34:45 -0600 Subject: [PATCH 08/12] fix: changed the SERVER_OPTS to wait for a remote debugger to attach Signed-off-by: Matt Peterson --- server/docker/update-env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/docker/update-env.sh b/server/docker/update-env.sh index a840ba65..eda32dd2 100755 --- a/server/docker/update-env.sh +++ b/server/docker/update-env.sh @@ -14,7 +14,7 @@ echo "REGISTRY_PREFIX=" >> .env echo "BLOCKNODE_STORAGE_ROOT_PATH=/app/storage" >> .env if [ $# -eq 2 ]; then - echo "SERVER_OPTS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005'" >> .env + echo "SERVER_OPTS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005'" >> .env fi echo "DEBUG $2" From c9864bee85cadf45f0b04c8512b797e491fb6ef0 Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Tue, 3 Sep 2024 08:43:08 -0600 Subject: [PATCH 09/12] feat: added additional metrics Signed-off-by: Matt Peterson --- .../metrics/dashboards/block-node-server.json | 811 +++++++++++++++--- .../block/server/BlockStreamService.java | 4 +- .../ConsumerStreamResponseObserver.java | 6 +- .../mediator/LiveStreamMediatorImpl.java | 11 +- .../server/metrics/BlockNodeMetricNames.java | 9 +- .../producer/ProducerBlockItemObserver.java | 14 +- .../ProducerBlockItemObserverTest.java | 48 +- 7 files changed, 784 insertions(+), 119 deletions(-) diff --git a/server/docker/metrics/dashboards/block-node-server.json b/server/docker/metrics/dashboards/block-node-server.json index 4a7e0807..e28ff6b8 100644 --- a/server/docker/metrics/dashboards/block-node-server.json +++ b/server/docker/metrics/dashboards/block-node-server.json @@ -21,16 +21,14 @@ "links": [], "panels": [ { - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, - "id": 9, - "panels": [], - "title": "Live Stream", + "id": 16, + "title": "Errors", "type": "row" }, { @@ -50,22 +48,27 @@ { "color": "green", "value": null + }, + { + "color": "red", + "value": 1 } ] - } + }, + "unit": "short" }, "overrides": [] }, "gridPos": { - "h": 7, + "h": 8, "w": 6, "x": 0, "y": 1 }, - "id": 3, + "id": 15, "options": { "colorMode": "value", - "graphMode": "area", + "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "percentChangeColorMode": "standard", @@ -88,14 +91,14 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "hedera_block_node_live_block_items_total", + "expr": "hedera_block_node_live_block_stream_mediator_error_total", "instant": false, - "legendFormat": "BlockItems", + "legendFormat": "Block Item Errors", "range": true, "refId": "A" } ], - "title": "Live Block Item Counter", + "title": "Mediator Errors", "type": "stat" }, { @@ -137,7 +140,7 @@ "mode": "none" }, "thresholdsStyle": { - "mode": "area" + "mode": "off" } }, "mappings": [], @@ -145,30 +148,25 @@ "mode": "absolute", "steps": [ { - "color": "dark-red", + "color": "green", "value": null }, { - "color": "#EAB839", - "value": 5 - }, - { - "color": "green", - "value": 30 + "color": "red", + "value": 1 } ] - }, - "unit": "reqps" + } }, "overrides": [] }, "gridPos": { - "h": 7, + "h": 8, "w": 18, "x": 6, "y": 1 }, - "id": 7, + "id": 14, "options": { "legend": { "calcs": [], @@ -181,7 +179,6 @@ "sort": "none" } }, - "pluginVersion": "11.1.3", "targets": [ { "datasource": { @@ -189,16 +186,29 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "rate( hedera_block_node_live_block_items_total [$__rate_interval])", + "expr": "rate( hedera_block_node_live_block_stream_mediator_error_total [$__rate_interval])", "instant": false, - "legendFormat": "BlockItems", + "legendFormat": "Mediator Errors", "range": true, "refId": "A" } ], - "title": "Live Block Item Counter", + "title": "Rate of Mediator Errors", "type": "timeseries" }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 9, + "panels": [], + "title": "Live Stream", + "type": "row" + }, { "datasource": { "type": "prometheus", @@ -218,20 +228,21 @@ "value": null } ] - } + }, + "unit": "short" }, "overrides": [] }, "gridPos": { - "h": 6, + "h": 8, "w": 6, "x": 0, - "y": 8 + "y": 10 }, - "id": 11, + "id": 13, "options": { "colorMode": "value", - "graphMode": "area", + "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "percentChangeColorMode": "standard", @@ -254,14 +265,14 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "hedera_block_node_live_block_items_consumed_total", + "expr": "hedera_block_node_live_block_items_received_total", "instant": false, - "legendFormat": "BlockItems Consumed", + "legendFormat": "BlockItems", "range": true, "refId": "A" } ], - "title": "Live Block Items Consumed Counter", + "title": "Live Block Items Received from Producer", "type": "stat" }, { @@ -269,6 +280,7 @@ "type": "prometheus", "uid": "PBFA97CFB590B2093" }, + "description": "", "fieldConfig": { "defaults": { "color": { @@ -311,25 +323,30 @@ "mode": "absolute", "steps": [ { - "color": "green", + "color": "red", "value": null }, { - "color": "red", - "value": 80 + "color": "#EAB839", + "value": 5 + }, + { + "color": "green", + "value": 30 } ] - } + }, + "unit": "reqps" }, "overrides": [] }, "gridPos": { - "h": 6, + "h": 8, "w": 18, "x": 6, - "y": 8 + "y": 10 }, - "id": 10, + "id": 12, "options": { "legend": { "calcs": [], @@ -349,14 +366,14 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "rate( hedera_block_node_live_block_items_consumed_total [$__rate_interval])", + "expr": "rate( hedera_block_node_live_block_items_received_total [$__rate_interval])", "instant": false, - "legendFormat": "__auto", + "legendFormat": "BlockItems", "range": true, "refId": "A" } ], - "title": "Live Block Items Consumed", + "title": "Rate of Live Block Items Received from Producer", "type": "timeseries" }, { @@ -378,7 +395,8 @@ "value": null } ] - } + }, + "unit": "short" }, "overrides": [] }, @@ -386,12 +404,12 @@ "h": 7, "w": 6, "x": 0, - "y": 14 + "y": 18 }, - "id": 6, + "id": 3, "options": { "colorMode": "value", - "graphMode": "area", + "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "percentChangeColorMode": "standard", @@ -414,14 +432,14 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "hedera_block_node_blocks_persisted_total", + "expr": "hedera_block_node_live_block_items_total", "instant": false, - "legendFormat": "Block Persistence Counter", + "legendFormat": "BlockItems", "range": true, "refId": "A" } ], - "title": "Block Persistence Counter", + "title": "Live Block Item Counter", "type": "stat" }, { @@ -471,20 +489,20 @@ "mode": "absolute", "steps": [ { - "color": "red", + "color": "dark-red", "value": null }, { "color": "#EAB839", - "value": 2 + "value": 5 }, { "color": "green", - "value": 4 + "value": 30 } ] }, - "unit": "wps" + "unit": "reqps" }, "overrides": [] }, @@ -492,9 +510,9 @@ "h": 7, "w": 18, "x": 6, - "y": 14 + "y": 18 }, - "id": 8, + "id": 7, "options": { "legend": { "calcs": [], @@ -515,14 +533,14 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "rate(hedera_block_node_blocks_persisted_total[$__rate_interval])", + "expr": "rate( hedera_block_node_live_block_items_total [$__rate_interval])", "instant": false, - "legendFormat": "Block Persistence Counter", + "legendFormat": "BlockItems", "range": true, "refId": "A" } ], - "title": "Block Persistence Counter", + "title": "Rate of Live Block Items Received by Mediator", "type": "timeseries" }, { @@ -535,40 +553,33 @@ "color": { "mode": "thresholds" }, - "displayName": "Subscribers", "mappings": [], - "max": 20, - "min": 0, "thresholds": { "mode": "absolute", "steps": [ { - "color": "green" - }, - { - "color": "yellow", - "value": 10 - }, - { - "color": "red", - "value": 15 + "color": "green", + "value": null } ] - } + }, + "unit": "short" }, "overrides": [] }, "gridPos": { - "h": 9, - "w": 9, + "h": 7, + "w": 6, "x": 0, - "y": 21 + "y": 25 }, - "id": 4, + "id": 11, "options": { - "minVizHeight": 75, - "minVizWidth": 75, + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", "orientation": "auto", + "percentChangeColorMode": "standard", "reduceOptions": { "calcs": [ "lastNotNull" @@ -576,9 +587,9 @@ "fields": "", "values": false }, - "showThresholdLabels": false, - "showThresholdMarkers": true, - "sizing": "auto" + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true }, "pluginVersion": "11.1.4", "targets": [ @@ -588,15 +599,15 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "hedera_block_node_subscribers", + "expr": "hedera_block_node_live_block_items_consumed_total", "instant": false, - "legendFormat": "__auto", + "legendFormat": "BlockItems Consumed", "range": true, "refId": "A" } ], - "title": "Subscribers", - "type": "gauge" + "title": "Live Block Items Consumed Counter", + "type": "stat" }, { "datasource": { @@ -645,10 +656,15 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "red", + "value": null }, { - "color": "red", + "color": "#EAB839", + "value": 5 + }, + { + "color": "green", "value": 80 } ] @@ -658,12 +674,12 @@ "overrides": [] }, "gridPos": { - "h": 9, - "w": 15, - "x": 9, - "y": 21 + "h": 7, + "w": 18, + "x": 6, + "y": 25 }, - "id": 5, + "id": 10, "options": { "legend": { "calcs": [], @@ -683,14 +699,613 @@ "uid": "PBFA97CFB590B2093" }, "editorMode": "code", - "expr": "rate(hedera_block_node_single_blocks_retrieved_total[$__rate_interval])", + "expr": "rate( hedera_block_node_live_block_items_consumed_total [$__rate_interval])", "instant": false, - "legendFormat": "RPS of Single Blocks Retrieval", + "legendFormat": "BlockItems", + "range": true, + "refId": "A" + } + ], + "title": "Rate of Block Items Sent to Consumer(s)", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "displayName": "Subscribers", + "mappings": [], + "max": 20, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 10 + }, + { + "color": "red", + "value": 15 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 32 + }, + "id": 4, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.1.4", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "hedera_block_node_subscribers", + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Subscribers", + "type": "gauge" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 40 + }, + "id": 18, + "panels": [], + "title": "Persistence", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 41 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.1.4", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "hedera_block_node_blocks_persisted_total", + "instant": false, + "legendFormat": "Block Persistence Counter", + "range": true, + "refId": "A" + } + ], + "title": "Block Persistence Counter", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "area" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "#EAB839", + "value": 2 + }, + { + "color": "green", + "value": 4 + } + ] + }, + "unit": "wps" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 18, + "x": 6, + "y": 41 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.1.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "rate(hedera_block_node_blocks_persisted_total[$__rate_interval])", + "instant": false, + "legendFormat": "Block Persistence Counter", + "range": true, + "refId": "A" + } + ], + "title": "Rate of Blocks Written to the File System", + "type": "timeseries" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 48 + }, + "id": 17, + "panels": [], + "title": "Single Block", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 49 + }, + "id": 19, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.1.4", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "hedera_block_node_single_blocks_retrieved_total", + "instant": false, + "legendFormat": "Single Blocks Retrieved", + "range": true, + "refId": "A" + } + ], + "title": "Single Blocks Retrieved", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 18, + "x": 6, + "y": 49 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "rate(hedera_block_node_single_blocks_retrieved_total[$__rate_interval])", + "instant": false, + "legendFormat": "RPS of Single Blocks Retrieval", + "range": true, + "refId": "A" + } + ], + "title": "Rate of Single Blocks Retrieved", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 0, + "y": 57 + }, + "id": 21, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.1.4", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "hedera_block_node_single_blocks_not_found_total", + "instant": false, + "legendFormat": "Single Blocks Not Found", + "range": true, + "refId": "A" + } + ], + "title": "Single Blocks Not Found", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 18, + "x": 6, + "y": 57 + }, + "id": 20, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "rate( hedera_block_node_single_blocks_not_found_total [$__rate_interval])", + "instant": false, + "legendFormat": "Single Blocks Not Found", "range": true, "refId": "A" } ], - "title": "Rate of Single Blocks Retrieval", + "title": "Rate of Single Blocks Not Found", "type": "timeseries" } ], @@ -708,6 +1323,6 @@ "timezone": "browser", "title": "Block-Node Server Dashboard", "uid": "edu86nutnxts0c", - "version": 8, + "version": 1, "weekStart": "" } diff --git a/server/src/main/java/com/hedera/block/server/BlockStreamService.java b/server/src/main/java/com/hedera/block/server/BlockStreamService.java index 7d8b87b0..807630b6 100644 --- a/server/src/main/java/com/hedera/block/server/BlockStreamService.java +++ b/server/src/main/java/com/hedera/block/server/BlockStreamService.java @@ -22,6 +22,7 @@ import static com.hedera.block.server.Constants.SINGLE_BLOCK_METHOD_NAME; import static com.hedera.block.server.Translator.fromPbj; import static com.hedera.block.server.Translator.toPbj; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.SingleBlocksNotFound; import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.SingleBlocksRetrieved; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; @@ -139,7 +140,7 @@ StreamObserver protocPublishB LOGGER.log(DEBUG, "Executing bidirectional publishBlockStream gRPC method"); return new ProducerBlockItemObserver( - streamMediator, publishStreamResponseObserver, serviceStatus); + streamMediator, publishStreamResponseObserver, blockNodeContext, serviceStatus); } void protocSubscribeBlockStream( @@ -208,6 +209,7 @@ private void singleBlock( } else { LOGGER.log(DEBUG, "Block number {0} not found", blockNumber); singleBlockResponseStreamObserver.onNext(buildSingleBlockNotFoundResponse()); + metricsService.get(SingleBlocksNotFound).increment(); } } catch (IOException e) { LOGGER.log(ERROR, "Error reading block number: {0}", blockNumber); diff --git a/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java b/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java index 32d351f1..da5887d8 100644 --- a/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java +++ b/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java @@ -167,9 +167,6 @@ public void onEvent( // Refresh the producer liveness and pass the BlockItem to the downstream observer. producerLivenessMillis = currentMillis; - // Increment counter - metricsService.get(LiveBlockItemsConsumed).increment(); - final SubscribeStreamResponse subscribeStreamResponse = event.get(); final ResponseSender responseSender = getResponseSender(subscribeStreamResponse); responseSender.send(subscribeStreamResponse); @@ -219,6 +216,9 @@ public void send(@NonNull final SubscribeStreamResponse subscribeStreamResponse) if (streamStarted) { LOGGER.log(DEBUG, "Sending BlockItem downstream: {0}", blockItem); + + // Increment counter + metricsService.get(LiveBlockItemsConsumed).increment(); subscribeStreamResponseObserver.onNext(fromPbj(subscribeStreamResponse)); } } diff --git a/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java b/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java index 02478630..e967740e 100644 --- a/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java +++ b/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java @@ -17,6 +17,7 @@ package com.hedera.block.server.mediator; import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockStreamMediatorError; import static com.hedera.block.server.metrics.BlockNodeMetricNames.Gauge.Subscribers; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; @@ -126,15 +127,19 @@ public void publish(@NonNull final BlockItem blockItem) throws IOException { // Persist the BlockItem blockWriter.write(blockItem); } catch (IOException e) { + + // Increment the error counter + metricsService.get(LiveBlockStreamMediatorError).increment(); + // Disable BlockItem publication for upstream producers - serviceStatus.setRunning(false); + serviceStatus.stopRunning(this.getClass().getName()); LOGGER.log( ERROR, "An exception occurred while attempting to persist the BlockItem: " + blockItem, e); - LOGGER.log(DEBUG, "Send a response to end the stream"); + LOGGER.log(ERROR, "Send a response to end the stream"); // Publish the block for all subscribers to receive final SubscribeStreamResponse endStreamResponse = buildEndStreamResponse(); @@ -142,7 +147,7 @@ public void publish(@NonNull final BlockItem blockItem) throws IOException { // Unsubscribe all downstream consumers for (final var subscriber : subscribers.keySet()) { - LOGGER.log(DEBUG, "Unsubscribing: {0}", subscriber); + LOGGER.log(ERROR, String.format("Unsubscribing: %s", subscriber)); unsubscribe(subscriber); } diff --git a/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java b/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java index e763f913..094e2de3 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java +++ b/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java @@ -22,10 +22,17 @@ public final class BlockNodeMetricNames { private BlockNodeMetricNames() {} public enum Counter implements MetricMetadata { + // Standard counters + LiveBlockItemsReceived("live_block_items_received", "Live Block Items Received"), LiveBlockItems("live_block_items", "Live BlockItems"), BlocksPersisted("blocks_persisted", "Blocks Persisted"), LiveBlockItemsConsumed("live_block_items_consumed", "Live Block Items Consumed"), - SingleBlocksRetrieved("single_blocks_retrieved", "Single Blocks Retrieved"); + SingleBlocksRetrieved("single_blocks_retrieved", "Single Blocks Retrieved"), + SingleBlocksNotFound("single_blocks_not_found", "Single Blocks Not Found"), + + // Error counters + LiveBlockStreamMediatorError( + "live_block_stream_mediator_error", "Live Block Stream Mediator Error"); private final String grafanaLabel; private final String description; diff --git a/server/src/main/java/com/hedera/block/server/producer/ProducerBlockItemObserver.java b/server/src/main/java/com/hedera/block/server/producer/ProducerBlockItemObserver.java index d8bb5fb3..36dd6f6c 100644 --- a/server/src/main/java/com/hedera/block/server/producer/ProducerBlockItemObserver.java +++ b/server/src/main/java/com/hedera/block/server/producer/ProducerBlockItemObserver.java @@ -18,13 +18,16 @@ import static com.hedera.block.server.Translator.fromPbj; import static com.hedera.block.server.Translator.toPbj; +import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItemsReceived; import static com.hedera.block.server.producer.Util.getFakeHash; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.ERROR; import com.hedera.block.server.ServiceStatus; +import com.hedera.block.server.config.BlockNodeContext; import com.hedera.block.server.mediator.Publisher; +import com.hedera.block.server.metrics.MetricsService; import com.hedera.hapi.block.Acknowledgement; import com.hedera.hapi.block.EndOfStream; import com.hedera.hapi.block.ItemAcknowledgement; @@ -53,6 +56,7 @@ public class ProducerBlockItemObserver publishStreamResponseObserver; private final Publisher publisher; private final ServiceStatus serviceStatus; + private final MetricsService metricsService; /** * Constructor for the ProducerBlockStreamObserver class. It is responsible for calling the @@ -72,10 +76,12 @@ public ProducerBlockItemObserver( @NonNull final StreamObserver publishStreamResponseObserver, + @NonNull final BlockNodeContext blockNodeContext, @NonNull final ServiceStatus serviceStatus) { this.publisher = publisher; this.publishStreamResponseObserver = publishStreamResponseObserver; + this.metricsService = blockNodeContext.metricsService(); this.serviceStatus = serviceStatus; } @@ -92,8 +98,12 @@ public void onNext( try { + LOGGER.log(DEBUG, "Received PublishStreamRequest from producer"); final BlockItem blockItem = toPbj(BlockItem.PROTOBUF, publishStreamRequest.getBlockItem().toByteArray()); + LOGGER.log(DEBUG, "Received block item: " + blockItem); + + metricsService.get(LiveBlockItemsReceived).increment(); // Publish the block to all the subscribers unless // there's an issue with the StreamMediator. @@ -113,10 +123,12 @@ public void onNext( } } else { + LOGGER.log(ERROR, "StreamMediator is not accepting BlockItems"); + // Close the upstream connection to the producer(s) final var errorResponse = buildErrorStreamResponse(); publishStreamResponseObserver.onNext(errorResponse); - LOGGER.log(DEBUG, "StreamMediator is not accepting BlockItems"); + LOGGER.log(ERROR, "Error PublishStreamResponse sent to upstream producer"); } } catch (IOException io) { final var errorResponse = buildErrorStreamResponse(); diff --git a/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java b/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java index bac879f4..848cd870 100644 --- a/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java +++ b/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java @@ -89,10 +89,14 @@ public class ProducerBlockItemObserverTest { @Test public void testProducerOnNext() throws IOException, NoSuchAlgorithmException { + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final List blockItems = generateBlockItems(1); final ProducerBlockItemObserver producerBlockItemObserver = new ProducerBlockItemObserver( - streamMediator, publishStreamResponseObserver, serviceStatus); + streamMediator, + publishStreamResponseObserver, + blockNodeContext, + serviceStatus); when(serviceStatus.isRunning()).thenReturn(true); @@ -173,7 +177,10 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) final ProducerBlockItemObserver producerBlockItemObserver = new ProducerBlockItemObserver( - streamMediator, publishStreamResponseObserver, serviceStatus); + streamMediator, + publishStreamResponseObserver, + blockNodeContext, + serviceStatus); final PublishStreamRequest publishStreamRequest = PublishStreamRequest.newBuilder().blockItem(blockItem).build(); @@ -196,10 +203,15 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) } @Test - public void testOnError() { + public void testOnError() throws IOException { + + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final ProducerBlockItemObserver producerBlockItemObserver = new ProducerBlockItemObserver( - streamMediator, publishStreamResponseObserver, serviceStatus); + streamMediator, + publishStreamResponseObserver, + blockNodeContext, + serviceStatus); final Throwable t = new Throwable("Test error"); producerBlockItemObserver.onError(t); @@ -207,13 +219,17 @@ public void testOnError() { } @Test - public void testItemAckBuilderExceptionTest() { + public void testItemAckBuilderExceptionTest() throws IOException { when(serviceStatus.isRunning()).thenReturn(true); + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final ProducerBlockItemObserver testProducerBlockItemObserver = new TestProducerBlockItemObserver( - streamMediator, publishStreamResponseObserver, serviceStatus); + streamMediator, + publishStreamResponseObserver, + blockNodeContext, + serviceStatus); final List blockItems = generateBlockItems(1); final BlockItem blockHeader = blockItems.getFirst(); @@ -232,10 +248,16 @@ public void testItemAckBuilderExceptionTest() { } @Test - public void testBlockItemThrowsParseException() throws InvalidProtocolBufferException { + public void testBlockItemThrowsParseException() + throws IOException, InvalidProtocolBufferException { + + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final ProducerBlockItemObserver producerBlockItemObserver = new ProducerBlockItemObserver( - streamMediator, publishStreamResponseObserver, serviceStatus); + streamMediator, + publishStreamResponseObserver, + blockNodeContext, + serviceStatus); // Create a pbj block item final List blockItems = generateBlockItems(1); @@ -276,11 +298,13 @@ public void testBlockItemThrowsParseException() throws InvalidProtocolBufferExce private static class TestProducerBlockItemObserver extends ProducerBlockItemObserver { public TestProducerBlockItemObserver( - StreamMediator> streamMediator, - StreamObserver + final StreamMediator> + streamMediator, + final StreamObserver publishStreamResponseObserver, - ServiceStatus serviceStatus) { - super(streamMediator, publishStreamResponseObserver, serviceStatus); + final BlockNodeContext blockNodeContext, + final ServiceStatus serviceStatus) { + super(streamMediator, publishStreamResponseObserver, blockNodeContext, serviceStatus); } @NonNull From 5d85bcdc7e315a905f33b92b6da494341e987b53 Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Tue, 3 Sep 2024 08:49:44 -0600 Subject: [PATCH 10/12] fix: changed method name from setRunning to stopRunning Signed-off-by: Matt Peterson --- .../java/com/hedera/block/server/ServiceStatus.java | 4 ++-- .../com/hedera/block/server/ServiceStatusImpl.java | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/com/hedera/block/server/ServiceStatus.java b/server/src/main/java/com/hedera/block/server/ServiceStatus.java index 1dc330d6..457e2c9d 100644 --- a/server/src/main/java/com/hedera/block/server/ServiceStatus.java +++ b/server/src/main/java/com/hedera/block/server/ServiceStatus.java @@ -35,9 +35,9 @@ public interface ServiceStatus { /** * Sets the running status of the service. * - * @param running true if the service is running, false otherwise + * @param className the name of the class stopping the service */ - void setRunning(final boolean running); + void stopRunning(final String className); /** * Sets the web server instance. diff --git a/server/src/main/java/com/hedera/block/server/ServiceStatusImpl.java b/server/src/main/java/com/hedera/block/server/ServiceStatusImpl.java index dd3243a1..53377428 100644 --- a/server/src/main/java/com/hedera/block/server/ServiceStatusImpl.java +++ b/server/src/main/java/com/hedera/block/server/ServiceStatusImpl.java @@ -16,6 +16,8 @@ package com.hedera.block.server; +import static java.lang.System.Logger.Level.DEBUG; + import edu.umd.cs.findbugs.annotations.NonNull; import io.helidon.webserver.WebServer; import java.util.concurrent.atomic.AtomicBoolean; @@ -29,6 +31,8 @@ @Singleton public class ServiceStatusImpl implements ServiceStatus { + private final System.Logger LOGGER = System.getLogger(getClass().getName()); + private final AtomicBoolean isRunning = new AtomicBoolean(true); private WebServer webServer; @@ -48,10 +52,11 @@ public boolean isRunning() { /** * Sets the running status of the service. * - * @param running true if the service is running, false otherwise + * @param className the name of the class stopping the service */ - public void setRunning(final boolean running) { - isRunning.set(running); + public void stopRunning(final String className) { + LOGGER.log(DEBUG, String.format("%s set the status to stopped", className)); + isRunning.set(false); } /** From 8c724ec382706aa3f483bc848df5ebfcdc167034 Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Tue, 3 Sep 2024 09:36:20 -0600 Subject: [PATCH 11/12] fix: metric service light refactoring Signed-off-by: Matt Peterson --- .../block/server/BlockStreamService.java | 4 +- .../ConsumerStreamResponseObserver.java | 2 +- .../mediator/LiveStreamMediatorImpl.java | 6 +-- ...icNames.java => BlockNodeMetricTypes.java} | 43 +++++++++++++++++-- .../block/server/metrics/MetricsService.java | 16 ++++++- .../server/metrics/MetricsServiceImpl.java | 28 ++++++++---- .../storage/write/BlockAsDirWriter.java | 2 +- .../producer/ProducerBlockItemObserver.java | 8 ++-- .../BlockStreamServiceIntegrationTest.java | 2 +- .../mediator/LiveStreamMediatorImplTest.java | 2 +- .../server/metrics/MetricsServiceTest.java | 10 ++--- .../ProducerBlockItemObserverTest.java | 2 +- 12 files changed, 94 insertions(+), 31 deletions(-) rename server/src/main/java/com/hedera/block/server/metrics/{BlockNodeMetricNames.java => BlockNodeMetricTypes.java} (62%) diff --git a/server/src/main/java/com/hedera/block/server/BlockStreamService.java b/server/src/main/java/com/hedera/block/server/BlockStreamService.java index 807630b6..009bfc60 100644 --- a/server/src/main/java/com/hedera/block/server/BlockStreamService.java +++ b/server/src/main/java/com/hedera/block/server/BlockStreamService.java @@ -22,8 +22,8 @@ import static com.hedera.block.server.Constants.SINGLE_BLOCK_METHOD_NAME; import static com.hedera.block.server.Translator.fromPbj; import static com.hedera.block.server.Translator.toPbj; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.SingleBlocksNotFound; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.SingleBlocksRetrieved; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.SingleBlocksNotFound; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.SingleBlocksRetrieved; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.ERROR; diff --git a/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java b/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java index da5887d8..25a028c8 100644 --- a/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java +++ b/server/src/main/java/com/hedera/block/server/consumer/ConsumerStreamResponseObserver.java @@ -17,7 +17,7 @@ package com.hedera.block.server.consumer; import static com.hedera.block.server.Translator.fromPbj; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItemsConsumed; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.LiveBlockItemsConsumed; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.ERROR; diff --git a/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java b/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java index e967740e..7691b62b 100644 --- a/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java +++ b/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java @@ -16,9 +16,9 @@ package com.hedera.block.server.mediator; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockStreamMediatorError; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Gauge.Subscribers; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.LiveBlockItems; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.LiveBlockStreamMediatorError; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Gauge.Subscribers; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.ERROR; diff --git a/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java b/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricTypes.java similarity index 62% rename from server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java rename to server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricTypes.java index 094e2de3..c5d968e4 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricNames.java +++ b/server/src/main/java/com/hedera/block/server/metrics/BlockNodeMetricTypes.java @@ -18,19 +18,48 @@ import edu.umd.cs.findbugs.annotations.NonNull; -public final class BlockNodeMetricNames { - private BlockNodeMetricNames() {} - +/** + * The BlockNodeMetricNames class contains the names of the metrics used by the BlockNode. + * + *

These names are used to register the metrics with the metrics service. + */ +public final class BlockNodeMetricTypes { + private BlockNodeMetricTypes() {} + + /** + * Add new counting metrics to this enum to automatically register them with the metrics + * service. + * + *

Each enum value should have a unique grafana label and meaningful description. These + * counters can capture data on standard operations or errors. + */ public enum Counter implements MetricMetadata { // Standard counters + /** The number of live block items received from a producer. */ LiveBlockItemsReceived("live_block_items_received", "Live Block Items Received"), + + /** The number of live block items received before publishing to the RingBuffer. */ LiveBlockItems("live_block_items", "Live BlockItems"), + + /** + * The number of blocks persisted to storage. + * + *

Block items are not counted here, only the blocks. + */ BlocksPersisted("blocks_persisted", "Blocks Persisted"), + + /** The number of live block items consumed from the by each consumer observer. */ LiveBlockItemsConsumed("live_block_items_consumed", "Live Block Items Consumed"), + + /** The number of single blocks retrieved from the singleBlock rpc service. */ SingleBlocksRetrieved("single_blocks_retrieved", "Single Blocks Retrieved"), + + /** The number of single blocks not found via the singleBlock rpc service. */ SingleBlocksNotFound("single_blocks_not_found", "Single Blocks Not Found"), // Error counters + + /** The number of errors encountered by the live block stream mediator. */ LiveBlockStreamMediatorError( "live_block_stream_mediator_error", "Live Block Stream Mediator Error"); @@ -55,7 +84,15 @@ public String description() { } } + /** + * Add new gauge metrics to this enum to automatically register them with the metrics service. + * + *

Each enum value should have a unique grafana label and meaningful description. These + * gauges can capture data on standard operations or errors. + */ public enum Gauge implements MetricMetadata { + + /** The number of subscribers receiving the live block stream. */ Subscribers("subscribers", "Subscribers"); private final String grafanaLabel; diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java index 8cce37f8..205c17e1 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java @@ -22,7 +22,19 @@ /** Use member variables of this class to update metric data for the Hedera Block Node. */ public interface MetricsService { - Counter get(@NonNull BlockNodeMetricNames.Counter key); + /** + * Use this method to get a specific counter for the given metric type. + * + * @param key to get a specific counter + * @return the counter + */ + Counter get(@NonNull BlockNodeMetricTypes.Counter key); - LongGauge get(@NonNull BlockNodeMetricNames.Gauge key); + /** + * Use this method to get a specific gauge for the given metric type. + * + * @param key to get a specific gauge + * @return the gauge + */ + LongGauge get(@NonNull BlockNodeMetricTypes.Gauge key); } diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java index 9207acc0..77631833 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java @@ -33,10 +33,10 @@ public class MetricsServiceImpl implements MetricsService { private static final String CATEGORY = "hedera_block_node"; - private final EnumMap counters = - new EnumMap<>(BlockNodeMetricNames.Counter.class); - private final EnumMap gauges = - new EnumMap<>(BlockNodeMetricNames.Gauge.class); + private final EnumMap counters = + new EnumMap<>(BlockNodeMetricTypes.Counter.class); + private final EnumMap gauges = + new EnumMap<>(BlockNodeMetricTypes.Gauge.class); /** * Create singleton instance of metrics service to be used throughout the application. @@ -46,7 +46,7 @@ public class MetricsServiceImpl implements MetricsService { @Inject public MetricsServiceImpl(@NonNull final Metrics metrics) { // Initialize the counters - for (BlockNodeMetricNames.Counter counter : BlockNodeMetricNames.Counter.values()) { + for (BlockNodeMetricTypes.Counter counter : BlockNodeMetricTypes.Counter.values()) { counters.put( counter, metrics.getOrCreate( @@ -55,7 +55,7 @@ public MetricsServiceImpl(@NonNull final Metrics metrics) { } // Initialize the gauges - for (BlockNodeMetricNames.Gauge gauge : BlockNodeMetricNames.Gauge.values()) { + for (BlockNodeMetricTypes.Gauge gauge : BlockNodeMetricTypes.Gauge.values()) { gauges.put( gauge, metrics.getOrCreate( @@ -64,15 +64,27 @@ public MetricsServiceImpl(@NonNull final Metrics metrics) { } } + /** + * Use this method to get a specific counter for the given metric type. + * + * @param key to get a specific counter + * @return the counter + */ @NonNull @Override - public Counter get(@NonNull BlockNodeMetricNames.Counter key) { + public Counter get(@NonNull BlockNodeMetricTypes.Counter key) { return counters.get(key); } + /** + * Use this method to get a specific gauge for the given metric type. + * + * @param key to get a specific gauge + * @return the gauge + */ @NonNull @Override - public LongGauge get(@NonNull BlockNodeMetricNames.Gauge key) { + public LongGauge get(@NonNull BlockNodeMetricTypes.Gauge key) { return gauges.get(key); } } diff --git a/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java b/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java index d097a4d7..e5c96e75 100644 --- a/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java +++ b/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java @@ -17,7 +17,7 @@ package com.hedera.block.server.persistence.storage.write; import static com.hedera.block.server.Constants.BLOCK_FILE_EXTENSION; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.BlocksPersisted; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.BlocksPersisted; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.ERROR; diff --git a/server/src/main/java/com/hedera/block/server/producer/ProducerBlockItemObserver.java b/server/src/main/java/com/hedera/block/server/producer/ProducerBlockItemObserver.java index 36dd6f6c..18151583 100644 --- a/server/src/main/java/com/hedera/block/server/producer/ProducerBlockItemObserver.java +++ b/server/src/main/java/com/hedera/block/server/producer/ProducerBlockItemObserver.java @@ -18,7 +18,7 @@ import static com.hedera.block.server.Translator.fromPbj; import static com.hedera.block.server.Translator.toPbj; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItemsReceived; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.LiveBlockItemsReceived; import static com.hedera.block.server.producer.Util.getFakeHash; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.DEBUG; @@ -64,9 +64,11 @@ public class ProducerBlockItemObserver * to the upstream producer via the responseStreamObserver. * * @param publisher the block item publisher to used to pass block items to consumers as they - * arrive from the upstream producer + * arrive from the upstream producer. * @param publishStreamResponseObserver the response stream observer to send responses back to - * the upstream producer for each block item processed + * the upstream producer for each block item processed. + * @param blockNodeContext the block node context used to access context objects for the Block + * Node (e.g. - the metrics service). * @param serviceStatus the service status used to determine if the downstream service is * accepting block items. In the event of an unrecoverable exception, it will be used to * stop the web server. diff --git a/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java b/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java index 52a0415e..ef4f985a 100644 --- a/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java @@ -17,7 +17,7 @@ package com.hedera.block.server; import static com.hedera.block.server.Translator.fromPbj; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.LiveBlockItems; import static com.hedera.block.server.producer.Util.getFakeHash; import static com.hedera.block.server.util.PersistTestUtils.generateBlockItems; import static java.lang.System.Logger; diff --git a/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java b/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java index 356687bf..63e1813f 100644 --- a/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java +++ b/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java @@ -17,7 +17,7 @@ package com.hedera.block.server.mediator; import static com.hedera.block.server.Translator.fromPbj; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.LiveBlockItems; import static com.hedera.block.server.util.PersistTestUtils.generateBlockItems; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java index ebdd0381..83e1dab4 100644 --- a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java +++ b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java @@ -16,11 +16,11 @@ package com.hedera.block.server.metrics; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.BlocksPersisted; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItemsConsumed; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.SingleBlocksRetrieved; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Gauge.Subscribers; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.BlocksPersisted; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.LiveBlockItems; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.LiveBlockItemsConsumed; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.SingleBlocksRetrieved; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Gauge.Subscribers; import static org.junit.jupiter.api.Assertions.assertEquals; import com.hedera.block.server.config.BlockNodeContext; diff --git a/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java b/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java index 848cd870..242ef05e 100644 --- a/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java +++ b/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java @@ -17,7 +17,7 @@ package com.hedera.block.server.producer; import static com.hedera.block.server.Translator.fromPbj; -import static com.hedera.block.server.metrics.BlockNodeMetricNames.Counter.LiveBlockItems; +import static com.hedera.block.server.metrics.BlockNodeMetricTypes.Counter.LiveBlockItems; import static com.hedera.block.server.producer.Util.getFakeHash; import static com.hedera.block.server.util.PersistTestUtils.generateBlockItems; import static com.hedera.block.server.util.PersistTestUtils.reverseByteArray; From c0c03be7f575c1ab215f3fb806107e1d39861f84 Mon Sep 17 00:00:00 2001 From: Matt Peterson Date: Tue, 3 Sep 2024 09:52:01 -0600 Subject: [PATCH 12/12] feat: added logging.properties and gradle config to enable Helidon logging Signed-off-by: Matt Peterson --- gradle/modules.properties | 2 ++ server/build.gradle.kts | 1 + server/docker/Dockerfile | 3 ++ server/docker/logging.properties | 32 +++++++++++++++++++ .../com/hedera/block/server/Constants.java | 6 ++++ .../java/com/hedera/block/server/Server.java | 17 ++++++++-- server/src/main/java/module-info.java | 1 + settings.gradle.kts | 1 + 8 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 server/docker/logging.properties diff --git a/gradle/modules.properties b/gradle/modules.properties index bff4c00c..8290bd36 100644 --- a/gradle/modules.properties +++ b/gradle/modules.properties @@ -12,6 +12,8 @@ com.lmax.disruptor=com.lmax:disruptor io.helidon.webserver=io.helidon.webserver:helidon-webserver io.helidon.webserver.grpc=io.helidon.webserver:helidon-webserver-grpc io.helidon.webserver.testing.junit5=io.helidon.webserver.testing.junit5:helidon-webserver-testing-junit5 + +io.helidon.logging=io.helidon.logging:helidon-logging-jul org.antlr.antlr4.runtime=org.antlr:antlr4-runtime com.google.common=com.google.guava:guava diff --git a/server/build.gradle.kts b/server/build.gradle.kts index 7bd25553..322e4b97 100644 --- a/server/build.gradle.kts +++ b/server/build.gradle.kts @@ -29,6 +29,7 @@ mainModuleInfo { annotationProcessor("com.google.auto.service.processor") runtimeOnly("com.swirlds.config.impl") runtimeOnly("org.apache.logging.log4j.slf4j2.impl") + runtimeOnly("io.helidon.logging") } testModuleInfo { diff --git a/server/docker/Dockerfile b/server/docker/Dockerfile index 693784aa..50b1c5ad 100644 --- a/server/docker/Dockerfile +++ b/server/docker/Dockerfile @@ -24,5 +24,8 @@ COPY --from=distributions server-${VERSION}.tar . # Extract the TAR file RUN tar -xvf server-${VERSION}.tar +# Copy the logging properties file +COPY logging.properties logging.properties + # RUN the bin script for starting the server ENTRYPOINT ["/bin/bash", "-c", "/app/server-${VERSION}/bin/server"] diff --git a/server/docker/logging.properties b/server/docker/logging.properties new file mode 100644 index 00000000..91d8f441 --- /dev/null +++ b/server/docker/logging.properties @@ -0,0 +1,32 @@ +# Log Level Values +# +# SEVERE: indicates a critical error or failure +# WARNING: warns of potential issues or errors +# INFO: reports normal operational information +# CONFIG: provides configuration-related information +# FINE: provides detailed debugging information +# FINER: provides finer-grained debugging information +# FINEST: provides the most detailed debugging information + +# Set the default logging level +.level=INFO + +# Helidon loggers +io.helidon.webserver.level=SEVERE +io.helidon.config.level=SEVERE +io.helidon.security.level=INFO +io.helidon.common.level=INFO + +# Configure the app log level +#com.hedera.block.level=FINE +#com.hedera.block.server.level=FINE + +# Configure specific loggers +#com.hedera.block.server.mediator.LiveStreamMediatorImpl.level=FINE +#com.hedera.block.server.persistence.storage.write.BlockAsDirWriter.level=FINE +#com.hedera.block.server.producer.ProducerBlockItemObserver.level=FINE + +# Console handler configuration +handlers = java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level = FINE +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter diff --git a/server/src/main/java/com/hedera/block/server/Constants.java b/server/src/main/java/com/hedera/block/server/Constants.java index 8fbd6900..9f12b594 100644 --- a/server/src/main/java/com/hedera/block/server/Constants.java +++ b/server/src/main/java/com/hedera/block/server/Constants.java @@ -25,6 +25,12 @@ private Constants() {} /** Constant mapped to the application.properties file in resources with default values */ @NonNull public static final String APPLICATION_PROPERTIES = "app.properties"; + /** + * Constant mapped to the Helidon logging.properties file in the docker directory with default + * values. + */ + @NonNull public static final String LOGGING_PROPERTIES = "logging.properties"; + /** Constant mapped to the name of the service in the .proto file */ @NonNull public static final String SERVICE_NAME = "BlockStreamService"; diff --git a/server/src/main/java/com/hedera/block/server/Server.java b/server/src/main/java/com/hedera/block/server/Server.java index 48b39490..1365bac7 100644 --- a/server/src/main/java/com/hedera/block/server/Server.java +++ b/server/src/main/java/com/hedera/block/server/Server.java @@ -16,6 +16,9 @@ package com.hedera.block.server; +import static com.hedera.block.server.Constants.APPLICATION_PROPERTIES; +import static com.hedera.block.server.Constants.LOGGING_PROPERTIES; +import static io.helidon.config.ConfigSources.file; import static java.lang.System.Logger; import static java.lang.System.Logger.Level.INFO; @@ -24,8 +27,10 @@ import com.swirlds.config.extensions.sources.ClasspathFileConfigSource; import com.swirlds.config.extensions.sources.SystemEnvironmentConfigSource; import com.swirlds.config.extensions.sources.SystemPropertiesConfigSource; +import io.helidon.config.Config; import java.io.IOException; import java.nio.file.Path; +import java.nio.file.Paths; /** Main class for the block node server */ public class Server { @@ -43,14 +48,20 @@ private Server() {} public static void main(final String[] args) throws IOException { LOGGER.log(INFO, "Starting BlockNode Server"); + // Set the global configuration + final Config config = + Config.builder() + .sources(file(Paths.get("/app", LOGGING_PROPERTIES)).optional()) + .build(); + + Config.global(config); + // Init BlockNode Configuration Configuration configuration = ConfigurationBuilder.create() .withSource(SystemEnvironmentConfigSource.getInstance()) .withSource(SystemPropertiesConfigSource.getInstance()) - .withSource( - new ClasspathFileConfigSource( - Path.of(Constants.APPLICATION_PROPERTIES))) + .withSources(new ClasspathFileConfigSource(Path.of(APPLICATION_PROPERTIES))) .autoDiscoverExtensions() .build(); diff --git a/server/src/main/java/module-info.java b/server/src/main/java/module-info.java index 4a938f30..63352467 100644 --- a/server/src/main/java/module-info.java +++ b/server/src/main/java/module-info.java @@ -26,6 +26,7 @@ requires dagger; requires io.grpc.stub; requires io.helidon.common; + requires io.helidon.config; requires io.helidon.webserver.grpc; requires io.helidon.webserver; requires javax.inject; diff --git a/settings.gradle.kts b/settings.gradle.kts index b195e4fa..4770f346 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -44,6 +44,7 @@ dependencyResolutionManagement { // Compile time dependencies version("io.helidon.webserver.http2", "4.1.0") version("io.helidon.webserver.grpc", "4.1.0") + version("io.helidon.logging", "4.1.0") version("com.lmax.disruptor", "4.0.0") version("com.github.spotbugs.annotations", "4.7.3") version("com.swirlds.metrics.api", swirldsVersion)