blob: fb9427581959ed9d86a168a1a98c557f8c7de48b (
plain) (
tree)
|
|
package org.openslx.dnbd3.status;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.openslx.dnbd3.status.output.EdgeSerializer;
import org.openslx.dnbd3.status.output.OutputMain;
import org.openslx.dnbd3.status.output.ServerStats;
import org.openslx.dnbd3.status.poller.ServerPoller;
import org.openslx.dnbd3.status.rpc.Client;
import org.openslx.dnbd3.status.rpc.Status;
import org.openslx.graph.ClientNode;
import org.openslx.graph.Edge;
import org.openslx.graph.Graph;
import org.openslx.graph.Node;
import org.openslx.graph.ServerNode;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class StatisticsGenerator
{
private final List<ServerPoller> pollers;
private volatile long lastUpdate = 0;
private ExecutorService threadPool = new ThreadPoolExecutor( 3, 8, 1, TimeUnit.MINUTES, new SynchronousQueue<Runnable>() );
private List<Future<Status>> futureStatusList = new ArrayList<>();
private List<Status> statusList = new ArrayList<>();
private final Gson jsonBuilder;
private final Graph graph = new Graph( "DNBD 3 Status" );
private byte[] imgData = null;
private final OutputMain output = new OutputMain();
public StatisticsGenerator( List<ServerPoller> pollers )
{
this.pollers = pollers;
for ( ServerPoller poller : pollers ) {
Node server = new ServerNode( poller.getAddress() );
server.activate();
graph.addNode( server );
}
// Prepare json serializer for graph
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.excludeFieldsWithoutExposeAnnotation();
gsonBuilder.registerTypeHierarchyAdapter( Edge.class, new EdgeSerializer() );
jsonBuilder = gsonBuilder.create();
output.graph = graph;
output.servers = new ArrayList<>();
output.timestamp = 0;
}
private synchronized void updateAll()
{
futureStatusList.clear();
for ( final ServerPoller p : pollers ) {
Callable<Status> task = new Callable<Status>() {
@Override
public Status call() throws Exception
{
return p.update();
}
};
try {
Future<Status> ret = threadPool.submit( task );
futureStatusList.add( ret );
} catch ( Exception e ) {
}
}
statusList.clear();
output.servers.clear();
for ( Future<Status> future : futureStatusList ) {
Status status;
try {
status = future.get();
} catch ( Exception e ) {
continue;
}
if ( status == null )
continue;
statusList.add( status );
ServerStats srv = new ServerStats();
srv.address = status.getAddress();
srv.bytesReceived = status.getBytesReceived();
srv.bytesSent = status.getBytesSent();
srv.clientCount = status.getClients().size();
srv.uptime = status.getUptime();
srv.timestamp = status.getTimestamp();
output.servers.add( srv );
}
output.timestamp = System.currentTimeMillis();
synchronized ( graph ) {
graph.decay();
for ( Status status : statusList ) {
String serverIp = status.getAddress();
Node server = graph.getNode( serverIp );
if ( server == null )
server = new ServerNode( serverIp );
server.activate();
for ( Client client : status.getClients() ) {
if ( client.getAddress() == null )
continue;
String ip = client.getAddress().replaceFirst( "\\:\\d+$", "" );
Node n = graph.getNode( ip );
if ( n == null )
n = new ClientNode( ip );
n.activate();
graph.setEdge( server, n, ( client.getBytesSent() >> 12 ) + 1 );
}
}
imgData = null;
}
}
private synchronized void ensureUpToDate()
{
final long now = System.currentTimeMillis();
if ( now - lastUpdate > 1900 ) {
lastUpdate = now;
updateAll();
}
}
public byte[] getImagePng()
{
ensureUpToDate();
synchronized ( graph ) {
if ( imgData == null ) {
imgData = graph.makeNextImage();
}
}
return imgData;
}
public String getJson()
{
ensureUpToDate();
synchronized ( output ) {
return jsonBuilder.toJson( output );
}
}
}
|