install.

Free Dual-In-line-Memory-Module (DIMM) monitoring on any Unix-like box with Error-Correcting-Code (ECC) Random-Access-Memory (RAM).

Pre-alpha   agent runs locally by default — publishing to our network is opt-in.

Supported platforms

Our agent reads ECC telemetry from whichever path the host's Operating-System (OS) exposes. Full support means per-Dual-In-line-Memory-Module (DIMM) Correctable-Error (CE) + Uncorrectable-Error (UE) counts; partial support means event-log fidelity with last-seen-event cursors so we count NEW events per tick (no double-counting on restart); limited support means heartbeats only (liveness signal, no per-stick counters).

v0.5.0 brought OpenBSD, NetBSD, DragonFly, and AIX up from limited to partial — each platform now has a native counter reader rather than relying on the Intelligent-Platform-Management-Interface (IPMI) fallback alone.

PlatformStatusTelemetry source
Linux (any distro) full Error-Detection-And-Correction (EDAC) sysfs: /sys/devices/system/edac/mc/*/dimm*/dimm_{ce,ue}_count. Dual-In-line-Memory-Module Decode (dmidecode) for manufacturer / part / serial.
Illumos (OmniOS, SmartOS, OpenIndiana) partial Fault-Management-Architecture (FMA): fmdump -e for ereport.cpu.*.cecc / ereport.cpu.*.uecc events with last-seen Event-Notification-Architecture (ENA) cursor; fmtopo for Dual-In-line-Memory-Module (DIMM) topology; prtdiag -v or croinfo for human-friendly slot locators.
Oracle Solaris partial Same FMA path as Illumos. Untested against current Solaris 11.4 — expected to work; please file a report.
FreeBSD partial Machine-Check-Exception (MCE) log via the mcelog port (pkg install mcelog); dmesg fallback when mcelog is absent (low fidelity).
DragonFly partial FreeBSD-shaped reader: mcelog port plus dmesg plus /var/log/messages with a byte-offset cursor. dmidecode port supplies per-stick metadata.
OpenBSD partial sysctl hw.sensors.* for any driver exposing ECC counters (ecc.N sensor names) plus a byte-offset cursor over /var/log/messages for kernel ECC / Machine-Check-Architecture (MCA) entries. The sysutils/dmidecode port supplies per-stick metadata when installed.
NetBSD partial envstat sensors (ECC counters on supported memory-controller drivers) plus a /var/log/messages cursor for MCA reports. sysutils/dmidecode from pkgsrc supplies per-stick metadata.
IBM Advanced-Interactive-eXecutive (AIX) partial errpt -a -J MEMORY_CONTROLLER with sequence-number cursor (only counts NEW events per tick); lscfg -vp for Vital-Product-Data (VPD): part number, serial, size, hardware-location code. Both ship in base AIX.
OpenBSD / NetBSD / DragonFly / AIX (IPMI fallback) limited When the native reader above returns empty, the agent still tries Intelligent-Platform-Management-Interface (IPMI) via ipmitool if a Baseboard-Management-Controller (BMC) device node (/dev/ipmi0) is present. Heartbeats fire as a liveness signal regardless.
macOS (Darwin) refused Current Apple silicon and recent Intel Macs ship no ECC RAM; Apple also publishes no Application-Programming-Interface (API) we could query on the rare units that do (some Intel-Xeon Mac Pro tower SKUs). --install exits 0 with a friendly message that links here; --tick exits 1. If you run an Intel-Xeon-era Mac Pro and disagree, please file an issue.

Our Salt-managed Linux fleet uses the salt state at foxhop-states/ecc-agent; non-Linux participants install via the curl one-liner below and our cron drop.

One-liner

# Download, inspect, then run with sudo. curl -fsSL https://ecc.unturf.com/install.sh > install.sh less install.sh # read it first sudo sh install.sh # then run it

The installer asks for a y confirmation before writing anything. If you want to script the install (no interactive prompt) use:

curl -fsSL https://ecc.unturf.com/install.sh | sudo sh -s -- -y

What the installer puts on your box

/usr/local/bin/ecc-agent      our POSIX shell agent (single file)
/etc/ecc-agent.conf           config — PUBLISH_ENABLED=false by default
/etc/cron.d/ecc-agent         single per-minute tick (self-schedules hourly chime)
/var/log/ecc-agent/           cron output goes here
/var/lib/ecc-agent/           agent state goes here

Nothing else. No daemons, no compiled binaries, no kernel modules, no inbound network ports. Read-only access to whichever ECC telemetry path the host exposes — see the supported-platforms table above.

Hosts without /etc/cron.d/ (some minimal containers, NetBSD, OpenBSD) need a manual crontab -e entry; copy the one line from /etc/cron.d/ecc-agent after install.

What it does at runtime

Per minute (--tick)

  1. Read EDAC sysfs files
  2. Diff against last tick's state
  3. Append to events.tsv ONLY if Correctable-Error (CE) or Uncorrectable-Error (UE) count increased
  4. If publishing: POST per-event JSON to capacitor
  5. Exit

~20-50 ms wall, single-digit MB Random-Access-Memory (RAM), zero network when memory is happy.

Hourly chime (inside --tick)

  1. If current minute = this host's chime minute (host-id derived, 0–59):
    • For each DIMM stick: sum minutes_observed + CE + UE for the previous hour
    • If publishing: POST heartbeat always, even all-zero
  2. Otherwise: skip the chime, just exit

~200-500 ms wall, 16-24 small JavaScript-Object-Notation (JSON) requests once per hour at your chime minute. Run ecc-agent --status to see it.

Daily totals for a typical healthy host: ~45 s Central-Processing-Unit (CPU), ~1 KB local log, ~25 KB network (if publishing).

Privacy & anti-extraction

What we always do

  • Open-source agent + capacitor (auditable, reproducible)
  • Default: local-only — first install does not POST anything
  • Hash every host identifier (sha256-truncated) before any post
  • Bucket geography wide — continent-scale region, altitude band
  • Publish daily anonymized data dumps so anyone can mirror

What we never do

  • Store hostnames, Internet-Protocol (IP) addresses, or exact locations
  • Require accounts, Application-Programming-Interface (API) keys, or login
  • Sell data or use it for advertising
  • Lock our software as proprietary
  • Refuse a withdrawal request

Manual install — for the careful

If you'd rather not pipe a shell script, here's the full recipe by hand:

sudo curl -fsSL https://ecc.unturf.com/install/ecc-agent.sh -o /usr/local/bin/ecc-agent
sudo chmod 0755 /usr/local/bin/ecc-agent
sudo mkdir -p /var/log/ecc-agent /var/lib/ecc-agent

# Inspect the agent before you trust it.
less /usr/local/bin/ecc-agent

# Write the config — keep PUBLISH_ENABLED=false for now.
sudo tee /etc/ecc-agent.conf >/dev/null <<'CONF'
LOG_DIR=/var/log/ecc-agent
STATE_DIR=/var/lib/ecc-agent
TICK_SECONDS=60
ECC_PROXY_URL="https://ecc.unturf.com/ingest"
PUBLISH_ENABLED=false
REGION=""
ALTITUDE_BAND=""
LOCATION_SOURCE="geoip"
CONF

# Cron: single per-minute tick.  The tick itself fires the hourly chime
# at this host's host-id-derived minute, so the fleet spreads load.
sudo tee /etc/cron.d/ecc-agent >/dev/null <<'CRON'
MAILTO=""
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
* * * * *  root  /usr/local/bin/ecc-agent --tick >> /var/log/ecc-agent/cron.log 2>&1
CRON

# First-run verify.
sudo /usr/local/bin/ecc-agent --tick

Verify it's working

# Status snapshot (config + current EDAC reading)
ecc-agent --status

# Last 20 events (anything written to events.tsv)
ecc-agent --tail 20

# Tail the cron log live
tail -f /var/log/ecc-agent/cron.log

Turn on publishing

The agent does nothing on the network by default. Once you've watched the local log for a day or so and you're comfortable with the data, flip the switch:

sudo sed -i 's/PUBLISH_ENABLED=false/PUBLISH_ENABLED=true/' /etc/ecc-agent.conf

The next hourly heartbeat will be the first POST. You can flip it back to false at any time and the agent stops contributing.

Uninstall

sudo rm -f /usr/local/bin/ecc-agent
sudo rm -f /etc/ecc-agent.conf
sudo rm -f /etc/cron.d/ecc-agent
# Optionally also remove your local logs + state:
sudo rm -rf /var/log/ecc-agent /var/lib/ecc-agent