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

Various monitor improvements #4787

Merged
merged 27 commits into from
Nov 18, 2020
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5c7aa80
Add deviation to persistent warnings/alerts
chimp1984 Nov 4, 2020
850f73a
Fix formatting
chimp1984 Nov 4, 2020
4d17e98
Update COMMIT_HASH to 04440f95 (after merged master)
chimp1984 Nov 4, 2020
ac955e1
Reduce TTL for ack and mailbox messages
chimp1984 Nov 4, 2020
b09ebde
Update COMMIT_HASH to fd2a04a2
chimp1984 Nov 4, 2020
012c54c
Fix log at startup
chimp1984 Nov 4, 2020
f10d231
Log when we remove expired entries
chimp1984 Nov 4, 2020
4becece
Increase MAX_PERMITTED_MESSAGE_SIZE to 15 MB, increase SOCKET_TIMEOUT…
chimp1984 Nov 4, 2020
b002c93
Increase SOCKET_TIMEOUT to 6 min
chimp1984 Nov 4, 2020
a1c8474
Add comments, revert TTL change at AckMessage as it has no effect anyway
chimp1984 Nov 4, 2020
33e378a
Update COMMIT_HASH to fec8f6e3
chimp1984 Nov 4, 2020
16880b2
Change deviation limits for OfferPayload
chimp1984 Nov 8, 2020
86a853b
Set response time only in non error case
chimp1984 Nov 8, 2020
a056542
Add historical data for error msg
chimp1984 Nov 8, 2020
1eca9df
Use dash for empty filteredSeedNodes value
chimp1984 Nov 8, 2020
5e41569
Add hasError util method
chimp1984 Nov 8, 2020
04ab507
Update COMMIT_HASH to 627888f0
chimp1984 Nov 8, 2020
86a2045
Fix wrong kb display
chimp1984 Nov 9, 2020
69802e2
Reduce timeout
chimp1984 Nov 9, 2020
bb095d4
Increase timout to 90 sec
chimp1984 Nov 10, 2020
6a2583d
Decrease deviationTolerance for numAllConnectionsLostEvents
chimp1984 Nov 10, 2020
1b7c1ce
Only reset numAllConnectionsLostEvents if we have nodes connected
chimp1984 Nov 10, 2020
2486bd5
Shut down if more then 1 all connections lost events
chimp1984 Nov 10, 2020
8bc78c8
Cleanup tor dir if all connections lost
chimp1984 Nov 10, 2020
2b80776
Update commit hash to 7f83d1b3
chimp1984 Nov 10, 2020
ee5fca9
Revert timeout changes and MAX_PERMITTED_MESSAGE_SIZE change
chimp1984 Nov 12, 2020
ccfcc35
Clean tor dir at startup
chimp1984 Nov 18, 2020
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
2 changes: 1 addition & 1 deletion common/src/main/java/bisq/common/setup/CommonSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
public class CommonSetup {

public static void setup(Config config, GracefulShutDownHandler gracefulShutDownHandler) {
AsciiLogo.showAsciiLogo();
setupLog(config);
AsciiLogo.showAsciiLogo();
Version.setBaseCryptoNetworkId(config.baseCurrencyNetwork.ordinal());
Version.printVersion();
maybePrintPathOfCodeSource();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void request() {
}

private void onTimeOut() {
errorMessageHandler.handleErrorMessage("Timeout got triggered (" + TIMEOUT_SEC + " sec)");
errorMessageHandler.handleErrorMessage("Request timeout");
shutDown();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public enum InventoryItem {
// Percentage deviation
OfferPayload("OfferPayload",
true,
new DeviationByPercentage(0.9, 1.1, 0.95, 1.05), 5),
new DeviationByPercentage(0.8, 1.2, 0.9, 1.1), 5),
MailboxStoragePayload("MailboxStoragePayload",
true,
new DeviationByPercentage(0.9, 1.1, 0.95, 1.05), 2),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
@Getter
public class RequestInfo {
// Carries latest commit hash of feature changes (not latest commit as that is then the commit for editing that field)
public static final String COMMIT_HASH = "d789282b";
public static final String COMMIT_HASH = "fec8f6e3";

private final long requestStartTime;
@Setter
Expand All @@ -56,6 +56,10 @@ public String getValue(InventoryItem inventoryItem) {
null;
}

public boolean hasError() {
return errorMessage != null && !errorMessage.isEmpty();
}

@Value
public static class Data {
private final String value;
Expand Down
6 changes: 3 additions & 3 deletions inventory/src/main/java/bisq/inventory/InventoryMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,16 @@ private void processResponse(NodeAddress nodeAddress,
RequestInfo requestInfo,
@Nullable Map<InventoryItem, String> result,
@Nullable String errorMessage) {
if (errorMessage != null) {
if (errorMessage != null && !errorMessage.isEmpty()) {
log.warn("Error at connection to peer {}: {}", nodeAddress, errorMessage);
requestInfo.setErrorMessage(errorMessage);
} else {
requestInfo.setResponseTime(System.currentTimeMillis());
}

boolean ignoreDeviationAtStartup;
if (result != null) {
log.info("nodeAddress={}, result={}", nodeAddress, result.toString());
long responseTime = System.currentTimeMillis();
requestInfo.setResponseTime(responseTime);

// If seed just started up we ignore the deviation as it can be expected that seed is still syncing
// DAO state/blocks. P2P data should be ready but as we received it from other seeds it is not that
Expand Down
143 changes: 114 additions & 29 deletions inventory/src/main/java/bisq/inventory/InventoryWebServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package bisq.inventory;

import bisq.core.network.p2p.inventory.model.DeviationByIntegerDiff;
import bisq.core.network.p2p.inventory.model.DeviationByPercentage;
import bisq.core.network.p2p.inventory.model.DeviationSeverity;
import bisq.core.network.p2p.inventory.model.InventoryItem;
import bisq.core.network.p2p.inventory.model.RequestInfo;
Expand All @@ -37,6 +39,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

import lombok.extern.slf4j.Slf4j;
Expand All @@ -50,6 +53,8 @@
@Slf4j
public class InventoryWebServer {
private final static String CLOSE_TAG = "</font><br/>";
private final static String WARNING_ICON = "&#9888; ";
private final static String ALERT_ICON = "&#9760; "; // &#9889; &#9889;

private final List<NodeAddress> seedNodes;
private final Map<String, String> operatorByNodeAddress = new HashMap<>();
Expand Down Expand Up @@ -122,10 +127,10 @@ private String generateHtml(Map<NodeAddress, List<RequestInfo>> map) {
html.append("<tr valign=\"top\">");
if (map.containsKey(seedNode) && !map.get(seedNode).isEmpty()) {
List<RequestInfo> list = map.get(seedNode);
int numResponses = list.size();
RequestInfo requestInfo = list.get(numResponses - 1);
int numRequests = list.size();
RequestInfo requestInfo = list.get(numRequests - 1);
html.append("<td>").append(getSeedNodeInfo(seedNode, requestInfo)).append("</td>")
.append("<td>").append(getRequestInfo(requestInfo, numResponses)).append("</td>")
.append("<td>").append(getRequestInfo(seedNode, requestInfo, numRequests, map)).append("</td>")
.append("<td>").append(getDataInfo(seedNode, requestInfo, map)).append("</td>")
.append("<td>").append(getDaoInfo(seedNode, requestInfo, map)).append("</td>")
.append("<td>").append(getNetworkInfo(seedNode, requestInfo, map)).append("</td>");
Expand Down Expand Up @@ -186,24 +191,32 @@ private String getSeedNodeInfo(NodeAddress nodeAddress,
"n/a";
sb.append("Run duration: ").append(duration).append("<br/>");

String filteredSeedNodes = requestInfo.getDisplayValue(InventoryItem.filteredSeeds)
.replace(System.getProperty("line.separator"), "<br/>");
if (filteredSeedNodes.isEmpty()) {
filteredSeedNodes = "-";
}
sb.append("Filtered seed nodes: ")
.append(requestInfo.getDisplayValue(InventoryItem.filteredSeeds).replace(System.getProperty("line.separator"), "<br/>"))
.append(filteredSeedNodes)
.append("<br/>");
}

return sb.toString();
}

private String getRequestInfo(RequestInfo requestInfo, int numResponses) {
private String getRequestInfo(NodeAddress seedNode,
RequestInfo requestInfo,
int numRequests,
Map<NodeAddress, List<RequestInfo>> map) {
StringBuilder sb = new StringBuilder();

DeviationSeverity deviationSeverity = numResponses == requestCounter ?
DeviationSeverity deviationSeverity = numRequests == requestCounter ?
DeviationSeverity.OK :
requestCounter - numResponses > 4 ?
requestCounter - numRequests > 4 ?
DeviationSeverity.ALERT :
DeviationSeverity.WARN;
sb.append("Number of responses: ").append(getColorTagByDeviationSeverity(deviationSeverity))
.append(numResponses).append(CLOSE_TAG);
sb.append("Number of requests: ").append(getColorTagByDeviationSeverity(deviationSeverity))
.append(numRequests).append(CLOSE_TAG);

DeviationSeverity rrtDeviationSeverity = DeviationSeverity.OK;
String rrtString = "n/a";
Expand All @@ -228,11 +241,7 @@ private String getRequestInfo(RequestInfo requestInfo, int numResponses) {
"n/a";
sb.append("Response received at: ").append(responseTime).append("<br/>");

String errorMessage = requestInfo.getErrorMessage();
if (errorMessage != null && !errorMessage.isEmpty()) {
sb.append("Error message: ").append(getColorTagByDeviationSeverity(DeviationSeverity.ALERT))
.append(errorMessage).append(CLOSE_TAG);
}
sb.append(getErrorMsgLine(seedNode, requestInfo, map));
return sb.toString();
}

Expand Down Expand Up @@ -353,41 +362,45 @@ private String getLine(String title,
DeviationSeverity deviationSeverity = DeviationSeverity.OK;
if (requestInfo.getDataMap().containsKey(inventoryItem)) {
RequestInfo.Data data = requestInfo.getDataMap().get(inventoryItem);
deviationAsPercentString = getDeviationAsPercentString(data.getDeviation());
deviationAsPercentString = getDeviationAsPercentString(inventoryItem, data);
deviationSeverity = data.getDeviationSeverity();
}

List<RequestInfo> requestInfoList = map.get(seedNode);
String historicalWarnings = "";
String historicalAlerts = "";
List<Integer> warningsAtRequestNumber = new ArrayList<>();
List<Integer> alertsAtRequestNumber = new ArrayList<>();
List<String> warningsAtRequestNumber = new ArrayList<>();
List<String> alertsAtRequestNumber = new ArrayList<>();
if (requestInfoList != null) {
for (int i = 0; i < requestInfoList.size(); i++) {
RequestInfo reqInfo = requestInfoList.get(i);
Map<InventoryItem, RequestInfo.Data> deviationInfoMap = reqInfo.getDataMap();
if (deviationInfoMap.containsKey(inventoryItem)) {
if (deviationInfoMap.get(inventoryItem).isPersistentWarning()) {
warningsAtRequestNumber.add(i + 1);
} else if (deviationInfoMap.get(inventoryItem).isPersistentAlert()) {
alertsAtRequestNumber.add(i + 1);
RequestInfo.Data data = deviationInfoMap.get(inventoryItem);
String deviationAsPercent = getDeviationAsPercentString(inventoryItem, data);
if (data.isPersistentWarning()) {
warningsAtRequestNumber.add((i + 1) + deviationAsPercent);
} else if (data.isPersistentAlert()) {
alertsAtRequestNumber.add((i + 1) + deviationAsPercent);
}
}
}

if (!warningsAtRequestNumber.isEmpty()) {
historicalWarnings = inventoryItem.getDeviationTolerance() + " repeated warning(s) at request(s) " + Joiner.on(", ").join(warningsAtRequestNumber);
historicalWarnings = warningsAtRequestNumber.size() + " repeated warning(s) at request(s) " +
Joiner.on(", ").join(warningsAtRequestNumber);
}
if (!alertsAtRequestNumber.isEmpty()) {
historicalAlerts = inventoryItem.getDeviationTolerance() + " repeated alert(s) at request(s): " + Joiner.on(", ").join(alertsAtRequestNumber);
historicalAlerts = alertsAtRequestNumber.size() + " repeated alert(s) at request(s): " +
Joiner.on(", ").join(alertsAtRequestNumber);
}
}
String warningIcon = "&#9888; ";
String historicalWarningsHtml = warningsAtRequestNumber.isEmpty() ? "" :
", <b><a id=\"warn\" href=\"#\" title=\"" + historicalWarnings + "\">" + warningIcon + warningsAtRequestNumber.size() + "</a></b>";
String errorIcon = "&#9760; "; // &#9889; &#9889;
", <b><a id=\"warn\" href=\"#\" title=\"" + historicalWarnings + "\">" + WARNING_ICON +
warningsAtRequestNumber.size() + "</a></b>";
String historicalAlertsHtml = alertsAtRequestNumber.isEmpty() ? "" :
", <b><a id=\"alert\" href=\"#\" title=\"" + historicalAlerts + "\">" + errorIcon + alertsAtRequestNumber.size() + "</a></b>";
", <b><a id=\"alert\" href=\"#\" title=\"" + historicalAlerts + "\">" + ALERT_ICON +
alertsAtRequestNumber.size() + "</a></b>";

return title +
getColorTagByDeviationSeverity(deviationSeverity) +
Expand All @@ -398,14 +411,29 @@ private String getLine(String title,
CLOSE_TAG;
}

private String getDeviationAsPercentString(@Nullable Double deviation) {
if (deviation == null) {
private String getDeviationAsPercentString(InventoryItem inventoryItem, RequestInfo.Data data) {
Double deviation = data.getDeviation();
if (deviation == null || deviation == 1) {
return "";
}
if (inventoryItem.getDeviationType() instanceof DeviationByPercentage) {
return getDeviationInRoundedPercent(deviation);
} else if (inventoryItem.getDeviationType() instanceof DeviationByIntegerDiff) {
// For larger numbers like chain height we need to show all decimals as diff can be very small
return getDeviationInExactPercent(deviation);
} else {
return "";
}
}

private String getDeviationInRoundedPercent(double deviation) {
return " (" + MathUtils.roundDouble(100 * deviation, 2) + " %)";
}

private String getDeviationInExactPercent(double deviation) {
return " (" + 100 * deviation + " %)";
}

private String getColorTagByDeviationSeverity(@Nullable DeviationSeverity deviationSeverity) {
if (deviationSeverity == null) {
return "<font color=\"black\">";
Expand Down Expand Up @@ -442,4 +470,61 @@ private void setupOperatorMap(BufferedReader seedNodeFile) {
}
});
}

// We use here a bit diff. model as with other historical data alerts/warnings as we do not store it in the data
// object as we do with normal inventoryItems. So the historical error msg are not available in the json file.
// If we need it we have to move that handling here to the InventoryMonitor and change the data model to support the
// missing data for error messages.
private String getErrorMsgLine(NodeAddress seedNode,
RequestInfo requestInfo,
Map<NodeAddress, List<RequestInfo>> map) {
String errorMessage = requestInfo.hasError() ? requestInfo.getErrorMessage() : "-";
List<RequestInfo> requestInfoList = map.get(seedNode);
List<String> errorsAtRequestNumber = new ArrayList<>();
String historicalErrorsHtml = "";
if (requestInfoList != null) {
for (int i = 0; i < requestInfoList.size(); i++) {
RequestInfo requestInfo1 = requestInfoList.get(i);

// We ignore old errors as at startup timeouts are expected and each node restarts once a day
long duration = System.currentTimeMillis() - requestInfo1.getRequestStartTime();
if (requestInfo1.getRequestStartTime() > 0 && duration > TimeUnit.HOURS.toMillis(24)) {
continue;
}

if (requestInfo1.hasError()) {
errorsAtRequestNumber.add((i + 1) + " (" + requestInfo1.getErrorMessage() + ")");
}
}

if (!errorsAtRequestNumber.isEmpty()) {
String errorIcon;
String type;
String style;
if (errorsAtRequestNumber.size() > 4) {
errorIcon = ALERT_ICON;
type = "alert";
style = "alert";
} else {
errorIcon = WARNING_ICON;
type = "warning";
style = "warn";
}
String historicalAlerts = errorsAtRequestNumber.size() + " repeated " + type + "(s) at request(s): " +
Joiner.on(", ").join(errorsAtRequestNumber);
historicalErrorsHtml = errorsAtRequestNumber.isEmpty() ? "" :
", <b><a id=\"" + style + "\" href=\"#\" title=\"" + historicalAlerts + "\">" + errorIcon +
errorsAtRequestNumber.size() + "</a></b>";
}
}
DeviationSeverity deviationSeverity = requestInfo.hasError() ?
errorsAtRequestNumber.size() > 4 ? DeviationSeverity.ALERT : DeviationSeverity.WARN
: DeviationSeverity.OK;

return "Error message: " +
getColorTagByDeviationSeverity(deviationSeverity) +
errorMessage +
historicalErrorsHtml +
CLOSE_TAG;
}
}
5 changes: 5 additions & 0 deletions p2p/src/main/java/bisq/network/p2p/AckMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@

import javax.annotation.Nullable;

// TODO ExpirablePayload has no effect here as it is either a direct msg or packed into MailboxStoragePayload
// We could extend the TTL by setting the TTL in MailboxStoragePayload from the type of msg which gets into the
// SealedAndSigned data.

// We exclude uid from hashcode and equals to detect duplicate entries of the same AckMessage
@EqualsAndHashCode(callSuper = true, exclude = {"uid"})
@Value
Expand Down Expand Up @@ -145,6 +149,7 @@ public static AckMessage fromProto(protobuf.AckMessage proto, int messageVersion
// API
///////////////////////////////////////////////////////////////////////////////////////////

//TODO has no effect, see comment at class definition
@Override
public long getTTL() {
return TimeUnit.DAYS.toMillis(10);
Expand Down
4 changes: 2 additions & 2 deletions p2p/src/main/java/bisq/network/p2p/network/Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ public enum PeerType {

// Leaving some constants package-private for tests to know limits.
private static final int PERMITTED_MESSAGE_SIZE = 200 * 1024; // 200 kb
private static final int MAX_PERMITTED_MESSAGE_SIZE = 10 * 1024 * 1024; // 10 MB (425 offers resulted in about 660 kb, mailbox msg will add more to it) offer has usually 2 kb, mailbox 3kb.
private static final int MAX_PERMITTED_MESSAGE_SIZE = 15 * 1024 * 1024; // 15 MB (425 offers resulted in about 660 kb, mailbox msg will add more to it) offer has usually 2 kb, mailbox 3kb.
//TODO decrease limits again after testing
private static final int SOCKET_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(180);
private static final int SOCKET_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(360);

public static int getPermittedMessageSize() {
return PERMITTED_MESSAGE_SIZE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

@Slf4j
public class GetDataRequestHandler {
private static final long TIMEOUT = 180;
private static final long TIMEOUT = 360;

private static final int MAX_ENTRIES = 10000;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

@Slf4j
class RequestDataHandler implements MessageListener {
private static final long TIMEOUT = 180;
private static final long TIMEOUT = 360;

private NodeAddress peersNodeAddress;
private String getDataRequestType;
Expand Down
12 changes: 8 additions & 4 deletions p2p/src/main/java/bisq/network/p2p/storage/P2PDataStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -511,10 +511,12 @@ void removeExpiredEntries() {

// Batch processing can cause performance issues, so do all of the removes first, then update the listeners
// to let them know about the removes.
toRemoveList.forEach(toRemoveItem -> {
log.debug("We found an expired data entry. We remove the protectedData:\n\t" +
Utilities.toTruncatedString(toRemoveItem.getValue()));
});
if (log.isDebugEnabled()) {
toRemoveList.forEach(toRemoveItem -> {
log.debug("We found an expired data entry. We remove the protectedData:\n\t{}",
Utilities.toTruncatedString(toRemoveItem.getValue()));
});
}
removeFromMapAndDataStore(toRemoveList);

if (sequenceNumberMap.size() > this.maxSequenceNumberMapSizeBeforePurge) {
Expand Down Expand Up @@ -937,6 +939,8 @@ private void removeFromMapAndDataStore(
if (entriesToRemoveWithPayloadHash.isEmpty())
return;

log.info("Remove {} expired data entries", entriesToRemoveWithPayloadHash.size());

ArrayList<ProtectedStorageEntry> entriesForSignal = new ArrayList<>(entriesToRemoveWithPayloadHash.size());
entriesToRemoveWithPayloadHash.forEach(entryToRemoveWithPayloadHash -> {
ByteArray hashOfPayload = entryToRemoveWithPayloadHash.getKey();
Expand Down
Loading