If you've ever worked with SNMP — testing NMS integrations, debugging trap handlers, or validating MIB structures — you know the pain. You end up juggling Net-SNMP CLI commands you can never remember, snmptrapd configs scattered everywhere, and a $500 MIB browser that still looks like it was designed in 2003.
I built Trishul SNMP to fix that. One Docker container. Browser-based. Free.
This post covers what's new in v1.2.4 — the biggest update yet — and why I built it this way.
What Is Trishul SNMP?
It's a self-hosted SNMP dev toolkit that combines five tools into one clean web UI:
| What | Instead of |
|---|---|
| SNMP Simulator (UDP agent) |
snmpsim + CLI config |
| Walk & Parse → JSON |
snmpwalk + manual OID lookup |
| Trap Sender + Receiver |
snmptrap + snmptrapd
|
| MIB Browser (tree view) | iReasoning MIB Browser ($500+) |
| MIB Manager (upload/validate) | Text editor + manual dependency hell |
Stack: Python 3.11, FastAPI, pysnmp, pysmi, Bootstrap 5, Docker.
# Install in one command
curl -fsSL https://raw.githubusercontent.com/tosumitdhaka/trishul-snmp/main/install-trishul-snmp.sh | bash
Then open http://localhost:8080. Default login: admin / admin123 — change it immediately in Settings.
What's New in v1.2.4
⚡ Real-Time WebSocket Push — Polling Is Dead
The biggest architectural change: the entire frontend is now event-driven.
Before: Every page polled the backend on a setInterval — dashboard every 30s, simulator every 5s. Stale data was common. Switching pages caused spinners.
After: A single persistent WebSocket connection at /api/ws. The backend broadcasts state changes the moment they happen. Dashboard, Simulator status, and Trap Receiver all update instantly — no refresh needed.
Browser ←──── WS push ────── FastAPI /api/ws
│
broadcasts on:
- trap received
- simulator start/stop
- MIB uploaded
- stats change
The navbar shows a live green dot when the WebSocket is healthy. On reconnect, the backend sends a full_state message to re-seed everything — so you never see stale data after a network hiccup.
Why this matters for devs: If you're building a trap handler and sending test traps from the UI, you now see the counter increment on the dashboard in real time. No F5 needed.
📊 Live Activity Stats Dashboard
A new 8-counter row on the dashboard shows everything happening in your session:
- SNMP Requests — Total polls served by the simulator
- OIDs Loaded — OIDs currently in memory across all loaded MIBs
- Traps Received / Sent — Live trap counters
- Walks Executed — How many SNMP walks you've run
- OIDs Returned — Total OIDs returned across all walks
- MIBs Uploaded / Times Reloaded — MIB management activity
All counters update via WebSocket push. They're also file-backed — they survive container restarts so you don't lose your session history.
⚙️ Settings — Three New Cards
App Behaviour
Two toggles: auto-start Simulator and auto-start Trap Receiver on container boot. Plus a configurable session timeout (60s–86400s). Settings persist to app_settings.json and take effect on next restart.
Stats Management
Export all counters as JSON (useful for logging test session results) or reset to zero for a clean baseline before a test run.
About
Version, author, and description pulled live from the backend — always in sync with what's actually deployed.
🐛 Notable Fixes
Timestamp bug: The Trap Receiver was showing 1970 for Last Received when the backend returned a Unix epoch 0. Now guarded and shown as --.
Traps Sent undercount: Stats were only incremented in the frontend — if you sent traps via API directly, the counter never moved. Fixed by broadcasting stats from the backend after every successful trap send.
Dashboard spinners on page switch: The WS full_state event fires before DashboardModule.init() registers its listener on page switch, so status tiles stayed as spinners until the next reconnect. Fixed by always seeding via REST on init, regardless of WS state.
MIB Browser state conflict: Navigating to the Browser from Walk & Parse (with a pre-filled OID) would sometimes log Could not find node because the previous session's pending tree state conflicted. Fixed by clearing pendingSelectedOid and pendingExpandedNodes when a programmatic OID search is present.
Who Is This For?
NMS / backend developers who need a real SNMP agent to poll without actual hardware, or need to fire specific trap OIDs to validate their handler code.
DevOps / integration engineers who need to test SNMP monitoring integrations in CI/staging environments.
Network engineers who want to explore MIB structures interactively — search by OID, by name, or by description — and understand what traps a device can fire before it's on the floor.
What It's NOT For
- Production 24/7 monitoring → use Zabbix, LibreNMS, PRTG
- Enterprise NMS → use SolarWinds, Cisco Prime
- High-availability trap collection at scale → use dedicated platforms
Trishul is a developer and testing tool, not a production monitoring system.
Quick Architecture
Browser (8080)
│ HTTP + WebSocket
▼
Nginx (static files + reverse proxy)
│ REST + WS
▼
FastAPI Backend (8000)
├── MIB Service (parse, validate, search)
├── SNMP Simulator (UDP 1061)
├── Trap Manager (send + receive on UDP 1162)
├── Walker (SNMP walk client)
└── WebSocket hub (/api/ws)
Everything runs in Docker with host network mode so the SNMP UDP ports (1061, 1162) are accessible directly from your local machine or test devices.
Try It
# One-command install
curl -fsSL https://raw.githubusercontent.com/tosumitdhaka/trishul-snmp/main/install-trishul-snmp.sh | bash
# Access at
http://localhost:8080
If it's useful, a ⭐ on GitHub goes a long way — it helps other devs find the project.
Happy to answer questions in the comments about architecture decisions, the pysnmp/pysmi integration, or the WebSocket implementation. 🔱
Top comments (0)