Implement handshake request metrics

This commit is contained in:
RuscalWorld 2021-05-25 22:02:52 +03:00
parent bad6896a5e
commit a3ef97f821
No known key found for this signature in database
GPG key ID: 4F53776031D128ED
5 changed files with 60 additions and 11 deletions

View file

@ -7,12 +7,12 @@ import net.minecraft.server.MinecraftServer;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import ru.ruscalworld.fabricexporter.config.MainConfig; import ru.ruscalworld.fabricexporter.config.MainConfig;
import ru.ruscalworld.fabricexporter.metrics.*;
import java.io.IOException; import java.io.IOException;
import java.util.Timer;
public class FabricExporter implements ModInitializer { public class FabricExporter implements ModInitializer {
private static FabricExporter instance;
private MinecraftServer server; private MinecraftServer server;
private MainConfig config; private MainConfig config;
private HTTPServer httpServer; private HTTPServer httpServer;
@ -50,6 +50,8 @@ public class FabricExporter implements ModInitializer {
this.getHttpServer().stop(); this.getHttpServer().stop();
this.getMetricRegistry().getTimer().cancel(); this.getMetricRegistry().getTimer().cancel();
}); });
instance = this;
} }
public static Logger getLogger() { public static Logger getLogger() {
@ -87,4 +89,8 @@ public class FabricExporter implements ModInitializer {
private void setMetricRegistry(MetricRegistry metricRegistry) { private void setMetricRegistry(MetricRegistry metricRegistry) {
this.metricRegistry = metricRegistry; this.metricRegistry = metricRegistry;
} }
public static FabricExporter getInstance() {
return instance;
}
} }

View file

@ -1,16 +1,20 @@
package ru.ruscalworld.fabricexporter; package ru.ruscalworld.fabricexporter;
import io.prometheus.client.Collector; import io.prometheus.client.Collector;
import io.prometheus.client.Counter;
import io.prometheus.client.SimpleCollector;
import ru.ruscalworld.fabricexporter.config.MainConfig; import ru.ruscalworld.fabricexporter.config.MainConfig;
import ru.ruscalworld.fabricexporter.metrics.*; import ru.ruscalworld.fabricexporter.metrics.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Timer; import java.util.Timer;
public class MetricRegistry { public class MetricRegistry {
private final FabricExporter exporter; private final FabricExporter exporter;
private final List<Metric> metrics = new ArrayList<>(); private final List<Metric> metrics = new ArrayList<>();
private final HashMap<String, Collector> customMetrics = new HashMap<>();
private final Timer timer; private final Timer timer;
public MetricRegistry(FabricExporter exporter) { public MetricRegistry(FabricExporter exporter) {
@ -32,25 +36,36 @@ public class MetricRegistry {
this.registerMetric(new TotalLoadedChunks()); this.registerMetric(new TotalLoadedChunks());
this.registerMetric(new TicksPerSecond()); this.registerMetric(new TicksPerSecond());
this.registerMetric(new MillisPerTick()); this.registerMetric(new MillisPerTick());
this.registerCustomMetric("handshakes", new Counter.Builder()
.name(getMetricName("handshakes"))
.help("Amount of handshake requests")
.labelNames("type")
);
} }
public void registerMetric(Metric metric) { public void registerMetric(Metric metric) {
MainConfig config = this.getExporter().getConfig(); MainConfig config = this.getExporter().getConfig();
if (metric instanceof SparkMetric && !config.shouldUseSpark()) return; if (metric instanceof SparkMetric && !config.shouldUseSpark()) return;
if (!this.isEnabled(metric.getName())) return; if (this.isDisabled(metric.getName())) return;
metric.getGauge().register(); metric.getGauge().register();
this.metrics.add(metric); this.metrics.add(metric);
} }
public void registerCustomMetric(String name, Collector collector) { public void registerCustomMetric(String name, SimpleCollector.Builder<?, ?> collector) {
if (this.isEnabled(name)) collector.register(); if (this.isDisabled(name)) return;
this.getCustomMetrics().put(name, collector.register());
} }
public boolean isEnabled(String name) { public boolean isDisabled(String name) {
MainConfig config = this.getExporter().getConfig(); MainConfig config = this.getExporter().getConfig();
String property = "enable-" + name.replace("_", "-"); String property = "enable-" + name.replace("_", "-");
return config.getProperties().getProperty(property, "true").equals("true"); return !config.getProperties().getProperty(property, "true").equals("true");
}
public static String getMetricName(String name) {
return "minecraft_" + name;
} }
public List<Metric> getMetrics() { public List<Metric> getMetrics() {
@ -64,4 +79,8 @@ public class MetricRegistry {
public Timer getTimer() { public Timer getTimer() {
return timer; return timer;
} }
public HashMap<String, Collector> getCustomMetrics() {
return customMetrics;
}
} }

View file

@ -2,6 +2,7 @@ package ru.ruscalworld.fabricexporter.metrics;
import io.prometheus.client.Gauge; import io.prometheus.client.Gauge;
import ru.ruscalworld.fabricexporter.FabricExporter; import ru.ruscalworld.fabricexporter.FabricExporter;
import ru.ruscalworld.fabricexporter.MetricRegistry;
public abstract class Metric { public abstract class Metric {
private final Gauge gauge; private final Gauge gauge;
@ -10,7 +11,7 @@ public abstract class Metric {
public Metric(String name, String help, String... labels) { public Metric(String name, String help, String... labels) {
this.name = name; this.name = name;
this.gauge = new Gauge.Builder() this.gauge = new Gauge.Builder()
.name("minecraft_" + name) .name(MetricRegistry.getMetricName(name))
.help(help) .help(help)
.labelNames(labels) .labelNames(labels)
.create(); .create();

View file

@ -0,0 +1,24 @@
package ru.ruscalworld.fabricexporter.mixin;
import io.prometheus.client.Collector;
import io.prometheus.client.Counter;
import net.minecraft.network.packet.c2s.handshake.HandshakeC2SPacket;
import net.minecraft.server.network.ServerHandshakeNetworkHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import ru.ruscalworld.fabricexporter.FabricExporter;
import ru.ruscalworld.fabricexporter.MetricRegistry;
@Mixin(ServerHandshakeNetworkHandler.class)
public class ServerHandshakeNetworkHandlerMixin {
@Inject(method = "onHandshake", at = @At("HEAD"))
public void onHandshake(HandshakeC2SPacket packet, CallbackInfo info) {
MetricRegistry metricRegistry = FabricExporter.getInstance().getMetricRegistry();
Collector collector = metricRegistry.getCustomMetrics().get("handshakes");
if (!(collector instanceof Counter)) return;
Counter counter = (Counter) collector;
counter.labels(packet.getIntendedState().name().toLowerCase()).inc();
}
}

View file

@ -3,9 +3,8 @@
"minVersion": "0.8", "minVersion": "0.8",
"package": "ru.ruscalworld.fabricexporter.mixin", "package": "ru.ruscalworld.fabricexporter.mixin",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_8",
"mixins": [ "server": [
], "ServerHandshakeNetworkHandlerMixin"
"client": [
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1