Skip to content

Commit

Permalink
Merge pull request #4435 from chimp1984/improve-network-statistics
Browse files Browse the repository at this point in the history
Add more detailed network statistics
  • Loading branch information
sqrrm authored Aug 29, 2020
2 parents 591d68a + 5ac1f6e commit 38f9d25
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 36 deletions.
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 @@ -1129,7 +1129,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 @@ -1142,7 +1143,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}";
}

}

0 comments on commit 38f9d25

Please sign in to comment.