forked from Qortal/qortal
Add access to network engine stats
Added API call GET /peers/enginestats to allow external monitoring. Extract all engine stats in one synchronized block, instead of separate calls, for better consistency.
This commit is contained in:
parent
c4643538f1
commit
51fd177d79
@ -31,6 +31,7 @@ import org.qortal.network.PeerAddress;
|
|||||||
import org.qortal.repository.DataException;
|
import org.qortal.repository.DataException;
|
||||||
import org.qortal.repository.Repository;
|
import org.qortal.repository.Repository;
|
||||||
import org.qortal.repository.RepositoryManager;
|
import org.qortal.repository.RepositoryManager;
|
||||||
|
import org.qortal.utils.ExecuteProduceConsume;
|
||||||
|
|
||||||
@Path("/peers")
|
@Path("/peers")
|
||||||
@Tag(name = "Peers")
|
@Tag(name = "Peers")
|
||||||
@ -108,6 +109,29 @@ public class PeersResource {
|
|||||||
return Network.getInstance().getSelfPeers();
|
return Network.getInstance().getSelfPeers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/enginestats")
|
||||||
|
@Operation(
|
||||||
|
summary = "Fetch statistics snapshot for networking engine",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
content = @Content(
|
||||||
|
mediaType = MediaType.APPLICATION_JSON,
|
||||||
|
array = @ArraySchema(
|
||||||
|
schema = @Schema(
|
||||||
|
implementation = ExecuteProduceConsume.StatsSnapshot.class
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public ExecuteProduceConsume.StatsSnapshot getEngineStats() {
|
||||||
|
Security.checkApiCallAllowed(request);
|
||||||
|
|
||||||
|
return Network.getInstance().getStatsSnapshot();
|
||||||
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Add new peer address",
|
summary = "Add new peer address",
|
||||||
|
@ -56,6 +56,7 @@ import org.qortal.repository.Repository;
|
|||||||
import org.qortal.repository.RepositoryManager;
|
import org.qortal.repository.RepositoryManager;
|
||||||
import org.qortal.settings.Settings;
|
import org.qortal.settings.Settings;
|
||||||
import org.qortal.utils.ExecuteProduceConsume;
|
import org.qortal.utils.ExecuteProduceConsume;
|
||||||
|
import org.qortal.utils.ExecuteProduceConsume.StatsSnapshot;
|
||||||
import org.qortal.utils.NTP;
|
import org.qortal.utils.NTP;
|
||||||
|
|
||||||
// For managing peers
|
// For managing peers
|
||||||
@ -199,6 +200,10 @@ public class Network {
|
|||||||
return this.maxMessageSize;
|
return this.maxMessageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StatsSnapshot getStatsSnapshot() {
|
||||||
|
return this.networkEPC.getStatsSnapshot();
|
||||||
|
}
|
||||||
|
|
||||||
// Peer lists
|
// Peer lists
|
||||||
|
|
||||||
public List<Peer> getConnectedPeers() {
|
public List<Peer> getConnectedPeers() {
|
||||||
|
@ -5,11 +5,26 @@ import java.util.concurrent.Executors;
|
|||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
public abstract class ExecuteProduceConsume implements Runnable {
|
public abstract class ExecuteProduceConsume implements Runnable {
|
||||||
|
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public static class StatsSnapshot {
|
||||||
|
public int activeThreadCount = 0;
|
||||||
|
public int greatestActiveThreadCount = 0;
|
||||||
|
public int consumerCount = 0;
|
||||||
|
public int tasksProduced = 0;
|
||||||
|
public int tasksConsumed = 0;
|
||||||
|
|
||||||
|
public StatsSnapshot() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final String className;
|
private final String className;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
|
|
||||||
@ -51,28 +66,18 @@ public abstract class ExecuteProduceConsume implements Runnable {
|
|||||||
return this.executor.awaitTermination(timeout, TimeUnit.MILLISECONDS);
|
return this.executor.awaitTermination(timeout, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getActiveThreadCount() {
|
public StatsSnapshot getStatsSnapshot() {
|
||||||
|
StatsSnapshot snapshot = new StatsSnapshot();
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
return this.activeThreadCount;
|
snapshot.activeThreadCount = this.activeThreadCount;
|
||||||
}
|
snapshot.greatestActiveThreadCount = this.greatestActiveThreadCount;
|
||||||
|
snapshot.consumerCount = this.consumerCount;
|
||||||
|
snapshot.tasksProduced = this.tasksProduced;
|
||||||
|
snapshot.tasksConsumed = this.tasksConsumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGreatestActiveThreadCount() {
|
return snapshot;
|
||||||
synchronized (this) {
|
|
||||||
return this.greatestActiveThreadCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTasksProduced() {
|
|
||||||
synchronized (this) {
|
|
||||||
return this.tasksProduced;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTasksConsumed() {
|
|
||||||
synchronized (this) {
|
|
||||||
return this.tasksConsumed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,6 +11,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.qortal.utils.ExecuteProduceConsume;
|
import org.qortal.utils.ExecuteProduceConsume;
|
||||||
|
import org.qortal.utils.ExecuteProduceConsume.StatsSnapshot;
|
||||||
|
|
||||||
public class EPCTests {
|
public class EPCTests {
|
||||||
|
|
||||||
@ -60,13 +61,12 @@ public class EPCTests {
|
|||||||
ScheduledExecutorService statusExecutor = Executors.newSingleThreadScheduledExecutor();
|
ScheduledExecutorService statusExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
|
||||||
statusExecutor.scheduleAtFixedRate(() -> {
|
statusExecutor.scheduleAtFixedRate(() -> {
|
||||||
synchronized (testEPC) {
|
StatsSnapshot snapshot = testEPC.getStatsSnapshot();
|
||||||
final long seconds = (System.currentTimeMillis() - start) / 1000L;
|
final long seconds = (System.currentTimeMillis() - start) / 1000L;
|
||||||
System.out.println(String.format("After %d second%s, active threads: %d, greatest thread count: %d, tasks produced: %d, tasks consumed: %d",
|
System.out.println(String.format("After %d second%s, active threads: %d, greatest thread count: %d, tasks produced: %d, tasks consumed: %d",
|
||||||
seconds, (seconds != 1 ? "s" : ""),
|
seconds, (seconds != 1 ? "s" : ""),
|
||||||
testEPC.getActiveThreadCount(), testEPC.getGreatestActiveThreadCount(),
|
snapshot.activeThreadCount, snapshot.greatestActiveThreadCount,
|
||||||
testEPC.getTasksProduced(), testEPC.getTasksConsumed()));
|
snapshot.tasksProduced, snapshot.tasksConsumed));
|
||||||
}
|
|
||||||
}, 1L, 1L, TimeUnit.SECONDS);
|
}, 1L, 1L, TimeUnit.SECONDS);
|
||||||
|
|
||||||
// Let it run for a minute
|
// Let it run for a minute
|
||||||
@ -78,10 +78,10 @@ public class EPCTests {
|
|||||||
final long after = System.currentTimeMillis();
|
final long after = System.currentTimeMillis();
|
||||||
|
|
||||||
System.out.println(String.format("Shutdown took %d milliseconds", after - before));
|
System.out.println(String.format("Shutdown took %d milliseconds", after - before));
|
||||||
System.out.println(String.format("Greatest thread count: %d", testEPC.getGreatestActiveThreadCount()));
|
|
||||||
|
|
||||||
System.out.println(String.format("Tasks produced: %d", testEPC.getTasksProduced()));
|
StatsSnapshot snapshot = testEPC.getStatsSnapshot();
|
||||||
System.out.println(String.format("Tasks consumed: %d", testEPC.getTasksConsumed()));
|
System.out.println(String.format("Greatest thread count: %d, tasks produced: %d, tasks consumed: %d",
|
||||||
|
snapshot.greatestActiveThreadCount, snapshot.tasksProduced, snapshot.tasksConsumed));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user