A lightweight Go HTTP service for managing and monitoring the ZSNES (Super Nintendo emulator) process on Linux.
- Go 1.22+
- ZSNES installed at
/usr/bin/zsnes, or specify a custom path - (Optional) Flatpak with
io.github.xyproto.zsnesinstalled for containerized operation
# Default: launch ZSNES from /usr/bin/zsnes on port 8080
go run .
# Use Flatpak containerized ZSNES
go run . --use-flatpak
# Specify custom ZSNES path
go run . --zsnes-path=/opt/zsnes/zsnes
# Custom HTTP port
go run . --port=9090
# Combine flags
go run . --use-flatpak --port=9090Waffle exposes four REST endpoints for process control and monitoring:
curl -X POST http://localhost:8080/zsnes/start
# Response: {"ok": true}curl -X POST http://localhost:8080/zsnes/stop
# Response: {"ok": true}curl http://localhost:8080/zsnes/statusResponse:
{
"running": true,
"pid": 12345,
"started_at": "2025-11-21T10:30:45.123456Z",
"start_count": 5,
"stop_count": 4
}Fields:
running: Whether ZSNES is currently runningpid: Process ID (0 if not running)started_at: Timestamp when current process startedstart_count: Total number of Start() callsstop_count: Total number of Stop() callsexit_err: Error message from last process exit (if applicable)
curl http://localhost:8080/metricsResponse:
{
"timestamp": "2025-11-21T10:30:50.654321Z",
"pid": 12345,
"cpu_percent": 45.2,
"rss_bytes": 524288000,
"vsz_bytes": 2147483648,
"threads": 8
}Fields:
timestamp: When metrics were collectedpid: Process ID being monitoredcpu_percent: CPU usage as percentage (0% on first call for a process)rss_bytes: Resident Set Size in bytesvsz_bytes: Virtual Set Size in bytesthreads: Number of active threads
Note: The /metrics endpoint requires ZSNES to be running and returns a 400 error if not.
make build # Cross-compile for Linux amd64Output: ./waffle binary
make fmt # Format Go codeWaffle provides a simple HTTP interface to lifecycle-manage ZSNES with real-time performance monitoring:
- Process Management: Start and stop ZSNES either as a native binary or via Flatpak containerization
- Status Tracking: Monitor process state, start/stop counts, and last exit errors
- Metrics Collection: Real-time CPU, memory, and thread metrics from Linux
/procfilesystem
All state mutations are protected by mutexes for thread-safe concurrent access. The service has zero external dependencies—it uses only Go's standard library.
CPU percentage is calculated as: (ΔprocTicks / ΔsysTicks) × 100 × NumCPU
This approximates the behavior of tools like top across multiple CPU cores. The first metrics call for a process returns 0% due to insufficient historical data.
- RSS (Resident Set Size): Stored as page count in
/proc/[pid]/stat, converted to bytes using system page size - VSZ (Virtual Set Size): Stored directly in bytes
Native Mode (default):
- Launches ZSNES binary directly
- Graceful shutdown via SIGTERM signal
- Any non-zero exit code is treated as an error
Flatpak Mode (--use-flatpak):
- Launches via
flatpak run io.github.xyproto.zsnes - Termination via
flatpak kill io.github.xyproto.zsnes - Exit code 137 / SIGKILL (from flatpak kill) is treated as normal shutdown
- Other exit codes are treated as errors