diff --git a/README.md b/README.md index 3aab559..b987271 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ Some metrics depend on server implementations (TPS/MSPT, player ping, tile entit | --- | --- | --- | --- | | spigot_chat_messages_total | counter | none | Total chat messages sent | | spigot_player_movements_total | counter | none | Total player movement events | +| spigot_player_movements_by_player_total | counter | player | Player movements by player | | spigot_players_joined_total | counter | none | Total player joins | | spigot_players_quit_total | counter | none | Total player quits | | spigot_chunk_loads_total | counter | none | Total chunk load events | @@ -92,6 +93,7 @@ Some metrics depend on server implementations (TPS/MSPT, player ping, tile entit | spigot_plugin_enable_total | counter | none | Total plugin enable events | | spigot_plugin_disable_total | counter | none | Total plugin disable events | | spigot_blocks_broken_total | counter | material | Blocks broken by material | +| spigot_blocks_broken_by_player_total | counter | player,material | Blocks broken by player and material | | spigot_blocks_placed_total | counter | material | Blocks placed by material | | spigot_items_crafted_total | counter | material | Items crafted by material | | spigot_entities_killed_total | counter | entity,killer | Entities killed by player | diff --git a/grafana-dashboard.json b/grafana-dashboard.json index 1802ce1..f1b0dfe 100644 --- a/grafana-dashboard.json +++ b/grafana-dashboard.json @@ -477,6 +477,93 @@ "y": 26 }, "id": 13, + "options": { + "showHeader": true + }, + "targets": [ + { + "expr": "topk(10, sum by (player, material) (rate(spigot_blocks_broken_by_player_total{instance=~\"$server\"}[5m])))", + "format": "table", + "legendFormat": "{{player}} / {{material}}", + "refId": "A" + } + ], + "title": "Block Breaks by Player (Top 10)", + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 26, + "panels": [], + "title": "Players", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 36 + }, + "id": 27, + "options": { + "displayMode": "gradient", + "minVizWidth": 0, + "minVizHeight": 10, + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true + }, + "targets": [ + { + "expr": "topk(10, sum by (player) (rate(spigot_player_movements_by_player_total{instance=~\"$server\"}[5m])))", + "legendFormat": "{{player}}", + "refId": "A" + } + ], + "title": "Movements by Player (Top 10)", + "type": "bargauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 36 + }, + "id": 28, "options": { "legend": { "displayMode": "list", @@ -499,7 +586,7 @@ "h": 1, "w": 24, "x": 0, - "y": 35 + "y": 45 }, "id": 14, "panels": [], @@ -522,7 +609,7 @@ "h": 6, "w": 6, "x": 0, - "y": 36 + "y": 46 }, "id": 15, "options": { @@ -563,7 +650,7 @@ "h": 6, "w": 6, "x": 6, - "y": 36 + "y": 46 }, "id": 16, "options": { @@ -604,7 +691,7 @@ "h": 6, "w": 6, "x": 12, - "y": 36 + "y": 46 }, "id": 17, "options": { @@ -645,7 +732,7 @@ "h": 6, "w": 6, "x": 18, - "y": 36 + "y": 46 }, "id": 18, "options": { @@ -676,7 +763,7 @@ "h": 1, "w": 24, "x": 0, - "y": 42 + "y": 52 }, "id": 19, "panels": [], @@ -698,7 +785,7 @@ "h": 9, "w": 12, "x": 0, - "y": 43 + "y": 53 }, "id": 20, "options": { @@ -740,7 +827,7 @@ "h": 9, "w": 12, "x": 12, - "y": 43 + "y": 53 }, "id": 21, "options": { @@ -763,7 +850,7 @@ "h": 1, "w": 24, "x": 0, - "y": 52 + "y": 62 }, "id": 22, "panels": [], @@ -785,7 +872,7 @@ "h": 8, "w": 12, "x": 0, - "y": 53 + "y": 63 }, "id": 23, "options": { @@ -825,7 +912,7 @@ "h": 8, "w": 6, "x": 12, - "y": 53 + "y": 63 }, "id": 24, "options": { @@ -865,7 +952,7 @@ "h": 8, "w": 6, "x": 18, - "y": 53 + "y": 63 }, "id": 25, "options": { diff --git a/src/main/java/com/prometheus/spigot/listeners/BlockBreakListener.java b/src/main/java/com/prometheus/spigot/listeners/BlockBreakListener.java index f508087..90a767f 100644 --- a/src/main/java/com/prometheus/spigot/listeners/BlockBreakListener.java +++ b/src/main/java/com/prometheus/spigot/listeners/BlockBreakListener.java @@ -15,5 +15,6 @@ public final class BlockBreakListener implements Listener { @EventHandler public void onBlockBreak(BlockBreakEvent event) { registry.incrementBlocksBroken(event.getBlock().getType()); + registry.incrementBlocksBroken(event.getBlock().getType(), event.getPlayer().getName()); } } diff --git a/src/main/java/com/prometheus/spigot/listeners/MoveListener.java b/src/main/java/com/prometheus/spigot/listeners/MoveListener.java index 6f38ece..a721c48 100644 --- a/src/main/java/com/prometheus/spigot/listeners/MoveListener.java +++ b/src/main/java/com/prometheus/spigot/listeners/MoveListener.java @@ -20,6 +20,7 @@ public final class MoveListener implements Listener { return; } registry.incrementPlayerMovements(); + registry.incrementPlayerMovements(event.getPlayer().getName()); } private boolean hasChangedBlock(PlayerMoveEvent event) { diff --git a/src/main/java/com/prometheus/spigot/metrics/MetricsRegistry.java b/src/main/java/com/prometheus/spigot/metrics/MetricsRegistry.java index 14e1b24..47fd8e0 100644 --- a/src/main/java/com/prometheus/spigot/metrics/MetricsRegistry.java +++ b/src/main/java/com/prometheus/spigot/metrics/MetricsRegistry.java @@ -46,12 +46,14 @@ public final class MetricsRegistry { private final LongAdder pluginDisables = new LongAdder(); private final ConcurrentHashMap blocksPlacedByMaterial = new ConcurrentHashMap<>(); private final ConcurrentHashMap blocksBrokenByMaterial = new ConcurrentHashMap<>(); + private final ConcurrentHashMap blocksBrokenByPlayerMaterial = new ConcurrentHashMap<>(); private final ConcurrentHashMap deathsByCause = new ConcurrentHashMap<>(); private final ConcurrentHashMap loginFailuresByReason = new ConcurrentHashMap<>(); private final ConcurrentHashMap commandsBlocked = new ConcurrentHashMap<>(); private final ConcurrentHashMap commandsExecuted = new ConcurrentHashMap<>(); private final ConcurrentHashMap itemsCraftedByMaterial = new ConcurrentHashMap<>(); private final ConcurrentHashMap entityKills = new ConcurrentHashMap<>(); + private final ConcurrentHashMap playerMovementsByPlayer = new ConcurrentHashMap<>(); public MetricsRegistry(Server server, boolean enableJvm, boolean enableProcess) { this.server = server; @@ -72,6 +74,10 @@ public final class MetricsRegistry { playerMovements.increment(); } + public void incrementPlayerMovements(String player) { + incrementLabeledCounter(playerMovementsByPlayer, player); + } + public void incrementPlayerJoins() { playerJoins.increment(); } @@ -88,6 +94,14 @@ public final class MetricsRegistry { incrementLabeledCounter(blocksBrokenByMaterial, material.name()); } + public void incrementBlocksBroken(Material material, String player) { + String normalizedMaterial = normalizeLabel(material.name()); + String normalizedPlayer = normalizeLabel(player); + blocksBrokenByPlayerMaterial + .computeIfAbsent(new LabelPair(normalizedPlayer, normalizedMaterial), key -> new LongAdder()) + .increment(); + } + public void incrementBlocksPlaced(Material material) { incrementLabeledCounter(blocksPlacedByMaterial, material.name()); } @@ -185,6 +199,8 @@ public final class MetricsRegistry { appendCounter(builder, "spigot_plugin_disable_total", "Total plugin disable events", pluginDisables.sum()); appendLabeledCounterAdder(builder, "spigot_blocks_broken_total", "Blocks broken by material", "material", blocksBrokenByMaterial); + appendLabeledCounterAdder(builder, "spigot_blocks_broken_by_player_total", "Blocks broken by player and material", "player", + "material", blocksBrokenByPlayerMaterial); appendLabeledCounterAdder(builder, "spigot_blocks_placed_total", "Blocks placed by material", "material", blocksPlacedByMaterial); appendLabeledCounterAdder(builder, "spigot_player_deaths_total", "Player deaths by cause", "cause", deathsByCause); appendLabeledCounterAdder(builder, "spigot_player_logins_failed_total", "Failed player logins by reason", "reason", loginFailuresByReason); @@ -192,6 +208,8 @@ public final class MetricsRegistry { appendLabeledCounterAdder(builder, "spigot_commands_executed_total", "Commands executed by source", "command", "source", commandsExecuted); appendLabeledCounterAdder(builder, "spigot_items_crafted_total", "Items crafted by material", "material", itemsCraftedByMaterial); appendLabeledCounterAdder(builder, "spigot_entities_killed_total", "Entities killed by player", "entity", "killer", entityKills); + appendLabeledCounterAdder(builder, "spigot_player_movements_by_player_total", "Player movements by player", "player", + playerMovementsByPlayer); appendGauge(builder, "spigot_players_online", "Online player count", server.getOnlinePlayers().size()); appendGauge(builder, "spigot_players_max", "Max player slots", server.getMaxPlayers());