Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more detailed network statistics #4435

Merged
merged 8 commits into from
Aug 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public SettableFuture<Tuple2<Map<String, Long>, Map<String, MarketPrice>>> reque
final String baseUrl = provider.getBaseUrl();
final SettableFuture<Tuple2<Map<String, Long>, Map<String, MarketPrice>>> resultFuture = SettableFuture.create();
ListenableFuture<Tuple2<Map<String, Long>, Map<String, MarketPrice>>> future = executorService.submit(() -> {
Thread.currentThread().setName("PriceRequest-" + provider.toString());
Thread.currentThread().setName("PriceRequest-" + provider.getBaseUrl());
return provider.getAll();
});

Expand Down
6 changes: 4 additions & 2 deletions core/src/main/resources/i18n/displayStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1124,7 +1124,8 @@ settings.net.p2PPeersLabel=Connected peers
settings.net.onionAddressColumn=Onion address
settings.net.creationDateColumn=Established
settings.net.connectionTypeColumn=In/Out
settings.net.totalTrafficLabel=Total traffic
settings.net.sentDataLabel=Sent data statistics
settings.net.receivedDataLabel=Received data statistics
settings.net.roundTripTimeColumn=Roundtrip
settings.net.sentBytesColumn=Sent
settings.net.receivedBytesColumn=Received
Expand All @@ -1137,7 +1138,8 @@ settings.net.heightColumn=Height

settings.net.needRestart=You need to restart the application to apply that change.\nDo you want to do that now?
settings.net.notKnownYet=Not known yet...
settings.net.sentReceived=Sent: {0}, received: {1}
settings.net.sentData=Sent data: {0}, {1} messages, {2} messages/sec
settings.net.receivedData=Received data: {0}, {1} messages, {2} messages/sec
settings.net.ips=[IP address:port | host name:port | onion address:port] (comma separated). Port can be omitted if default is used (8333).
settings.net.seedNode=Seed node
settings.net.directPeer=Peer (direct)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,13 @@
</TableView>
</VBox>

<BisqTextField fx:id="totalTrafficTextField" GridPane.rowIndex="7" editable="false"
<BisqTextField fx:id="sentDataTextField" GridPane.rowIndex="7" editable="false"
focusTraversable="false" labelFloat="true"/>

<AutoTooltipButton fx:id="openTorSettingsButton" GridPane.rowIndex="8" GridPane.columnIndex="0"/>
<BisqTextField fx:id="receivedDataTextField" GridPane.rowIndex="8" editable="false"
focusTraversable="false" labelFloat="true"/>

<AutoTooltipButton fx:id="openTorSettingsButton" GridPane.rowIndex="9" GridPane.columnIndex="0"/>

<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" minWidth="500"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static javafx.beans.binding.Bindings.createStringBinding;

@FxmlView
public class NetworkSettingsView extends ActivatableView<GridPane, Void> {

Expand All @@ -83,7 +85,7 @@ public class NetworkSettingsView extends ActivatableView<GridPane, Void> {
@FXML
InputTextField btcNodesInputTextField;
@FXML
TextField onionAddress, totalTrafficTextField;
TextField onionAddress, sentDataTextField, receivedDataTextField;
@FXML
Label p2PPeersLabel, bitcoinPeersLabel;
@FXML
Expand Down Expand Up @@ -175,7 +177,8 @@ public void initialize() {
onionAddressColumn.getStyleClass().add("first-column");
creationDateColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.creationDateColumn")));
connectionTypeColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.connectionTypeColumn")));
totalTrafficTextField.setPromptText(Res.get("settings.net.totalTrafficLabel"));
sentDataTextField.setPromptText(Res.get("settings.net.sentDataLabel"));
receivedDataTextField.setPromptText(Res.get("settings.net.receivedDataLabel"));
roundTripTimeColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.roundTripTimeColumn")));
sentBytesColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.sentBytesColumn")));
receivedBytesColumn.setGraphic(new AutoTooltipLabel(Res.get("settings.net.receivedBytesColumn")));
Expand Down Expand Up @@ -297,11 +300,18 @@ public void activate() {
Res.get("settings.net.notKnownYet") :
nodeAddress.getFullAddress()));
numP2PPeersSubscription = EasyBind.subscribe(p2PService.getNumConnectedPeers(), numPeers -> updateP2PTable());
totalTrafficTextField.textProperty().bind(EasyBind.combine(Statistic.totalSentBytesProperty(),
Statistic.totalReceivedBytesProperty(),
(sent, received) -> Res.get("settings.net.sentReceived",
FormattingUtils.formatBytes((long) sent),
FormattingUtils.formatBytes((long) received))));

sentDataTextField.textProperty().bind(createStringBinding(() -> Res.get("settings.net.sentData",
FormattingUtils.formatBytes(Statistic.totalSentBytesProperty().get()),
Statistic.numTotalSentMessagesProperty().get(),
Statistic.numTotalSentMessagesPerSecProperty().get()),
Statistic.numTotalSentMessagesPerSecProperty()));

receivedDataTextField.textProperty().bind(createStringBinding(() -> Res.get("settings.net.receivedData",
FormattingUtils.formatBytes(Statistic.totalReceivedBytesProperty().get()),
Statistic.numTotalReceivedMessagesProperty().get(),
Statistic.numTotalReceivedMessagesPerSecProperty().get()),
Statistic.numTotalReceivedMessagesPerSecProperty()));

bitcoinSortedList.comparatorProperty().bind(bitcoinPeersTableView.comparatorProperty());
bitcoinPeersTableView.setItems(bitcoinSortedList);
Expand Down Expand Up @@ -338,7 +348,8 @@ public void deactivate() {
if (numP2PPeersSubscription != null)
numP2PPeersSubscription.unsubscribe();

totalTrafficTextField.textProperty().unbind();
sentDataTextField.textProperty().unbind();
receivedDataTextField.textProperty().unbind();

bitcoinSortedList.comparatorProperty().unbind();
p2pSortedList.comparatorProperty().unbind();
Expand Down
113 changes: 90 additions & 23 deletions p2p/src/main/java/bisq/network/p2p/network/Statistic.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,40 +20,93 @@
import bisq.common.UserThread;
import bisq.common.proto.network.NetworkEnvelope;

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleLongProperty;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import lombok.extern.slf4j.Slf4j;

/**
* Network statistics per connection. As we are also interested in total network statistics
* we use static properties to get traffic of all connections combined.
*/
@Slf4j
public class Statistic {

///////////////////////////////////////////////////////////////////////////////////////////
// Static
///////////////////////////////////////////////////////////////////////////////////////////


private final static long startTime = System.currentTimeMillis();
private final static LongProperty totalSentBytes = new SimpleLongProperty(0);
private final static LongProperty totalReceivedBytes = new SimpleLongProperty(0);

public static long getTotalSentBytes() {
return totalSentBytes.get();
private final static Map<String, Integer> totalReceivedMessages = new ConcurrentHashMap<>();
private final static Map<String, Integer> totalSentMessages = new ConcurrentHashMap<>();
private final static LongProperty numTotalSentMessages = new SimpleLongProperty(0);
private final static DoubleProperty numTotalSentMessagesPerSec = new SimpleDoubleProperty(0);
private final static LongProperty numTotalReceivedMessages = new SimpleLongProperty(0);
private final static DoubleProperty numTotalReceivedMessagesPerSec = new SimpleDoubleProperty(0);

static {
UserThread.runPeriodically(() -> {
numTotalSentMessages.set(totalSentMessages.values().stream().mapToInt(Integer::intValue).sum());
numTotalReceivedMessages.set(totalReceivedMessages.values().stream().mapToInt(Integer::intValue).sum());

long passed = (System.currentTimeMillis() - startTime) / 1000;
numTotalSentMessagesPerSec.set(((double) numTotalSentMessages.get()) / passed);
numTotalReceivedMessagesPerSec.set(((double) numTotalReceivedMessages.get()) / passed);
}, 1);

// We log statistics every minute
UserThread.runPeriodically(() -> {
log.info("Network statistics:\n" +
"Bytes sent: {} kb;\n" +
"Number of sent messages/Sent messages: {} / {};\n" +
"Number of sent messages per sec: {};\n" +
"Bytes received: {} kb\n" +
"Number of received messages/Received messages: {} / {};\n" +
"Number of received messages per sec: {};",
totalSentBytes.get() / 1024d,
numTotalSentMessages.get(), totalSentMessages,
numTotalSentMessagesPerSec.get(),
totalReceivedBytes.get() / 1024d,
numTotalReceivedMessages.get(), totalReceivedMessages,
numTotalReceivedMessagesPerSec.get());
}, 60);
}

public static LongProperty totalSentBytesProperty() {
return totalSentBytes;
}

public static long getTotalReceivedBytes() {
return totalReceivedBytes.get();
}

public static LongProperty totalReceivedBytesProperty() {
return totalReceivedBytes;
}

public static LongProperty numTotalSentMessagesProperty() {
return numTotalSentMessages;
}

public static DoubleProperty numTotalSentMessagesPerSecProperty() {
return numTotalSentMessagesPerSec;
}

public static LongProperty numTotalReceivedMessagesProperty() {
return numTotalReceivedMessages;
}

public static DoubleProperty numTotalReceivedMessagesPerSecProperty() {
return numTotalReceivedMessagesPerSec;
}


///////////////////////////////////////////////////////////////////////////////////////////
// Instance fields
Expand All @@ -72,49 +125,61 @@ public static LongProperty totalReceivedBytesProperty() {
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////

public Statistic() {
Statistic() {
creationDate = new Date();
}

///////////////////////////////////////////////////////////////////////////////////////////
// Update, increment
///////////////////////////////////////////////////////////////////////////////////////////

public void updateLastActivityTimestamp() {
void updateLastActivityTimestamp() {
UserThread.execute(() -> lastActivityTimestamp = System.currentTimeMillis());
}

public void addSentBytes(int value) {
void addSentBytes(int value) {
UserThread.execute(() -> {
sentBytes.set(sentBytes.get() + value);
totalSentBytes.set(totalSentBytes.get() + value);
});
}

public void addReceivedBytes(int value) {
void addReceivedBytes(int value) {
UserThread.execute(() -> {
receivedBytes.set(receivedBytes.get() + value);
totalReceivedBytes.set(totalReceivedBytes.get() + value);
});
}

// TODO would need msg inspection to get useful information...
public void addReceivedMessage(NetworkEnvelope networkEnvelope) {
void addReceivedMessage(NetworkEnvelope networkEnvelope) {
String messageClassName = networkEnvelope.getClass().getSimpleName();
int counter = 1;
if (receivedMessages.containsKey(messageClassName))
if (receivedMessages.containsKey(messageClassName)) {
counter = receivedMessages.get(messageClassName) + 1;

}
receivedMessages.put(messageClassName, counter);

counter = 1;
if (totalReceivedMessages.containsKey(messageClassName)) {
counter = totalReceivedMessages.get(messageClassName) + 1;
}
totalReceivedMessages.put(messageClassName, counter);
}

public void addSentMessage(NetworkEnvelope networkEnvelope) {
void addSentMessage(NetworkEnvelope networkEnvelope) {
String messageClassName = networkEnvelope.getClass().getSimpleName();
int counter = 1;
if (sentMessages.containsKey(messageClassName))
if (sentMessages.containsKey(messageClassName)) {
counter = sentMessages.get(messageClassName) + 1;

}
sentMessages.put(messageClassName, counter);

counter = 1;
if (totalSentMessages.containsKey(messageClassName)) {
counter = totalSentMessages.get(messageClassName) + 1;
}
totalSentMessages.put(messageClassName, counter);
}

public void setRoundTripTime(int roundTripTime) {
Expand Down Expand Up @@ -160,11 +225,13 @@ public IntegerProperty roundTripTimeProperty() {
@Override
public String toString() {
return "Statistic{" +
"creationDate=" + creationDate +
", lastActivityTimestamp=" + lastActivityTimestamp +
", sentBytes=" + sentBytes +
", receivedBytes=" + receivedBytes +
'}';
"\n creationDate=" + creationDate +
",\n lastActivityTimestamp=" + lastActivityTimestamp +
",\n sentBytes=" + sentBytes +
",\n receivedBytes=" + receivedBytes +
",\n receivedMessages=" + receivedMessages +
",\n sentMessages=" + sentMessages +
",\n roundTripTime=" + roundTripTime +
"\n}";
}

}