# pscand A pluggable system condition monitoring daemon for Linux systems. ## Overview `pscand` (Pluggable System Condition Monitoring Daemon) is a lightweight, extensible monitoring daemon that collects system metrics through dynamically loadable scanner plugins. Built with Rust and designed for systemd-based Linux distributions, it provides real-time monitoring of system resources with minimal overhead. ### Motivation Sometime after updating to Linux 6.18, my system has started rebooting randomly. While at first I've assumed this is some kind of hard failure, I have then noticed that in the system's eyes the shutdown is _entirely graceful_. This lead me to believe this is some hardware issue, where a certain anomaly prompts the motherboard to poweroff. To understand what kind of an anomaly is triggering the reboots, I've created `pscand`. It is a pluggable system daemon that collects system metrics through custom scanner plugins that you load, and provides insight into your system. ### Features - **Modular Architecture**: Scanner plugins are dynamically loaded as shared libraries (`.so` files) - **Configurable**: TOML-based configuration with per-scanner settings - **Plugin System**: Easy to extend with custom scanners - **Systemd Integration**: Native journal logging and service support - **Runtime Metrics**: Built-in collection statistics and health monitoring ## Included Scanners | Scanner | Description | Metrics Collected | | ---------------- | -------------------------- | ---------------------------------------------- | | `scanner-system` | System resource monitoring | CPU, memory, disk, network, load averages | | `scanner-sensor` | Hardware sensor readings | Temperatures, fan speeds, voltages (via hwmon) | | `scanner-power` | Power management | Battery status, power supply state | | `scanner-proc` | Process monitoring | Process states, zombie detection | ## Quick Start ### Installation #### From Source ```bash # Clone the repository $ git clone https://git.frzn.dev/NotAShelf/pscand $ cd pscand # Build the project $ cargo build --release # Install binaries (adjust paths as needed for your system) $ install -Dm755 target/release/pscand ~/.local/bin/pscand $ install -Dm644 config/pscand.toml ~/.config/pscand/pscand.toml ``` ### Systemd Service Create `/etc/systemd/system/pscand.service`: ```ini [Unit] Description=Pluggable System Condition Monitoring Daemon After=network.target [Service] Type=simple ExecStart=%h/.local/bin/pscand run Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target ``` Then enable and start: ```bash sudo systemctl daemon-reload sudo systemctl enable --now pscand ``` ### Installing via Nix Keep in mind that the **recommended** way of installing pscand is through Nix. A Nix package is provided, and is designed to work without additional configuration on first run. To get the daemon functionality, you must use the NixOS module. #### Run directly with `nix run` ```bash nix run git+https://git.frzn.dev/NotAShelf/pscand ``` #### NixOS Module The flake provides a NixOS module at `nixosModules.default`: ```nix { inputs, config, pkgs, ...}: let pscandPkg = inputs.pscand.packages.${pkgs.hostPlatform.system}.default; in { imports = [inputs.pscand.nixosModules.default]; services.pscand = { enable = true; package = pscandPkg; # or your custom package }; } ``` This will: - Install the `pscand` binary and scanner plugins - Create and enable a Systemd service - Configure scanner library paths automatically ## Usage ```bash # Run the daemon with default configuration pscand run # Run with debug logging pscand run --debug # List available built-in scanners pscand list ``` ## Configuration Configuration is stored in `/etc/pscand/pscand.toml`: ```toml # Scanner plugin directories scanner_dirs = ["~/.local/share/pscand/scanners"] # Where to store log files log_dir = "~/.local/share/pscand/logs" # Per-scanner configuration (interval in seconds) [scanners.system] enabled = true interval_secs = 5 [scanners.sensor] enabled = true interval_secs = 10 [scanners.power] enabled = true interval_secs = 30 [scanners.proc] enabled = true interval_secs = 5 ``` ### Scanner Directories Scanner directories can be configured via: 1. Config file: `scanner_dirs` array 2. Environment variable: `PSCAND_SCANNER_DIRS` (colon-separated paths) Default search paths: - `$LIB_PSCAND/scanners` - `~/.local/share/pscand/scanners` - `./pscand/scanners` ## Development ### Prerequisites - Rust 1.90+ (stable toolchain) - Cargo - Linux system with systemd ### Building ```bash # Build entire workspace cargo build # Build release (optimized) cargo build --release # Run tests cargo test # Check formatting cargo fmt --check # Run clippy cargo clippy -- -D warnings ``` ## Contributing Contributions are welcome! Please ensure your code: - Follows the existing code style (run `cargo fmt`) - Passes clippy lints (`cargo clippy -- -D warnings`) - Includes appropriate tests where applicable - Maintains backward compatibility for existing scanners ## License This project is licensed under the [Mozilla Public License 2.0](LICENSE).