blob: 48b075d25efcec3f1eae774eddd4d0a6daf16c82 (
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 exposedJsonBuilder;
private final Gson defaultJsonBuilder;
private final Graph graph = new Graph( "DNBD 3 Status" );
private byte[] imgData = null;
private final OutputMain output = new OutputMain();
private final OutputMain newOutput = 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() );
exposedJsonBuilder = gsonBuilder.create();
defaultJsonBuilder = new GsonBuilder().create();
output.graph = graph;
output.servers = new ArrayList<>();
output.timestamp = 0;
newOutput.servers = new ArrayList<>();
newOutput.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 ) {
e.printStackTrace();
}
}
statusList.clear();
List<ServerStats> outServers = new ArrayList<ServerStats>();
List<ServerStats> newOutServers = new ArrayList<ServerStats>();
for ( Future<Status> future : futureStatusList ) {
Status status;
try {
status = future.get();
} catch ( Exception e ) {
System.out.println("Future timeout");
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.getClientCount();
srv.serverCount = status.getServerCount();
srv.uptime = status.getUptime();
srv.timestamp = status.getTimestamp();
outServers.add( srv );
srv = srv.clone();
srv.images = status.getImages();
srv.clients = status.getClients();
if (srv.clientCount == 0 && srv.serverCount == 0) {
// For older dnbd3-server
srv.clientCount = srv.clients.size();
}
newOutServers.add( srv );
}
output.servers = outServers;
newOutput.servers = newOutServers;
newOutput.timestamp = 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( boolean newFormat )
{
ensureUpToDate();
if ( newFormat ) {
synchronized ( newOutput ) {
return defaultJsonBuilder.toJson( newOutput );
}
} else {
synchronized ( output ) {
return exposedJsonBuilder.toJson( output );
}
}
}
}
|