diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManager.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManager.java index a449c0ad7a..879672eb31 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManager.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManager.java @@ -17,6 +17,10 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.request.SubscriptionType; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.request.UnsubscribeRequest; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.response.SubscriptionResponse; +import tech.pegasys.pantheon.metrics.Counter; +import tech.pegasys.pantheon.metrics.LabelledMetric; +import tech.pegasys.pantheon.metrics.MetricCategory; +import tech.pegasys.pantheon.metrics.MetricsSystem; import java.util.List; import java.util.Map; @@ -45,6 +49,23 @@ public class SubscriptionManager extends AbstractVerticle { private final AtomicLong subscriptionCounter = new AtomicLong(0); private final Map subscriptions = new ConcurrentHashMap<>(); private final SubscriptionBuilder subscriptionBuilder = new SubscriptionBuilder(); + private final LabelledMetric subscribeCounter; + private final LabelledMetric unsubscribeCounter; + + public SubscriptionManager(final MetricsSystem metricsSystem) { + subscribeCounter = + metricsSystem.createLabelledCounter( + MetricCategory.RPC, + "subscription_subscribe_total", + "Total number of subscriptions", + "type"); + unsubscribeCounter = + metricsSystem.createLabelledCounter( + MetricCategory.RPC, + "subscription_unsubscribe_total", + "Total number of unsubscriptions", + "type"); + } @Override public void start() { @@ -53,6 +74,7 @@ public void start() { public Long subscribe(final SubscribeRequest request) { LOG.debug("Subscribe request {}", request); + subscribeCounter.labels(request.getSubscriptionType().getCode()).inc(); final long subscriptionId = subscriptionCounter.incrementAndGet(); final Subscription subscription = @@ -79,7 +101,10 @@ public boolean unsubscribe(final UnsubscribeRequest request) { } private void destroySubscription(final long subscriptionId) { - subscriptions.remove(subscriptionId); + final Subscription removed = subscriptions.remove(subscriptionId); + if (removed != null) { + unsubscribeCounter.labels(removed.getSubscriptionType().getCode()).inc(); + } } private void removeSubscriptions(final Message message) { diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketHostWhitelistTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketHostWhitelistTest.java index 774f749bb5..59c524cbbc 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketHostWhitelistTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketHostWhitelistTest.java @@ -19,6 +19,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.JsonRpcMethod; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.methods.WebSocketMethodsFactory; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.SubscriptionManager; +import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; import java.net.InetSocketAddress; import java.util.Arrays; @@ -65,7 +66,9 @@ public void initServerAndClient() { vertx = Vertx.vertx(); final Map websocketMethods = - new WebSocketMethodsFactory(new SubscriptionManager(), new HashMap<>()).methods(); + new WebSocketMethodsFactory( + new SubscriptionManager(new NoOpMetricsSystem()), new HashMap<>()) + .methods(); webSocketRequestHandlerSpy = spy(new WebSocketRequestHandler(vertx, websocketMethods)); websocketService = diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketServiceLoginTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketServiceLoginTest.java index 2641132fbd..25b75245e6 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketServiceLoginTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketServiceLoginTest.java @@ -19,6 +19,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.JsonRpcMethod; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.methods.WebSocketMethodsFactory; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.SubscriptionManager; +import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; import java.net.URISyntaxException; import java.nio.file.Paths; @@ -74,7 +75,9 @@ public void before() throws URISyntaxException { websocketConfiguration.setHostsWhitelist(Collections.singleton("*")); final Map websocketMethods = - new WebSocketMethodsFactory(new SubscriptionManager(), new HashMap<>()).methods(); + new WebSocketMethodsFactory( + new SubscriptionManager(new NoOpMetricsSystem()), new HashMap<>()) + .methods(); webSocketRequestHandlerSpy = spy(new WebSocketRequestHandler(vertx, websocketMethods)); websocketService = diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketServiceTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketServiceTest.java index 8438630e11..9c4d4480f6 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketServiceTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/WebSocketServiceTest.java @@ -19,6 +19,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods.JsonRpcMethod; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.methods.WebSocketMethodsFactory; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.SubscriptionManager; +import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; import java.util.Arrays; import java.util.Collections; @@ -60,7 +61,9 @@ public void before() { websocketConfiguration.setHostsWhitelist(Collections.singleton("*")); final Map websocketMethods = - new WebSocketMethodsFactory(new SubscriptionManager(), new HashMap<>()).methods(); + new WebSocketMethodsFactory( + new SubscriptionManager(new NoOpMetricsSystem()), new HashMap<>()) + .methods(); webSocketRequestHandlerSpy = spy(new WebSocketRequestHandler(vertx, websocketMethods)); websocketService = diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/methods/EthSubscribeIntegrationTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/methods/EthSubscribeIntegrationTest.java index e35e9af5cb..ed83b2c77f 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/methods/EthSubscribeIntegrationTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/methods/EthSubscribeIntegrationTest.java @@ -20,6 +20,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.SubscriptionManager; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.request.SubscriptionType; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.syncing.SyncingSubscription; +import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; import java.util.HashMap; import java.util.List; @@ -49,7 +50,7 @@ public class EthSubscribeIntegrationTest { @Before public void before() { vertx = Vertx.vertx(); - subscriptionManager = new SubscriptionManager(); + subscriptionManager = new SubscriptionManager(new NoOpMetricsSystem()); webSocketMethodsFactory = new WebSocketMethodsFactory(subscriptionManager, new HashMap<>()); webSocketRequestHandler = new WebSocketRequestHandler(vertx, webSocketMethodsFactory.methods()); } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/methods/EthUnsubscribeIntegrationTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/methods/EthUnsubscribeIntegrationTest.java index feae0f381b..bf065eb72b 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/methods/EthUnsubscribeIntegrationTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/methods/EthUnsubscribeIntegrationTest.java @@ -19,6 +19,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.SubscriptionManager; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.request.SubscribeRequest; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.request.SubscriptionType; +import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; import java.util.HashMap; @@ -45,7 +46,7 @@ public class EthUnsubscribeIntegrationTest { @Before public void before() { vertx = Vertx.vertx(); - subscriptionManager = new SubscriptionManager(); + subscriptionManager = new SubscriptionManager(new NoOpMetricsSystem()); webSocketMethodsFactory = new WebSocketMethodsFactory(subscriptionManager, new HashMap<>()); webSocketRequestHandler = new WebSocketRequestHandler(vertx, webSocketMethodsFactory.methods()); } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManagerSendMessageTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManagerSendMessageTest.java index afea27d6c3..389f5a8cc3 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManagerSendMessageTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManagerSendMessageTest.java @@ -19,6 +19,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.request.SubscribeRequest; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.request.SubscriptionType; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.response.SubscriptionResponse; +import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; import java.util.UUID; @@ -42,7 +43,7 @@ public class SubscriptionManagerSendMessageTest { @Before public void before(final TestContext context) { vertx = Vertx.vertx(); - subscriptionManager = new SubscriptionManager(); + subscriptionManager = new SubscriptionManager(new NoOpMetricsSystem()); vertx.deployVerticle(subscriptionManager, context.asyncAssertSuccess()); } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManagerTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManagerTest.java index 3bb21bfd18..8a23439660 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManagerTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/websocket/subscription/SubscriptionManagerTest.java @@ -24,6 +24,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.request.SubscriptionType; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.request.UnsubscribeRequest; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.subscription.syncing.SyncingSubscription; +import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; import java.util.List; import java.util.UUID; @@ -42,7 +43,7 @@ public class SubscriptionManagerTest { @Before public void before() { - subscriptionManager = new SubscriptionManager(); + subscriptionManager = new SubscriptionManager(new NoOpMetricsSystem()); } @Test diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java index 41cfd0277c..c4c1f630e5 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java @@ -503,7 +503,7 @@ private Map jsonRpcMethods( private SubscriptionManager createSubscriptionManager( final Vertx vertx, final TransactionPool transactionPool) { - final SubscriptionManager subscriptionManager = new SubscriptionManager(); + final SubscriptionManager subscriptionManager = new SubscriptionManager(metricsSystem); final PendingTransactionSubscriptionService pendingTransactions = new PendingTransactionSubscriptionService(subscriptionManager); final PendingTransactionDroppedSubscriptionService pendingTransactionsRemoved =