Listen to your servers scream in agony through a MIDI synthesizer
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Python 100.0%
1 1 0

Clone this repository

https://tangled.org/meson.ninja/snmp-midi https://tangled.org/did:plc:z6b4y3evxxb5ufbfn5pa65fa/snmp-midi
git@tangled.org:meson.ninja/snmp-midi git@tangled.org:did:plc:z6b4y3evxxb5ufbfn5pa65fa/snmp-midi

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

snmp-midi#

Polls server metrics via SNMP and plays them as MIDI notes. Each stat maps to an instrument on its own channel — pitch tracks the value, velocity tracks intensity. The result is an ambient, real-time sonic portrait of a running server.

Features#

  • Maps CPU, memory, disk, network, and process stats to MIDI instruments
  • Per-core CPU load and multi-timescale load averages (1min / 5min / 15min)
  • Configurable scales, octaves, note durations, and velocity ranges
  • Cascade stagger: voices roll in sequentially each poll cycle
  • Optional threshold triggers for alert notes
  • Works with hardware synths, virtual ports, or any MIDI-capable DAW
  • Roland GS reset on startup for hardware synth initialization

Requirements#

  • Python 3.8+
  • SNMP-enabled server (snmpd with UCD-SNMP-MIB and HOST-RESOURCES-MIB)
  • MIDI output: hardware synth, software synth (FluidSynth), or DAW

Installation#

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Quick Start#

# Copy example config and edit with your server details
cp config.example.yaml config.yaml
$EDITOR config.yaml

# List available MIDI ports
./main.py -l

# Run (port number from -l output)
./main.py -P 0

Usage#

./main.py [options]

  -c FILE       Config file (default: config.yaml)
  -g            Write default config to FILE and exit
  -l            List MIDI ports and exit
  -H HOST       SNMP host (overrides config)
  -p PORT       SNMP port (overrides config)
  -C STR        SNMP community string (overrides config)
  -P NUM        MIDI port by index number
  -m NAME       MIDI port by name
  -v            Use virtual MIDI port
  -i SECS       Poll interval in seconds (overrides config)

Configuration#

Copy config.example.yaml to config.yaml and edit. The config.yaml file is gitignored so credentials stay local.

Available stat types#

stat_name stat_key Description
cpu_load 1-minute load average
cpu_load_5min 5-minute load average
cpu_load_15min 15-minute load average
per_core_cpu_load core0, core1, … coreN Per-core CPU % (hrProcessorLoad)
memory_usage percent, total, available, cached Memory stats (UCD-SNMP-MIB)
disk_usage percent, size, used First mounted filesystem
network_stats in_bytes, out_bytes Cumulative octets (IF-MIB)
process_count hrSystemProcesses

Scales#

major · minor · pentatonic_major · pentatonic_minor · blues · dorian · mixolydian · chromatic

Mapping fields#

mappings:
  - stat_name: cpu_load          # stat type (see table above)
    stat_key: null               # sub-key within stat, if applicable
    channel: 0                   # MIDI channel 0–15
    program: 73                  # GM program number 0–127
    scale: pentatonic_major      # musical scale
    root: C                      # root note
    octave: 5                    # base octave
    min_value: 0                 # value mapped to lowest scale note
    max_value: 10                # value mapped to highest scale note
    note_duration: 1.0           # seconds (must be < poll_interval)
    cc_number: null              # also send value as CC, or null
    enabled: true

Threshold triggers#

triggers:
  - stat_name: cpu_load
    threshold: 8.0
    above: true
    note: 72
    velocity: 127
    channel: 0
    duration: 0.5

Timing#

note_duration must be less than poll_interval or note-off threads from earlier polls will cancel newer notes before slow-attack instruments sound. Use onboard reverb to blur the gaps between notes.

Setting Up snmpd#

sudo apt-get install snmpd snmp-mibs-downloader

/etc/snmp/snmpd.conf minimal additions:

rocommunity public 127.0.0.1
rocommunity public 192.168.0.0/16
sudo systemctl restart snmpd
# Test
snmpwalk -v2c -c public localhost 1.3.6.1.2.1.1.1.0

Connecting a Synthesizer#

Hardware synth: connect via USB-MIDI or DIN, then ./main.py -l to find the port index.

FluidSynth:

sudo apt-get install fluidsynth fluid-soundfont-gm
fluidsynth -a alsa -m alsa_seq /usr/share/sounds/sf2/FluidR3_GM.sf2 &
./main.py -l
./main.py -P <port number>

DAW: create a virtual MIDI port in your DAW, then ./main.py -m "port name".

License#

MIT