All checks were successful
Build and Deploy / deploy (push) Successful in 2m42s
Grafana 12 expects Prometheus annotation queries wrapped in a 'target' object with datasource, expr, refId, and range fields. The previous format had expr/step as top-level fields which Grafana silently ignored.
699 lines
16 KiB
Nix
699 lines
16 KiB
Nix
{
|
|
...
|
|
}:
|
|
let
|
|
promDs = {
|
|
type = "prometheus";
|
|
uid = "prometheus";
|
|
};
|
|
|
|
dashboard = {
|
|
editable = true;
|
|
graphTooltip = 1;
|
|
schemaVersion = 39;
|
|
tags = [
|
|
"system"
|
|
"monitoring"
|
|
];
|
|
time = {
|
|
from = "now-6h";
|
|
to = "now";
|
|
};
|
|
timezone = "browser";
|
|
title = "System Overview";
|
|
uid = "system-overview";
|
|
|
|
annotations.list = [
|
|
{
|
|
name = "Jellyfin Streams";
|
|
datasource = {
|
|
type = "grafana";
|
|
uid = "-- Grafana --";
|
|
};
|
|
enable = true;
|
|
iconColor = "green";
|
|
showIn = 0;
|
|
type = "tags";
|
|
tags = [ "jellyfin" ];
|
|
}
|
|
{
|
|
name = "ZFS Scrubs";
|
|
datasource = {
|
|
type = "grafana";
|
|
uid = "-- Grafana --";
|
|
};
|
|
enable = true;
|
|
iconColor = "orange";
|
|
showIn = 0;
|
|
type = "tags";
|
|
tags = [ "zfs-scrub" ];
|
|
}
|
|
{
|
|
name = "LLM Requests";
|
|
datasource = promDs;
|
|
enable = true;
|
|
iconColor = "purple";
|
|
target = {
|
|
datasource = promDs;
|
|
expr = "llamacpp:requests_processing > 0";
|
|
instant = false;
|
|
range = true;
|
|
refId = "A";
|
|
};
|
|
titleFormat = "LLM inference";
|
|
}
|
|
];
|
|
|
|
panels = [
|
|
# -- Row 1: UPS --
|
|
{
|
|
id = 1;
|
|
type = "timeseries";
|
|
title = "UPS Power Draw";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 8;
|
|
x = 0;
|
|
y = 0;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = "apcupsd_ups_load_percent / 100 * apcupsd_nominal_power_watts";
|
|
legendFormat = "Power (W)";
|
|
refId = "A";
|
|
}
|
|
{
|
|
datasource = promDs;
|
|
expr = "avg_over_time((apcupsd_ups_load_percent / 100 * apcupsd_nominal_power_watts + 4.5)[5m:])";
|
|
legendFormat = "5m average (W)";
|
|
refId = "B";
|
|
}
|
|
];
|
|
fieldConfig = {
|
|
defaults = {
|
|
unit = "watt";
|
|
color.mode = "palette-classic";
|
|
custom = {
|
|
lineWidth = 2;
|
|
fillOpacity = 20;
|
|
spanNulls = true;
|
|
};
|
|
};
|
|
overrides = [
|
|
{
|
|
matcher = {
|
|
id = "byFrameRefID";
|
|
options = "A";
|
|
};
|
|
properties = [
|
|
{
|
|
id = "custom.lineStyle";
|
|
value = {
|
|
fill = "dot";
|
|
};
|
|
}
|
|
{
|
|
id = "custom.fillOpacity";
|
|
value = 10;
|
|
}
|
|
{
|
|
id = "custom.lineWidth";
|
|
value = 1;
|
|
}
|
|
{
|
|
id = "custom.pointSize";
|
|
value = 1;
|
|
}
|
|
];
|
|
}
|
|
{
|
|
matcher = {
|
|
id = "byFrameRefID";
|
|
options = "B";
|
|
};
|
|
properties = [
|
|
{
|
|
id = "custom.lineWidth";
|
|
value = 4;
|
|
}
|
|
{
|
|
id = "custom.fillOpacity";
|
|
value = 0;
|
|
}
|
|
];
|
|
}
|
|
];
|
|
};
|
|
}
|
|
{
|
|
id = 7;
|
|
type = "stat";
|
|
title = "Energy Usage (24h)";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 4;
|
|
x = 8;
|
|
y = 0;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = "avg_over_time((apcupsd_ups_load_percent / 100 * apcupsd_nominal_power_watts + 4.5)[24h:]) * 24 / 1000";
|
|
legendFormat = "";
|
|
refId = "A";
|
|
}
|
|
];
|
|
fieldConfig = {
|
|
defaults = {
|
|
unit = "kwatth";
|
|
decimals = 2;
|
|
thresholds = {
|
|
mode = "absolute";
|
|
steps = [
|
|
{
|
|
color = "green";
|
|
value = null;
|
|
}
|
|
{
|
|
color = "yellow";
|
|
value = 5;
|
|
}
|
|
{
|
|
color = "red";
|
|
value = 10;
|
|
}
|
|
];
|
|
};
|
|
};
|
|
overrides = [ ];
|
|
};
|
|
options = {
|
|
reduceOptions = {
|
|
calcs = [ "lastNotNull" ];
|
|
fields = "";
|
|
values = false;
|
|
};
|
|
colorMode = "value";
|
|
graphMode = "none";
|
|
};
|
|
}
|
|
{
|
|
id = 2;
|
|
type = "gauge";
|
|
title = "UPS Load";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 6;
|
|
x = 12;
|
|
y = 0;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = "apcupsd_ups_load_percent";
|
|
refId = "A";
|
|
}
|
|
];
|
|
fieldConfig = {
|
|
defaults = {
|
|
unit = "percent";
|
|
min = 0;
|
|
max = 100;
|
|
thresholds = {
|
|
mode = "absolute";
|
|
steps = [
|
|
{
|
|
color = "green";
|
|
value = null;
|
|
}
|
|
{
|
|
color = "yellow";
|
|
value = 70;
|
|
}
|
|
{
|
|
color = "red";
|
|
value = 90;
|
|
}
|
|
];
|
|
};
|
|
};
|
|
overrides = [ ];
|
|
};
|
|
options.reduceOptions = {
|
|
calcs = [ "lastNotNull" ];
|
|
fields = "";
|
|
values = false;
|
|
};
|
|
}
|
|
{
|
|
id = 3;
|
|
type = "gauge";
|
|
title = "UPS Battery";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 6;
|
|
x = 18;
|
|
y = 0;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = "apcupsd_battery_charge_percent";
|
|
refId = "A";
|
|
}
|
|
];
|
|
fieldConfig = {
|
|
defaults = {
|
|
unit = "percent";
|
|
min = 0;
|
|
max = 100;
|
|
thresholds = {
|
|
mode = "absolute";
|
|
steps = [
|
|
{
|
|
color = "red";
|
|
value = null;
|
|
}
|
|
{
|
|
color = "yellow";
|
|
value = 20;
|
|
}
|
|
{
|
|
color = "green";
|
|
value = 50;
|
|
}
|
|
];
|
|
};
|
|
};
|
|
overrides = [ ];
|
|
};
|
|
options.reduceOptions = {
|
|
calcs = [ "lastNotNull" ];
|
|
fields = "";
|
|
values = false;
|
|
};
|
|
}
|
|
|
|
# -- Row 2: System --
|
|
{
|
|
id = 4;
|
|
type = "timeseries";
|
|
title = "CPU Temperature";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 12;
|
|
x = 0;
|
|
y = 8;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = ''node_hwmon_temp_celsius{chip=~"pci.*"}'';
|
|
legendFormat = "CPU {{sensor}}";
|
|
refId = "A";
|
|
}
|
|
];
|
|
fieldConfig = {
|
|
defaults = {
|
|
unit = "celsius";
|
|
color.mode = "palette-classic";
|
|
custom = {
|
|
lineWidth = 2;
|
|
fillOpacity = 10;
|
|
spanNulls = true;
|
|
};
|
|
};
|
|
overrides = [ ];
|
|
};
|
|
}
|
|
{
|
|
id = 5;
|
|
type = "stat";
|
|
title = "System Uptime";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 6;
|
|
x = 12;
|
|
y = 8;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = "time() - node_boot_time_seconds";
|
|
refId = "A";
|
|
}
|
|
];
|
|
fieldConfig = {
|
|
defaults = {
|
|
unit = "s";
|
|
thresholds = {
|
|
mode = "absolute";
|
|
steps = [
|
|
{
|
|
color = "green";
|
|
value = null;
|
|
}
|
|
];
|
|
};
|
|
};
|
|
overrides = [ ];
|
|
};
|
|
options = {
|
|
reduceOptions = {
|
|
calcs = [ "lastNotNull" ];
|
|
fields = "";
|
|
values = false;
|
|
};
|
|
colorMode = "value";
|
|
graphMode = "none";
|
|
};
|
|
}
|
|
{
|
|
id = 6;
|
|
type = "stat";
|
|
title = "Jellyfin Active Streams";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 6;
|
|
x = 18;
|
|
y = 8;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = "count(jellyfin_now_playing_state) 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";
|
|
};
|
|
}
|
|
|
|
# -- Row 3: qBittorrent --
|
|
{
|
|
id = 11;
|
|
type = "timeseries";
|
|
title = "qBittorrent Speed";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 24;
|
|
x = 0;
|
|
y = 16;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = "sum(qbit_dlspeed) or vector(0)";
|
|
legendFormat = "Download";
|
|
refId = "A";
|
|
}
|
|
{
|
|
datasource = promDs;
|
|
expr = "sum(qbit_upspeed) or vector(0)";
|
|
legendFormat = "Upload";
|
|
refId = "B";
|
|
}
|
|
{
|
|
datasource = promDs;
|
|
expr = "avg_over_time((sum(qbit_dlspeed) or vector(0))[10m:])";
|
|
legendFormat = "Download (10m avg)";
|
|
refId = "C";
|
|
}
|
|
{
|
|
datasource = promDs;
|
|
expr = "avg_over_time((sum(qbit_upspeed) or vector(0))[10m:])";
|
|
legendFormat = "Upload (10m avg)";
|
|
refId = "D";
|
|
}
|
|
];
|
|
fieldConfig = {
|
|
defaults = {
|
|
unit = "binBps";
|
|
min = 0;
|
|
color.mode = "palette-classic";
|
|
custom = {
|
|
lineWidth = 1;
|
|
fillOpacity = 10;
|
|
spanNulls = true;
|
|
};
|
|
};
|
|
overrides = [
|
|
{
|
|
matcher = {
|
|
id = "byFrameRefID";
|
|
options = "A";
|
|
};
|
|
properties = [
|
|
{
|
|
id = "color";
|
|
value = {
|
|
fixedColor = "green";
|
|
mode = "fixed";
|
|
};
|
|
}
|
|
{
|
|
id = "custom.fillOpacity";
|
|
value = 5;
|
|
}
|
|
];
|
|
}
|
|
{
|
|
matcher = {
|
|
id = "byFrameRefID";
|
|
options = "B";
|
|
};
|
|
properties = [
|
|
{
|
|
id = "color";
|
|
value = {
|
|
fixedColor = "blue";
|
|
mode = "fixed";
|
|
};
|
|
}
|
|
{
|
|
id = "custom.fillOpacity";
|
|
value = 5;
|
|
}
|
|
];
|
|
}
|
|
{
|
|
matcher = {
|
|
id = "byFrameRefID";
|
|
options = "C";
|
|
};
|
|
properties = [
|
|
{
|
|
id = "color";
|
|
value = {
|
|
fixedColor = "green";
|
|
mode = "fixed";
|
|
};
|
|
}
|
|
{
|
|
id = "custom.lineWidth";
|
|
value = 3;
|
|
}
|
|
{
|
|
id = "custom.fillOpacity";
|
|
value = 0;
|
|
}
|
|
];
|
|
}
|
|
{
|
|
matcher = {
|
|
id = "byFrameRefID";
|
|
options = "D";
|
|
};
|
|
properties = [
|
|
{
|
|
id = "color";
|
|
value = {
|
|
fixedColor = "blue";
|
|
mode = "fixed";
|
|
};
|
|
}
|
|
{
|
|
id = "custom.lineWidth";
|
|
value = 3;
|
|
}
|
|
{
|
|
id = "custom.fillOpacity";
|
|
value = 0;
|
|
}
|
|
];
|
|
}
|
|
];
|
|
};
|
|
}
|
|
|
|
# -- Row 4: Intel GPU --
|
|
{
|
|
id = 8;
|
|
type = "timeseries";
|
|
title = "Intel GPU Utilization";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 24;
|
|
x = 0;
|
|
y = 24;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = "igpu_engines_busy_percent";
|
|
legendFormat = "{{engine}}";
|
|
refId = "A";
|
|
}
|
|
];
|
|
fieldConfig = {
|
|
defaults = {
|
|
unit = "percent";
|
|
min = 0;
|
|
max = 100;
|
|
color.mode = "palette-classic";
|
|
custom = {
|
|
lineWidth = 2;
|
|
fillOpacity = 10;
|
|
spanNulls = true;
|
|
};
|
|
};
|
|
overrides = [ ];
|
|
};
|
|
}
|
|
|
|
# -- Row 5: Storage --
|
|
{
|
|
id = 12;
|
|
type = "timeseries";
|
|
title = "ZFS Pool Utilization";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 12;
|
|
x = 0;
|
|
y = 32;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = "zfs_pool_allocated_bytes{pool=\"tank\"} / zfs_pool_size_bytes{pool=\"tank\"} * 100";
|
|
legendFormat = "tank";
|
|
refId = "A";
|
|
}
|
|
{
|
|
datasource = promDs;
|
|
expr = "zfs_pool_allocated_bytes{pool=\"hdds\"} / zfs_pool_size_bytes{pool=\"hdds\"} * 100";
|
|
legendFormat = "hdds";
|
|
refId = "B";
|
|
}
|
|
];
|
|
fieldConfig = {
|
|
defaults = {
|
|
unit = "percent";
|
|
min = 0;
|
|
max = 100;
|
|
color.mode = "palette-classic";
|
|
custom = {
|
|
lineWidth = 2;
|
|
fillOpacity = 20;
|
|
spanNulls = true;
|
|
};
|
|
};
|
|
overrides = [ ];
|
|
};
|
|
}
|
|
{
|
|
id = 13;
|
|
type = "timeseries";
|
|
title = "Boot Drive Partitions";
|
|
gridPos = {
|
|
h = 8;
|
|
w = 12;
|
|
x = 12;
|
|
y = 32;
|
|
};
|
|
datasource = promDs;
|
|
targets = [
|
|
{
|
|
datasource = promDs;
|
|
expr = "(node_filesystem_size_bytes{mountpoint=\"/boot\"} - node_filesystem_avail_bytes{mountpoint=\"/boot\"}) / node_filesystem_size_bytes{mountpoint=\"/boot\"} * 100";
|
|
legendFormat = "/boot";
|
|
refId = "A";
|
|
}
|
|
{
|
|
datasource = promDs;
|
|
expr = "(node_filesystem_size_bytes{mountpoint=\"/persistent\"} - node_filesystem_avail_bytes{mountpoint=\"/persistent\"}) / node_filesystem_size_bytes{mountpoint=\"/persistent\"} * 100";
|
|
legendFormat = "/persistent";
|
|
refId = "B";
|
|
}
|
|
{
|
|
datasource = promDs;
|
|
expr = "(node_filesystem_size_bytes{mountpoint=\"/nix\"} - node_filesystem_avail_bytes{mountpoint=\"/nix\"}) / node_filesystem_size_bytes{mountpoint=\"/nix\"} * 100";
|
|
legendFormat = "/nix";
|
|
refId = "C";
|
|
}
|
|
];
|
|
fieldConfig = {
|
|
defaults = {
|
|
unit = "percent";
|
|
min = 0;
|
|
max = 100;
|
|
color.mode = "palette-classic";
|
|
custom = {
|
|
lineWidth = 2;
|
|
fillOpacity = 20;
|
|
spanNulls = true;
|
|
};
|
|
};
|
|
overrides = [ ];
|
|
};
|
|
}
|
|
];
|
|
};
|
|
in
|
|
{
|
|
environment.etc."grafana-dashboards/system-overview.json" = {
|
|
text = builtins.toJSON dashboard;
|
|
mode = "0444";
|
|
};
|
|
}
|