Pluggable system condition monitoring daemon
  • Rust 92.9%
  • Nix 7.1%
Find a file
NotAShelf 5850f342a1
pscand-cli: error when there are no scanners configured
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Id4e5a2ffc70efb10ba37c0b203a0ac166a6a6964
2026-02-19 01:42:43 +03:00
config pscand-cli: error when there are no scanners configured 2026-02-19 01:42:43 +03:00
contrib chore: switch to TOML-based configuration 2026-02-19 00:57:41 +03:00
crates pscand-cli: error when there are no scanners configured 2026-02-19 01:42:43 +03:00
docs docs: update scanner development guide 2026-02-19 01:42:42 +03:00
nix nix: seralize TOML config in the NixOS module 2026-02-19 00:57:42 +03:00
scanners scanner: make plugin interface ffi-safe with handle-based registry 2026-02-19 00:13:14 +03:00
.envrc initial commit 2026-02-19 00:13:08 +03:00
.gitignore initial commit 2026-02-19 00:13:08 +03:00
Cargo.lock initial commit 2026-02-19 00:13:08 +03:00
Cargo.toml treewide: move application-specific crates to crates/ 2026-02-19 00:13:17 +03:00
flake.lock initial commit 2026-02-19 00:13:08 +03:00
flake.nix nix: add package & NixOS module 2026-02-19 00:13:18 +03:00

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

# 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:

[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:

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

nix run git+https://git.frzn.dev/NotAShelf/pscand

NixOS Module

The flake provides a NixOS module at nixosModules.default:

{ 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

# 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:

# 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

# 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.