Get monitor up to speed again (#3633)

* Updated price node list for monitor

* Price monitor is more resilient against timeouts

Recenty, a price node got removed. Unfortunately, this node
has been the first in the list of configured price nodes in
the monitor configuration.

A misplaced catch block caused the loop to stop instead of
trying the next configured price node in the list.

* Monitor selects a price node randomly

Up until now, the monitor always chose the price nodes
in their configured order. This resulted in querying
always the same node and thus, create a bigger system
load for this very node. Only in case of a failure,
the monitor moved on to another node.

Shuffling the list of nodes prior to querying provides
at least some load balancing for the price nodes.

* Fixed monitor market API query

The format of the market API response changed. Formerly,
there has been one line, now it is pretty print json.

* Add RefundAgent messages to monitor

Add the relatively new RefundAgent message to the monitor.

* Adjust monitor timeout

Observed, that a timeout of one minute works better than
the original 90 seconds.
This commit is contained in:
Christoph Atteneder 2019-11-21 09:42:40 +01:00 committed by GitHub
commit 42dfc6a158
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 59 deletions

View File

@ -89,6 +89,7 @@ public class Monitor {
Capability.BLIND_VOTE,
Capability.DAO_STATE,
Capability.BUNDLE_OF_ENVELOPES,
Capability.REFUND_AGENT,
Capability.MEDIATION);
// assemble Metrics

View File

@ -56,7 +56,7 @@ public class ThreadGate {
public synchronized void await() {
while (lock.getCount() > 0)
try {
if (!lock.await(90, TimeUnit.SECONDS)) {
if (!lock.await(60, TimeUnit.SECONDS)) {
log.warn("timeout occured!");
break; // break the loop
}

View File

@ -90,7 +90,9 @@ public class MarketStats extends Metric {
// prepare to receive data
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String all = in.readLine();
String line, all = "";
while ((line = in.readLine()) != null)
all += ' ' + line;
in.close();
Arrays.stream(all.substring(0, all.length() - 2).split("}")).forEach(trade -> {

View File

@ -40,6 +40,7 @@ import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -81,72 +82,81 @@ public class PriceNodeStats extends Metric {
checkNotNull(tor, "tor must not be null");
Socks5Proxy proxy = tor.getProxy();
String[] hosts = configuration.getProperty(HOSTS, "").split(",");
Collections.shuffle(Arrays.asList(hosts));
// for each configured host
for (String current : configuration.getProperty(HOSTS, "").split(",")) {
for (String current : hosts) {
Map<String, String> result = new HashMap<>();
// parse Url
NodeAddress tmp = OnionParser.getNodeAddress(current);
// connect
SocksSocket socket = new SocksSocket(proxy, tmp.getHostName(), tmp.getPort());
try {
SocksSocket socket = new SocksSocket(proxy, tmp.getHostName(), tmp.getPort());
// prepare to receive data
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// prepare to receive data
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// ask for fee data
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
out.println("GET /getFees/");
out.println();
out.flush();
// ask for fee data
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
out.println("GET /getFees/");
out.println();
out.flush();
// sift through the received lines and see if we got something json-like
String line;
while((line = in.readLine()) != null) {
Matcher matcher = stringNumberPattern.matcher(line);
if(matcher.find())
if(!IGNORE.contains(matcher.group(1)))
result.put("fees." + matcher.group(1), matcher.group(2));
// sift through the received lines and see if we got something json-like
String line;
while ((line = in.readLine()) != null) {
Matcher matcher = stringNumberPattern.matcher(line);
if (matcher.find())
if (!IGNORE.contains(matcher.group(1)))
result.put("fees." + matcher.group(1), matcher.group(2));
}
in.close();
out.close();
socket.close();
// connect
socket = new SocksSocket(proxy, tmp.getHostName(), tmp.getPort());
// prepare to receive data
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// ask for exchange rate data
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
out.println("GET /getAllMarketPrices/");
out.println();
out.flush();
String currencyCode = "";
while ((line = in.readLine()) != null) {
Matcher currencyCodeMatcher = currencyCodePattern.matcher(line);
Matcher priceMatcher = pricePattern.matcher(line);
if (currencyCodeMatcher.find()) {
currencyCode = currencyCodeMatcher.group(1);
if (!assets.contains(currencyCode))
currencyCode = "";
} else if (!"".equals(currencyCode) && priceMatcher.find())
result.put("price." + currencyCode, priceMatcher.group(1));
}
// close all the things
in.close();
out.close();
socket.close();
// report
reporter.report(result, getName());
// only ask for data as long as we got none
if (!result.isEmpty())
break;
} catch (IOException e) {
log.error("{} seems to be down. Trying next configured price node.", tmp.getHostName());
e.printStackTrace();
}
in.close();
out.close();
socket.close();
// connect
socket = new SocksSocket(proxy, tmp.getHostName(), tmp.getPort());
// prepare to receive data
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// ask for exchange rate data
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
out.println("GET /getAllMarketPrices/");
out.println();
out.flush();
String currencyCode = "";
while((line = in.readLine()) != null) {
Matcher currencyCodeMatcher = currencyCodePattern.matcher(line);
Matcher priceMatcher = pricePattern.matcher(line);
if(currencyCodeMatcher.find()) {
currencyCode = currencyCodeMatcher.group(1);
if(!assets.contains(currencyCode))
currencyCode = "";
} else if(!"".equals(currencyCode) && priceMatcher.find())
result.put("price." + currencyCode, priceMatcher.group(1));
}
// close all the things
in.close();
out.close();
socket.close();
// report
reporter.report(result, getName());
// only ask for data as long as we got none
if(!result.isEmpty())
break;
}
} catch (TorCtlException | IOException e) {
// TODO Auto-generated catch block

View File

@ -62,7 +62,7 @@ P2PMarketStats.run.torProxyPort=9063
#PriceNodeStats Metric
PriceNodeStats.enabled=false
PriceNodeStats.run.interval=42
PriceNodeStats.run.hosts=http://5bmpx76qllutpcyp.onion, http://xc3nh4juf2hshy7e.onion, http://44mgyoe2b6oqiytt.onion, http://62nvujg5iou3vu3i.onion, http://ceaanhbvluug4we6.onion
PriceNodeStats.run.hosts=http://xc3nh4juf2hshy7e.onion, http://44mgyoe2b6oqiytt.onion, http://62nvujg5iou3vu3i.onion, http://ceaanhbvluug4we6.onion, http://gztmprecgqjq64zh.onion/
#MarketStats Metric
MarketStats.enabled=false