Add metrics.

This commit is contained in:
md_5 2012-10-16 16:34:28 +11:00
parent 86b081ddfd
commit 738ff6c249
3 changed files with 137 additions and 1 deletions

View File

@ -54,7 +54,7 @@ public class BungeeCord {
/** /**
* Current version. * Current version.
*/ */
private String version = (getClass().getPackage().getImplementationVersion() == null) ? "unknown" : getClass().getPackage().getImplementationVersion(); public String version = (getClass().getPackage().getImplementationVersion() == null) ? "unknown" : getClass().getPackage().getImplementationVersion();
/** /**
* Fully qualified connections. * Fully qualified connections.
*/ */
@ -142,6 +142,8 @@ public class BungeeCord {
saveThread.start(); saveThread.start();
$().info("Listening on " + addr); $().info("Listening on " + addr);
new Metrics().start();
} }
/** /**

View File

@ -13,6 +13,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import static net.md_5.bungee.Logger.$; import static net.md_5.bungee.Logger.$;
import net.md_5.bungee.command.CommandSender; import net.md_5.bungee.command.CommandSender;
import net.md_5.bungee.command.ConsoleCommandSender; import net.md_5.bungee.command.ConsoleCommandSender;
@ -109,6 +110,10 @@ public class Configuration {
* Maximum number of lines to log before old ones are removed. * Maximum number of lines to log before old ones are removed.
*/ */
public int logNumLines = 1 << 14; public int logNumLines = 1 << 14;
/**
* UUID for Metrics.
*/
public String statsUuid = UUID.randomUUID().toString();
/** /**
* Load the configuration and save default values. * Load the configuration and save default values.

View File

@ -0,0 +1,129 @@
package net.md_5.bungee;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import static net.md_5.bungee.Logger.$;
public class Metrics extends Thread {
/**
* The current revision number
*/
private final static int REVISION = 5;
/**
* The base url of the metrics domain
*/
private static final String BASE_URL = "http://mcstats.org";
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/report/%s";
/**
* Interval of time to ping (in minutes)
*/
private final static int PING_INTERVAL = 10;
public Metrics() {
super("Metrics Gathering Thread");
setDaemon(true);
}
@Override
public void run() {
boolean firstPost = true;
while (true) {
try {
// We use the inverse of firstPost because if it is the first time we are posting,
// it is not a interval ping, so it evaluates to FALSE
// Each time thereafter it will evaluate to TRUE, i.e PING!
postPlugin(!firstPost);
// After the first post we set firstPost to false
// Each post thereafter will be a ping
firstPost = false;
} catch (IOException ex) {
$().info("[Metrics] " + ex.getMessage());
}
try {
sleep(PING_INTERVAL * 1000 * 60);
} catch (InterruptedException ex) {
break;
}
}
}
/**
* Generic method that posts a plugin to the metrics website
*/
private void postPlugin(boolean isPing) throws IOException {
// Construct the post data
final StringBuilder data = new StringBuilder();
data.append(encode("guid")).append('=').append(encode(BungeeCord.instance.config.statsUuid));
encodeDataPair(data, "version", BungeeCord.instance.version);
encodeDataPair(data, "server", "0");
encodeDataPair(data, "players", Integer.toString(BungeeCord.instance.connections.size()));
encodeDataPair(data, "revision", String.valueOf(REVISION));
// If we're pinging, append it
if (isPing) {
encodeDataPair(data, "ping", "true");
}
// Create the url
URL url = new URL(BASE_URL + String.format(REPORT_URL, encode("BungeeCord")));
// Connect to the website
URLConnection connection;
connection = url.openConnection();
connection.setDoOutput(true);
final BufferedReader reader;
final String response;
try (OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream())) {
writer.write(data.toString());
writer.flush();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
response = reader.readLine();
}
reader.close();
if (response == null || response.startsWith("ERR")) {
throw new IOException(response); //Throw the exception
}
}
/**
* <p>Encode a key/value data pair to be used in a HTTP post request. This
* INCLUDES a & so the first key/value pair MUST be included manually,
* e.g:</p>
* <code>
* StringBuffer data = new StringBuffer();
* data.append(encode("guid")).append('=').append(encode(guid));
* encodeDataPair(data, "version", description.getVersion());
* </code>
*
* @param buffer the StringBuilder to append the data pair onto
* @param key the key value
* @param value the value
*/
private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException {
buffer.append('&').append(encode(key)).append('=').append(encode(value));
}
/**
* Encode text as UTF-8
*
* @param text the text to encode
* @return the encoded text, as UTF-8
*/
private static String encode(final String text) throws UnsupportedEncodingException {
return URLEncoder.encode(text, "UTF-8");
}
}