config graphs to show
This commit is contained in:
@@ -36,7 +36,7 @@ The executable application files are installed under
|
|||||||
separate.
|
separate.
|
||||||
|
|
||||||
Edit `/opt/cheap_system_monitor/monitor.conf` to choose network interfaces,
|
Edit `/opt/cheap_system_monitor/monitor.conf` to choose network interfaces,
|
||||||
mountpoints, and the graph directory. For example, use
|
mountpoints, graphs, and the graph directory. For example, use
|
||||||
`mountpoints = /, /boot/firmware, /mnt/data` to monitor two additional disks;
|
`mountpoints = /, /boot/firmware, /mnt/data` to monitor two additional disks;
|
||||||
every configured path must be mounted and accessible.
|
every configured path must be mounted and accessible.
|
||||||
Restarting is unnecessary after configuration changes—the next timer runs use
|
Restarting is unnecessary after configuration changes—the next timer runs use
|
||||||
@@ -44,6 +44,18 @@ the new values. If the RRD has already been created, do not change the order of
|
|||||||
mountpoints unless you intentionally want the historical graph labels to refer
|
mountpoints unless you intentionally want the historical graph labels to refer
|
||||||
to different disks.
|
to different disks.
|
||||||
|
|
||||||
|
Use the `graphs` setting to choose which graphs are generated and shown, and
|
||||||
|
to set their dashboard order. Available names are `load`, `cpu`, `thermal`,
|
||||||
|
`trouble`, `network`, `disk`, `storage-health`, and `uptime`. For a virtual
|
||||||
|
machine where temperature is not meaningful, for example:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
graphs = load, cpu, trouble, network, disk, storage-health, uptime
|
||||||
|
```
|
||||||
|
|
||||||
|
Omitting a graph does not disable collection of its underlying metrics. This
|
||||||
|
keeps the RRD schema consistent if the graph is enabled later.
|
||||||
|
|
||||||
The generated PNG files and four responsive, auto-refreshing dashboard pages
|
The generated PNG files and four responsive, auto-refreshing dashboard pages
|
||||||
are placed in `/var/www/html/system-monitor` by default. `index.html` shows
|
are placed in `/var/www/html/system-monitor` by default. `index.html` shows
|
||||||
the last 3 hours and links to the 1-day, 2-week, and 1-year pages.
|
the last 3 hours and links to the 1-day, 2-week, and 1-year pages.
|
||||||
|
|||||||
@@ -11,3 +11,8 @@ interfaces = auto
|
|||||||
|
|
||||||
# CPU percentages are measured over this interval each minute.
|
# CPU percentages are measured over this interval each minute.
|
||||||
cpu_sample_seconds = 1.0
|
cpu_sample_seconds = 1.0
|
||||||
|
|
||||||
|
# Graphs to generate and show, in dashboard order. Available names:
|
||||||
|
# load, cpu, thermal, trouble, network, disk, storage-health, uptime
|
||||||
|
# For example, omit "thermal" on a virtual machine.
|
||||||
|
graphs = load, cpu, thermal, trouble, network, disk, storage-health, uptime
|
||||||
|
|||||||
+22
-1
@@ -13,6 +13,10 @@ import subprocess
|
|||||||
PERIODS = {"3hours": "3h", "1day": "1d", "2weeks": "2w", "1year": "1y"}
|
PERIODS = {"3hours": "3h", "1day": "1d", "2weeks": "2w", "1year": "1y"}
|
||||||
COLORS = ["#2563EB", "#DC2626", "#16A34A", "#9333EA"]
|
COLORS = ["#2563EB", "#DC2626", "#16A34A", "#9333EA"]
|
||||||
LOAD_COLORS = ["#FACC15", "#F59E0B", "#DC2626"] # bottom to top
|
LOAD_COLORS = ["#FACC15", "#F59E0B", "#DC2626"] # bottom to top
|
||||||
|
DEFAULT_GRAPHS = (
|
||||||
|
"load", "cpu", "thermal", "trouble", "network", "disk",
|
||||||
|
"storage-health", "uptime",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def graph(output: Path, rrd: Path, start: str, title: str, unit: str,
|
def graph(output: Path, rrd: Path, start: str, title: str, unit: str,
|
||||||
@@ -107,7 +111,7 @@ def main() -> None:
|
|||||||
mounts = [item.strip() for item in config["mountpoints"].split(",") if item.strip()]
|
mounts = [item.strip() for item in config["mountpoints"].split(",") if item.strip()]
|
||||||
if not mounts or mounts[0] != "/":
|
if not mounts or mounts[0] != "/":
|
||||||
mounts.insert(0, "/")
|
mounts.insert(0, "/")
|
||||||
definitions = [
|
all_definitions = [
|
||||||
("load", "Processor load", "load", [("load15", "15 minutes", "AVERAGE"), ("load5", "5 minutes", "AVERAGE"), ("load1", "1 minute", "AVERAGE")], False, True, False, False, False, False),
|
("load", "Processor load", "load", [("load15", "15 minutes", "AVERAGE"), ("load5", "5 minutes", "AVERAGE"), ("load1", "1 minute", "AVERAGE")], False, True, False, False, False, False),
|
||||||
("cpu", "CPU usage", "%", [("cpu_user", "user", "AVERAGE"), ("cpu_system", "system", "AVERAGE"), ("cpu_nice", "nice", "AVERAGE"), ("io_wait", "I/O wait", "AVERAGE")], False, True, False, False, False, False),
|
("cpu", "CPU usage", "%", [("cpu_user", "user", "AVERAGE"), ("cpu_system", "system", "AVERAGE"), ("cpu_nice", "nice", "AVERAGE"), ("io_wait", "I/O wait", "AVERAGE")], False, True, False, False, False, False),
|
||||||
("thermal", "CPU temperature and throttling", "°C", [("temperature", "temperature", "AVERAGE"), ("throttled", "throttled", "MAX")], False, False, False, False, True, False),
|
("thermal", "CPU temperature and throttling", "°C", [("temperature", "temperature", "AVERAGE"), ("throttled", "throttled", "MAX")], False, False, False, False, True, False),
|
||||||
@@ -117,6 +121,23 @@ def main() -> None:
|
|||||||
("storage-health", "Storage operational health", "0–10", [(f"health_{'root' if i == 0 else i}", mount, "MIN") for i, mount in enumerate(mounts)], False, False, False, False, False, False),
|
("storage-health", "Storage operational health", "0–10", [(f"health_{'root' if i == 0 else i}", mount, "MIN") for i, mount in enumerate(mounts)], False, False, False, False, False, False),
|
||||||
("uptime", "System uptime", "days", [("uptime", "uptime", "AVERAGE")], False, False, False, False, False, False),
|
("uptime", "System uptime", "days", [("uptime", "uptime", "AVERAGE")], False, False, False, False, False, False),
|
||||||
]
|
]
|
||||||
|
configured_graphs = [
|
||||||
|
item.strip()
|
||||||
|
for item in config.get("graphs", ",".join(DEFAULT_GRAPHS)).split(",")
|
||||||
|
if item.strip()
|
||||||
|
]
|
||||||
|
if not configured_graphs:
|
||||||
|
raise SystemExit("At least one graph must be configured in 'graphs'")
|
||||||
|
definitions_by_name = {definition[0]: definition for definition in all_definitions}
|
||||||
|
unknown = [name for name in configured_graphs if name not in definitions_by_name]
|
||||||
|
if unknown:
|
||||||
|
available = ", ".join(DEFAULT_GRAPHS)
|
||||||
|
raise SystemExit(
|
||||||
|
f"Unknown graph name(s): {', '.join(unknown)}. Available: {available}"
|
||||||
|
)
|
||||||
|
if len(configured_graphs) != len(set(configured_graphs)):
|
||||||
|
raise SystemExit("Graph names in 'graphs' must not be repeated")
|
||||||
|
definitions = [definitions_by_name[name] for name in configured_graphs]
|
||||||
for period_name, start in PERIODS.items():
|
for period_name, start in PERIODS.items():
|
||||||
for filename, title, unit, series, logarithmic, stacked, disk_memory, network_mixed, thermal_mixed, trouble_mixed in definitions:
|
for filename, title, unit, series, logarithmic, stacked, disk_memory, network_mixed, thermal_mixed, trouble_mixed in definitions:
|
||||||
graph(output_dir / f"{filename}-{period_name}.png", rrd, start,
|
graph(output_dir / f"{filename}-{period_name}.png", rrd, start,
|
||||||
|
|||||||
Reference in New Issue
Block a user