package net.unit8.waitt.feature.admin.routes;
import com.sun.net.httpserver.HttpExchange;
import net.unit8.waitt.api.EmbeddedServer;
import net.unit8.waitt.api.dto.ServerMetadata;
import net.unit8.waitt.feature.admin.Route;
import org.rrd4j.ConsolFun;
import org.rrd4j.core.Util;
import org.rrd4j.graph.RrdGraph;
import org.rrd4j.graph.RrdGraphDef;
import javax.xml.bind.JAXB;
import java.awt.*;
import java.io.IOException;
import java.io.StringWriter;
/**
* Provide information about the server.
*
* @author kawasima
*/
public class ServerAction implements Route {
private final EmbeddedServer server;
private final String rrdPath;
public ServerAction(EmbeddedServer server, String rrdPath) {
this.server = server;
this.rrdPath = rrdPath;
}
@Override
public boolean canHandle(HttpExchange exchange) {
return "GET".equalsIgnoreCase(exchange.getRequestMethod())
&& exchange.getRequestURI().getPath().startsWith("/server");
}
@Override
public void handle(HttpExchange exchange) throws IOException {
if ("/server/cpu.png".equals(exchange.getRequestURI().getPath())) {
byte[] graph = renderGraph(GraphType.CPU);
exchange.getResponseHeaders().add("Content-Type", "image/png");
exchange.sendResponseHeaders(200, graph.length);
exchange.getResponseBody().write(graph);
} else if ("/server/memory.png".equals(exchange.getRequestURI().getPath())) {
byte[] graph = renderGraph(GraphType.MEMORY);
exchange.getResponseHeaders().add("Content-Type", "image/png");
exchange.sendResponseHeaders(200, graph.length);
exchange.getResponseBody().write(graph);
} else {
StringWriter sw = new StringWriter();
ServerMetadata metadata = new ServerMetadata();
metadata.setName(server.getName());
metadata.setStatus(server.getStatus());
JAXB.marshal(metadata, sw);
byte[] body = sw.toString().getBytes("UTF-8");
exchange.sendResponseHeaders(200, body.length);
exchange.getResponseBody().write(body);
}
}
private byte[] renderGraph(GraphType type) throws IOException {
RrdGraphDef gDef = new RrdGraphDef();
long now = Util.getTimestamp();
gDef.setStartTime(now - 24 * 60 * 60);
gDef.setEndTime(now);
gDef.setWidth(500);
gDef.setHeight(300);
gDef.setFilename("-");
gDef.setPoolUsed(true);
gDef.setImageFormat("png");
switch (type) {
case MEMORY:
renderGraphMemory(gDef);
break;
case CPU:
renderGraphCpu(gDef);
break;
}
return new RrdGraph(gDef).getRrdGraphInfo().getBytes();
}
private void renderGraphMemory(RrdGraphDef gDef) {
gDef.setTitle("Memory usage");
gDef.setVerticalLabel("bytes");
gDef.line("Free memory (physical)", Color.BLUE);
gDef.line("Free memory (swap)", Color.GREEN);
gDef.datasource("Free memory (physical)", rrdPath, "memory-physical", ConsolFun.AVERAGE);
gDef.datasource("Free memory (swap)", rrdPath, "memory-swap", ConsolFun.AVERAGE);
gDef.gprint("Free memory (physical)", ConsolFun.AVERAGE, "Free memory (physical) = %.3f%s");
gDef.gprint("Free memory (swap)", ConsolFun.AVERAGE, "Free memory (swap) = %.3f%s\\c");
}
private void renderGraphCpu(RrdGraphDef gDef) {
gDef.setTitle("CPU load");
gDef.setVerticalLabel("%");
gDef.line("Process", Color.BLUE);
gDef.line("System", Color.GREEN);
gDef.datasource("Process", rrdPath, "load-process", ConsolFun.AVERAGE);
gDef.datasource("System", rrdPath, "load-system", ConsolFun.AVERAGE);
gDef.gprint("Process", ConsolFun.AVERAGE, "Load average (process) = %.3f%s");
gDef.gprint("System", ConsolFun.AVERAGE, "Load average (system) = %.3f%s\\c");
}
private enum GraphType { MEMORY, CPU }
}