grafana: add minecraft server stats
This commit is contained in:
@@ -196,6 +196,10 @@ rec {
|
|||||||
port = 9563;
|
port = 9563;
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
};
|
};
|
||||||
|
minecraft_exporter = {
|
||||||
|
port = 9567;
|
||||||
|
proto = "tcp";
|
||||||
|
};
|
||||||
prometheus_zfs = {
|
prometheus_zfs = {
|
||||||
port = 9134;
|
port = 9134;
|
||||||
proto = "tcp";
|
proto = "tcp";
|
||||||
|
|||||||
@@ -75,4 +75,19 @@ final: prev: {
|
|||||||
'';
|
'';
|
||||||
meta.mainProgram = "igpu-exporter";
|
meta.mainProgram = "igpu-exporter";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mc-monitor = prev.buildGoModule rec {
|
||||||
|
pname = "mc-monitor";
|
||||||
|
version = "0.16.1";
|
||||||
|
src = prev.fetchFromGitHub {
|
||||||
|
owner = "itzg";
|
||||||
|
repo = "mc-monitor";
|
||||||
|
rev = version;
|
||||||
|
hash = "sha256-/94+Z9FTFOzQHynHiJuaGFiidkOxmM0g/FIpHn+xvJM=";
|
||||||
|
};
|
||||||
|
vendorHash = "sha256-qq7rIpvGRi3AMnBbi8uAhiPcfSF4McIuqozdtxB5CeQ=";
|
||||||
|
# upstream tests probe live Minecraft servers
|
||||||
|
doCheck = false;
|
||||||
|
meta.mainProgram = "mc-monitor";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -687,6 +687,188 @@ let
|
|||||||
overrides = [ ];
|
overrides = [ ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# -- Row 6: Minecraft --
|
||||||
|
{
|
||||||
|
id = 14;
|
||||||
|
type = "stat";
|
||||||
|
title = "Minecraft Players";
|
||||||
|
gridPos = {
|
||||||
|
h = 8;
|
||||||
|
w = 6;
|
||||||
|
x = 0;
|
||||||
|
y = 40;
|
||||||
|
};
|
||||||
|
datasource = promDs;
|
||||||
|
targets = [
|
||||||
|
{
|
||||||
|
datasource = promDs;
|
||||||
|
expr = "sum(minecraft_status_players_online_count) or vector(0)";
|
||||||
|
refId = "A";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
fieldConfig = {
|
||||||
|
defaults = {
|
||||||
|
thresholds = {
|
||||||
|
mode = "absolute";
|
||||||
|
steps = [
|
||||||
|
{
|
||||||
|
color = "green";
|
||||||
|
value = null;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
color = "yellow";
|
||||||
|
value = 3;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
color = "red";
|
||||||
|
value = 6;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
overrides = [ ];
|
||||||
|
};
|
||||||
|
options = {
|
||||||
|
reduceOptions = {
|
||||||
|
calcs = [ "lastNotNull" ];
|
||||||
|
fields = "";
|
||||||
|
values = false;
|
||||||
|
};
|
||||||
|
colorMode = "value";
|
||||||
|
graphMode = "area";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
id = 15;
|
||||||
|
type = "stat";
|
||||||
|
title = "Minecraft Server";
|
||||||
|
gridPos = {
|
||||||
|
h = 8;
|
||||||
|
w = 6;
|
||||||
|
x = 6;
|
||||||
|
y = 40;
|
||||||
|
};
|
||||||
|
datasource = promDs;
|
||||||
|
targets = [
|
||||||
|
{
|
||||||
|
datasource = promDs;
|
||||||
|
expr = "max(minecraft_status_healthy) or vector(0)";
|
||||||
|
refId = "A";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
fieldConfig = {
|
||||||
|
defaults = {
|
||||||
|
mappings = [
|
||||||
|
{
|
||||||
|
type = "value";
|
||||||
|
options = {
|
||||||
|
"0" = {
|
||||||
|
text = "Offline";
|
||||||
|
color = "red";
|
||||||
|
index = 0;
|
||||||
|
};
|
||||||
|
"1" = {
|
||||||
|
text = "Online";
|
||||||
|
color = "green";
|
||||||
|
index = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
thresholds = {
|
||||||
|
mode = "absolute";
|
||||||
|
steps = [
|
||||||
|
{
|
||||||
|
color = "red";
|
||||||
|
value = null;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
color = "green";
|
||||||
|
value = 1;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
overrides = [ ];
|
||||||
|
};
|
||||||
|
options = {
|
||||||
|
reduceOptions = {
|
||||||
|
calcs = [ "lastNotNull" ];
|
||||||
|
fields = "";
|
||||||
|
values = false;
|
||||||
|
};
|
||||||
|
colorMode = "value";
|
||||||
|
graphMode = "none";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
id = 16;
|
||||||
|
type = "timeseries";
|
||||||
|
title = "Minecraft Player Activity";
|
||||||
|
gridPos = {
|
||||||
|
h = 8;
|
||||||
|
w = 12;
|
||||||
|
x = 12;
|
||||||
|
y = 40;
|
||||||
|
};
|
||||||
|
datasource = promDs;
|
||||||
|
targets = [
|
||||||
|
{
|
||||||
|
datasource = promDs;
|
||||||
|
expr = "sum(minecraft_status_players_online_count) or vector(0)";
|
||||||
|
legendFormat = "Online players";
|
||||||
|
refId = "A";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
datasource = promDs;
|
||||||
|
expr = "max(minecraft_status_players_max_count) or vector(0)";
|
||||||
|
legendFormat = "Max players";
|
||||||
|
refId = "B";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
fieldConfig = {
|
||||||
|
defaults = {
|
||||||
|
unit = "short";
|
||||||
|
min = 0;
|
||||||
|
decimals = 0;
|
||||||
|
color.mode = "palette-classic";
|
||||||
|
custom = {
|
||||||
|
lineWidth = 2;
|
||||||
|
fillOpacity = 15;
|
||||||
|
spanNulls = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
overrides = [
|
||||||
|
{
|
||||||
|
matcher = {
|
||||||
|
id = "byFrameRefID";
|
||||||
|
options = "B";
|
||||||
|
};
|
||||||
|
properties = [
|
||||||
|
{
|
||||||
|
id = "custom.lineStyle";
|
||||||
|
value = {
|
||||||
|
fill = "dash";
|
||||||
|
dash = [
|
||||||
|
8
|
||||||
|
4
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
id = "custom.fillOpacity";
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
id = "custom.lineWidth";
|
||||||
|
value = 1;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ let
|
|||||||
jellyfinExporterPort = service_configs.ports.private.jellyfin_exporter.port;
|
jellyfinExporterPort = service_configs.ports.private.jellyfin_exporter.port;
|
||||||
qbitExporterPort = service_configs.ports.private.qbittorrent_exporter.port;
|
qbitExporterPort = service_configs.ports.private.qbittorrent_exporter.port;
|
||||||
igpuExporterPort = service_configs.ports.private.igpu_exporter.port;
|
igpuExporterPort = service_configs.ports.private.igpu_exporter.port;
|
||||||
|
minecraftExporterPort = service_configs.ports.private.minecraft_exporter.port;
|
||||||
|
minecraftServerName = service_configs.minecraft.server_name;
|
||||||
|
minecraftServerPort = service_configs.ports.public.minecraft.port;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# -- Jellyfin Prometheus Exporter --
|
# -- Jellyfin Prometheus Exporter --
|
||||||
@@ -109,4 +112,45 @@ in
|
|||||||
REFRESH_PERIOD_MS = "30000";
|
REFRESH_PERIOD_MS = "30000";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# -- Minecraft Prometheus Exporter --
|
||||||
|
# itzg/mc-monitor queries the local server via SLP on each scrape and exposes
|
||||||
|
# minecraft_status_{healthy,response_time_seconds,players_online_count,players_max_count}.
|
||||||
|
# mc-monitor binds to 0.0.0.0 (no listen-address flag); the firewall keeps
|
||||||
|
# 9567 internal and IPAddressAllow pins the socket to loopback as defense-in-depth.
|
||||||
|
systemd.services.minecraft-exporter =
|
||||||
|
lib.mkIf (config.services.grafana.enable && config.services.minecraft-servers.enable)
|
||||||
|
{
|
||||||
|
description = "Prometheus exporter for Minecraft (mc-monitor SLP)";
|
||||||
|
after = [
|
||||||
|
"network.target"
|
||||||
|
"minecraft-server-${minecraftServerName}.service"
|
||||||
|
];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${lib.getExe pkgs.mc-monitor} export-for-prometheus";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = "10s";
|
||||||
|
DynamicUser = true;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
RestrictAddressFamilies = [
|
||||||
|
"AF_INET"
|
||||||
|
"AF_INET6"
|
||||||
|
];
|
||||||
|
IPAddressAllow = [
|
||||||
|
"127.0.0.0/8"
|
||||||
|
"::1/128"
|
||||||
|
];
|
||||||
|
IPAddressDeny = "any";
|
||||||
|
};
|
||||||
|
environment = {
|
||||||
|
EXPORT_SERVERS = "127.0.0.1:${toString minecraftServerPort}";
|
||||||
|
EXPORT_PORT = toString minecraftExporterPort;
|
||||||
|
TIMEOUT = "5s";
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,12 @@ in
|
|||||||
{ targets = [ "127.0.0.1:${toString service_configs.ports.private.igpu_exporter.port}" ]; }
|
{ targets = [ "127.0.0.1:${toString service_configs.ports.private.igpu_exporter.port}" ]; }
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
job_name = "minecraft";
|
||||||
|
static_configs = [
|
||||||
|
{ targets = [ "127.0.0.1:${toString service_configs.ports.private.minecraft_exporter.port}" ]; }
|
||||||
|
];
|
||||||
|
}
|
||||||
{
|
{
|
||||||
job_name = "zfs";
|
job_name = "zfs";
|
||||||
static_configs = [
|
static_configs = [
|
||||||
|
|||||||
Reference in New Issue
Block a user