Init BsqBlocks metric

This commit is contained in:
Florian Reimair 2019-02-15 18:49:08 +01:00
parent fa45916582
commit 438c0dcf43
No known key found for this signature in database
GPG Key ID: 05634D8D7A7954C8
4 changed files with 148 additions and 13 deletions

View File

@ -20,6 +20,7 @@ package bisq.monitor;
import bisq.monitor.metric.MarketStats;
import bisq.monitor.metric.P2PMarketStats;
import bisq.monitor.metric.P2PNetworkLoad;
import bisq.monitor.metric.P2PSeedNodeBSQBlocksSnapshot;
import bisq.monitor.metric.P2PSeedNodeSnapshot;
import bisq.monitor.metric.P2PRoundTripTime;
import bisq.monitor.metric.PriceNodeStats;
@ -97,6 +98,7 @@ public class Monitor {
metrics.add(new P2PMarketStats(graphiteReporter));
metrics.add(new PriceNodeStats(graphiteReporter));
metrics.add(new MarketStats(graphiteReporter));
metrics.add(new P2PSeedNodeBSQBlocksSnapshot(graphiteReporter));
// prepare configuration reload
// Note that this is most likely only work on Linux

View File

@ -61,7 +61,7 @@ public class P2PMarketStats extends P2PSeedNodeSnapshot {
}
@Override
public synchronized void log(ProtectedStoragePayload message) {
public synchronized void log(Object message) {
if(message instanceof OfferPayload) {
OfferPayload currentMessage = (OfferPayload) message;

View File

@ -0,0 +1,123 @@
/*
* This file is part of Bisq.
*
* bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.monitor.metric;
import bisq.monitor.Reporter;
import bisq.core.dao.node.messages.GetBlocksRequest;
import bisq.core.dao.node.messages.GetBlocksResponse;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.network.Connection;
import bisq.network.p2p.network.MessageListener;
import bisq.common.proto.network.NetworkEnvelope;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import lombok.extern.slf4j.Slf4j;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Contacts a list of hosts and asks them for all the data excluding persisted messages. The
* answers are then compiled into buckets of message types. Based on these
* buckets, the Metric reports (for each host) the message types observed and
* their number.
*
* @author Florian Reimair
*
*/
@Slf4j
public class P2PSeedNodeBSQBlocksSnapshot extends P2PSeedNodeSnapshot implements MessageListener {
Statistics statistics;
Map<NodeAddress, Statistics> blocksPerHost = new ConcurrentHashMap<>();
/**
* Efficient way to count message occurrences.
*/
private class Counter {
private final int value;
Counter(int value) {
this.value = value;
}
int value() {
return value;
}
}
/**
* Use a counter to do statistics.
*/
private class MyStatistics implements Statistics<Counter> {
private Map<String, Counter> buckets = new HashMap<>();
@Override
public Statistics create() {
return new MyStatistics();
}
@Override
public synchronized void log(Object value) {
buckets.putIfAbsent("BsqBlocks", new Counter((Integer) value));
}
@Override
public Map<String, Counter> values() {
return buckets;
}
@Override
public synchronized void reset() {
buckets.clear();
}
}
public P2PSeedNodeBSQBlocksSnapshot(Reporter reporter) {
super(reporter);
statistics = new MyStatistics();
}
protected NetworkEnvelope getFreshRequest(NodeAddress nodeAddress) {
return new GetBlocksRequest(0, 0, nodeAddress);
}
@Override
public boolean treatMessage(NetworkEnvelope networkEnvelope, Connection connection) {
if (networkEnvelope instanceof GetBlocksResponse) {
Statistics result = this.statistics.create();
result.log(((GetBlocksResponse) networkEnvelope).getBlocks().size());
checkNotNull(connection.getPeersNodeAddressProperty(),
"although the property is nullable, we need it to not be null");
blocksPerHost.put(connection.getPeersNodeAddressProperty().getValue(), result);
return true;
}
return false;
}
}

View File

@ -91,7 +91,7 @@ public class P2PSeedNodeSnapshot extends Metric implements MessageListener {
Statistics create();
void log(ProtectedStoragePayload message);
void log(Object message);
Map<String, T> values();
@ -126,7 +126,7 @@ public class P2PSeedNodeSnapshot extends Metric implements MessageListener {
}
@Override
public synchronized void log(ProtectedStoragePayload message) {
public synchronized void log(Object message) {
// For logging different data types
String className = message.getClass().getSimpleName();
@ -174,8 +174,7 @@ public class P2PSeedNodeSnapshot extends Metric implements MessageListener {
NodeAddress target = OnionParser.getNodeAddress(current);
// do the data request
SettableFuture<Connection> future = networkNode.sendMessage(target,
new PreliminaryGetDataRequest(new Random().nextInt(), hashes));
SettableFuture<Connection> future = networkNode.sendMessage(target, getFreshRequest(networkNode.getNodeAddress()));
Futures.addCallback(future, new FutureCallback<>() {
@Override
@ -211,6 +210,11 @@ public class P2PSeedNodeSnapshot extends Metric implements MessageListener {
report();
}
protected NetworkEnvelope getFreshRequest(NodeAddress nodeAddress) {
int nonce = new Random().nextInt();
return new PreliminaryGetDataRequest(nonce, hashes);
}
/**
* Report all the stuff. Uses the configured reporter directly.
*/
@ -261,6 +265,18 @@ public class P2PSeedNodeSnapshot extends Metric implements MessageListener {
@Override
public void onMessage(NetworkEnvelope networkEnvelope, Connection connection) {
if(treatMessage(networkEnvelope, connection)) {
connection.shutDown(CloseConnectionReason.APP_SHUT_DOWN);
gate.proceed();
} else if (networkEnvelope instanceof CloseConnectionMessage) {
gate.unlock();
} else {
log.warn("Got an unexpected message of type <{}>",
networkEnvelope.getClass().getSimpleName());
}
}
protected boolean treatMessage(NetworkEnvelope networkEnvelope, Connection connection) {
if (networkEnvelope instanceof GetDataResponse) {
Statistics result = this.statistics.create();
@ -295,14 +311,8 @@ public class P2PSeedNodeSnapshot extends Metric implements MessageListener {
checkNotNull(connection.getPeersNodeAddressProperty(),
"although the property is nullable, we need it to not be null");
bucketsPerHost.put(connection.getPeersNodeAddressProperty().getValue(), result);
connection.shutDown(CloseConnectionReason.APP_SHUT_DOWN);
gate.proceed();
} else if (networkEnvelope instanceof CloseConnectionMessage) {
gate.unlock();
} else {
log.warn("Got a message of type <{}>, expected <GetDataResponse>",
networkEnvelope.getClass().getSimpleName());
return true;
}
return false;
}
}