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

Monitor release: Showing off #2348

Merged
merged 40 commits into from
Feb 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
b5a7994
P2P roundtriptime metric init
freimair Jan 9, 2019
985c353
Add missing Version information
freimair Jan 21, 2019
2d9ec11
P2PRttMetric learns about sample size
freimair Jan 21, 2019
515247e
P2PRttMetric knows multiple targets
freimair Jan 21, 2019
ad2de68
Cleanup
freimair Jan 21, 2019
3c6566b
P2PRtt Metric has configurable Tor proxy port
freimair Jan 21, 2019
832bc45
Set BTC_MAINNET for real
freimair Jan 21, 2019
6918f1b
NetworkLoad Metric init
freimair Jan 24, 2019
01924b8
Only request new data
freimair Jan 24, 2019
ed0dede
Collect NetworkLoad histogram
freimair Jan 24, 2019
724caf9
Query multiple nodes for NetworkLoad metric
freimair Jan 24, 2019
662891c
Cleanup
freimair Jan 24, 2019
70d18e0
Data consistency metrics
freimair Jan 24, 2019
273b8c1
Updated sample config
freimair Jan 24, 2019
bafce45
Limit hashlist in size
freimair Jan 24, 2019
d87038f
Comments
freimair Jan 24, 2019
cae4a62
Use global Tor for P2P metrics
freimair Jan 24, 2019
2c3fcc6
Added P2P metrics
freimair Jan 28, 2019
7207506
Refactored Onion address parsing
freimair Jan 28, 2019
06876dd
Only start network nodes if metric is enabled
freimair Jan 28, 2019
e5f4776
Refactored thread synchronization
freimair Jan 29, 2019
2aaa81b
Shutdown metric before sleep if shut down
freimair Jan 29, 2019
202acac
Refactored lock implementation
freimair Jan 29, 2019
692da95
Unlock gate in case of an error
freimair Jan 29, 2019
eeca2d3
Added P2P Message Snapshot metric
freimair Jan 29, 2019
7c6e71c
Unlock gates in case of connection shutdown
freimair Jan 29, 2019
2f7e74f
Reduce log output in productive environment
freimair Jan 29, 2019
1cdecd2
Introduce timeout for ThreadGates
freimair Jan 30, 2019
a363f15
Do not flood a node with requests
freimair Jan 30, 2019
2ca5fdc
Fix negation bug
freimair Jan 30, 2019
f64a0ba
Open gate if request failed
freimair Jan 30, 2019
9f3b3cd
Close unneeded connections
freimair Jan 30, 2019
d93f3c4
Insert sleep phases to not flood Tor with requests
freimair Jan 30, 2019
834a7de
The lockcount does no longer influence the timeout
freimair Jan 30, 2019
1e8a6e7
Add torProxyPort setting to example config
freimair Jan 30, 2019
f54ea61
Remove superfluous code
freimair Jan 30, 2019
8cacd92
GraphiteReporter can handle non-HS target urls
freimair Jan 31, 2019
3ca0f67
Monitor release: Showing off
freimair Jan 31, 2019
f066fc2
Refactoring: remove unneeded exception
freimair Feb 1, 2019
d13dceb
Insert null checks
freimair Feb 1, 2019
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: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ configure(project(':monitor')) {
}

dependencies {
compile project(':p2p')
compile project(':core')
compile "org.slf4j:slf4j-api:$slf4jVersion"
compile "ch.qos.logback:logback-core:$logbackVersion"
compile "ch.qos.logback:logback-classic:$logbackVersion"
Expand Down
50 changes: 50 additions & 0 deletions monitor/src/main/java/bisq/monitor/AvailableTor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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;

import java.io.File;
import org.berndpruenster.netlayer.tor.Tor;
import bisq.network.p2p.network.TorMode;

/**
* This class uses an already defined Tor via <code>Tor.getDefault()</code>
*
* @author Florian Reimair
*
*/
public class AvailableTor extends TorMode {

private String hiddenServiceDirectory;

public AvailableTor(File torWorkingDirectory, String hiddenServiceDirectory) {
super(torWorkingDirectory);

this.hiddenServiceDirectory = hiddenServiceDirectory;
}

@Override
public Tor getTor() {
return Tor.getDefault();
}

@Override
public String getHiddenServiceDirectory() {
return hiddenServiceDirectory;
}

}
9 changes: 7 additions & 2 deletions monitor/src/main/java/bisq/monitor/Metric.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ protected Metric(Reporter reporter) {
disable();
}

protected boolean enabled() {
boolean enabled() {
return !shutdown;
}

Expand Down Expand Up @@ -117,9 +117,14 @@ public void run() {
while (!shutdown) {
// if not, execute all the things
synchronized (this) {
log.info("{} started", getName());
execute();
log.info("{} done", getName());
}

if (shutdown)
continue;

// make sure our configuration is not changed in the moment we want to query it
String interval;
synchronized (this) {
Expand Down Expand Up @@ -148,7 +153,7 @@ public void shutdown() {
shutdown = true;
}

protected void join() throws InterruptedException {
void join() throws InterruptedException {
thread.join();
}

Expand Down
19 changes: 12 additions & 7 deletions monitor/src/main/java/bisq/monitor/Monitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

package bisq.monitor;

import bisq.monitor.metric.P2PNetworkLoad;
import bisq.monitor.metric.P2PNetworkMessageSnapshot;
import bisq.monitor.metric.P2PRoundTripTime;
import bisq.monitor.metric.TorHiddenServiceStartupTime;
import bisq.monitor.metric.TorRoundTripTime;
import bisq.monitor.metric.TorStartupTime;
Expand Down Expand Up @@ -48,6 +51,7 @@
@Slf4j
public class Monitor {

public static final File TOR_WORKING_DIR = new File("monitor/monitor-tor");
private static String[] args = {};

public static void main(String[] args) throws Throwable {
Expand All @@ -63,11 +67,12 @@ public static void main(String[] args) throws Throwable {
/**
* Starts up all configured Metrics.
*
* @throws Exception
* @throws Throwable in case something goes wrong
*/
private void start() throws Throwable {

// start Tor
Tor.setDefault(new NativeTor(new File("monitor/monitor-tor"), null, null, false));
Tor.setDefault(new NativeTor(TOR_WORKING_DIR, null, null, false));

// assemble Metrics
// - create reporters
Expand All @@ -78,12 +83,13 @@ private void start() throws Throwable {
metrics.add(new TorStartupTime(graphiteReporter));
metrics.add(new TorRoundTripTime(graphiteReporter));
metrics.add(new TorHiddenServiceStartupTime(graphiteReporter));
metrics.add(new P2PRoundTripTime(graphiteReporter));
metrics.add(new P2PNetworkLoad(graphiteReporter));
metrics.add(new P2PNetworkMessageSnapshot(graphiteReporter));

// prepare configuration reload
// Note that this is most likely only work on Linux
Signal.handle(new Signal("USR1"), signal -> {
reload();
});
Signal.handle(new Signal("USR1"), signal -> reload());

// configure Metrics
// - which also starts the metrics if appropriate
Expand Down Expand Up @@ -133,7 +139,6 @@ private void reload() {
for (Metric current : metrics)
current.configure(properties);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Expand All @@ -142,7 +147,7 @@ private void reload() {
* Overloads a default set of properties with a file if given
*
* @return a set of properties
* @throws Exception
* @throws Exception in case something goes wrong
*/
private Properties getProperties() throws Exception {
Properties defaults = new Properties();
Expand Down
47 changes: 47 additions & 0 deletions monitor/src/main/java/bisq/monitor/OnionParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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;

import java.net.MalformedURLException;
import java.net.URL;

import bisq.network.p2p.NodeAddress;

/**
* Helper for parsing and pretty printing onion addresses.
*
* @author Florian Reimair
*/
public class OnionParser {

public static NodeAddress getNodeAddress(final String current) throws MalformedURLException {
String nodeAddress = current.trim();
if (!nodeAddress.startsWith("http://"))
nodeAddress = "http://" + nodeAddress;
URL tmp = new URL(nodeAddress);
return new NodeAddress(tmp.getHost(), tmp.getPort());
}

public static String prettyPrint(final NodeAddress host) {
return host.getHostNameWithoutPostFix();
}

public static String prettyPrint(String host) throws MalformedURLException {
return prettyPrint(getNodeAddress(host));
}
}
66 changes: 66 additions & 0 deletions monitor/src/main/java/bisq/monitor/StatisticsHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* 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;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.Map;

/**
* Calculates average, max, min, p25, p50, p75 off of a list of samples and
* throws in the sample size for good measure.
*
* @author Florian Reimair
*/
public class StatisticsHelper {

public static Map<String, String> process(List<Long> samples) {

// aftermath
Collections.sort(samples);

// - average, max, min , sample size
LongSummaryStatistics statistics = samples.stream().mapToLong(val -> val).summaryStatistics();

Map<String, String> results = new HashMap<>();
results.put("average", String.valueOf(Math.round(statistics.getAverage())));
results.put("max", String.valueOf(statistics.getMax()));
results.put("min", String.valueOf(statistics.getMin()));
results.put("sampleSize", String.valueOf(statistics.getCount()));

// - p25, median, p75
Integer[] percentiles = new Integer[] { 25, 50, 75 };
for (Integer percentile : percentiles) {
double rank = statistics.getCount() * percentile / 100;
Long percentileValue;
if (samples.size() <= rank + 1)
percentileValue = samples.get(samples.size() - 1);
else if (Math.floor(rank) == rank)
percentileValue = samples.get((int) rank);
else
percentileValue = Math.round(samples.get((int) Math.floor(rank))
+ (samples.get((int) (Math.floor(rank) + 1)) - samples.get((int) Math.floor(rank)))
/ (rank - Math.floor(rank)));
results.put("p" + percentile, String.valueOf(percentileValue));
}

return results;
}
}
81 changes: 81 additions & 0 deletions monitor/src/main/java/bisq/monitor/ThreadGate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* 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;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import lombok.extern.slf4j.Slf4j;

/**
* Gate pattern to help with thread synchronization
*
* @author Florian Reimair
*/
@Slf4j
public class ThreadGate {

private CountDownLatch lock = new CountDownLatch(0);

/**
* Make everyone wait until the gate is open again.
*/
public void engage() {
lock = new CountDownLatch(1);
}

/**
* Make everyone wait until the gate is open again.
*
* @param numberOfLocks how often the gate has to be unlocked until the gate
* opens.
*/
public void engage(int numberOfLocks) {
lock = new CountDownLatch(numberOfLocks);
}

/**
* Wait for the gate to be opened. Blocks until the gate is open again. Returns
* immediately if the gate is already open.
*/
public synchronized void await() {
while (lock.getCount() > 0)
try {
if (!lock.await(90, TimeUnit.SECONDS)) {
log.warn("timeout occured!");
break; // break the loop
}
} catch (InterruptedException ignore) {
}
}

/**
* Open the gate and let everyone proceed with their execution.
*/
public void proceed() {
lock.countDown();
}

/**
* Open the gate with no regards on how many locks are still in place.
*/
public void unlock() {
while (lock.getCount() > 0)
lock.countDown();
}
}
Loading