Open source · AGPL-3.0 ·v0.3.47

Network monitoring built for tens of thousands of nodes.

Yagra is an open-source NMS written in Rust. ICMP, SNMP v2c/v3, HTTP and API checks; distributed pollers; alerting that won’t flood your on-call. It ships as Docker containers and scales out by config, not rewrite.

Rust · Tokio · Axum · React · PostgreSQL · VictoriaMetrics · NATS

Capabilities

One system, from liveness to flow.

Active and passive monitoring, discovery, alerting, and traffic analysis — designed to stay honest and quiet at scale.

Active monitoring

  • ICMP liveness over raw sockets
  • SNMP v2c and v3 (USM), GETBULK per-interface
  • HTTP / URL checks: response time, body keyword, JSON values, TLS expiry
  • DNS name resolution with CNAME-chain history
  • Cisco Meraki via the read-only Dashboard API: organizations import and file their own devices
  • Huawei and Cisco wireless controllers: every access point as a node, radios as ports, SSIDs with history
  • Interval jitter and per-device rate limiting

Discovery & classification

  • IP-range discovery with a credential finder
  • Sweeps you can route to a site, leave and come back to, and stop mid-run
  • A folder tree pulled read-only from NetBox: regions, sites, site codes, and the subnets a sweep can be aimed at
  • Auto-classification by sysObjectID / sysDescr
  • Corrected classification rules re-run on nodes already in the tree
  • A network map derived from CDP/LLDP, subnets, OSPF and BGP
  • Unregistered devices from CDP/LLDP neighbors, OSPF/BGP peers, syslog/trap senders and ARP caches — detected and added from their row
  • Editable device profiles and collection templates
  • Classification rules and a curated MIB/OID catalog

Alert quality

  • Dwell-time hysteresis and flapping detection
  • Memory, CPU and temperature judged per pool, CPU and sensor, with rules that name the row
  • Dependency suppression with root-cause roll-up
  • Let Yagra derive the dependency graph — preview what changes first
  • Maintenance windows, mutes, dedup and grouping
  • PagerDuty and Jira Service Management forwarding, carrying your node tags
  • A delivery log that says whether each notification arrived, and on whose side it failed

Passive events

  • Syslog (RFC 5424 / 3164) and inbound webhooks
  • SNMP v1/v2c traps + informs, OID→name decoded
  • Operator rules: severity, auto-close TTL, clear-pattern
  • Full-text event search over VictoriaLogs
  • Forward it onward: filtered tee to a SIEM, or rows into BigQuery

Traffic flow

  • NetFlow v5/v9, IPFIX and sFlow v5 into ClickHouse
  • Top talkers, ports and protocols
  • AS conversations (Sankey) with offline IP→ASN enrichment
  • Click any dimension to filter the flows

Operator UX

  • Customizable shared and per-user dashboards
  • Chart every metric a device reports, not only the anticipated ones
  • Topology and dependency maps
  • Reports to HTML, CSV and PDF, on a schedule
  • Upgrade from the WebUI: backup, install, verify — remote sites included
  • Full mobile parity, EN/日本語, light and dark

AI & automation

  • Built-in MCP server for AI assistants, on from the first boot
  • Query status, metrics, flow and events; run Troubleshoot analyses
  • Audited write actions: ack, maintenance, poll — never device config
  • API tokens with role scope; per-tool RBAC
Architecture

Decoupled from day one.

Core and pollers talk only through the bus, so pollers are stateless, horizontally scalable, and deployable at remote sites across NAT and firewalls. They poll outward and receive passive intake inward — syslog, traps and flow exports — and each kind of data lands in the store built for it.

WebUIbrowserCoreorchestration · REST APIAlertTopologyDiscoveryForwardSecretsBusTelemetryNATSmessage brokerPollerpool · A / pool · BTransportIngestDiscoveryBusTelemetryNetworkdevicesRESTICMP · SNMP · APIsyslog · SNMP traps · NetFlow · sFlowPostgreSQLmetadataRedisephemeral stateVictoriaMetricsmetricsVictoriaLogseventsClickHouseflows

Core never calls a poller directly, and receives no device traffic of its own: syslog, SNMP traps and flow exports all land on a poller at the edge — including remote-site pollers behind NAT — and reach core over the bus. Inbound webhooks are the one exception, arriving straight on the API. NATS is the broker itself, a backing service like the stores; Bus is the client crate compiled into core and into every poller, which is why it appears in both.

Components

Every one of these appears in the diagram above. Core, Poller and the WebUI are the processes you deploy; the small boxes drawn inside them are the Rust crates each process is built from, and the tag repeats which process that is.

Corecore
Orchestration, scheduling, northbound REST API
Pollerpoller
ICMP/SNMP/API polling and passive intake — stateless, horizontally scalable
WebUIbrowser
Dashboards and visualization (React + TypeScript)
Buscore + poller
Job distribution and poller fan-out over NATS
Transportpoller
One abstraction over ICMP, SNMP and HTTP device I/O
Topologycore
Dependency graph powering suppression and the network map
Discoverycore + poller
Device discovery and classification
Alertcore
State machine, hysteresis, dependency suppression
Ingestpoller
Syslog, SNMP-trap and flow parsing; edge rate limiting
Forwardcore
Filtered tee of received events and flows to external collectors
Secretscore
Envelope-encrypted device credentials — only core holds the key
Telemetrycore + poller
Structured logs, Prometheus metrics, OpenTelemetry traces
Scale & resilience

Built to grow without a rewrite.

The MVP runs co-located in a few containers; the same build scales out to distributed pollers and highly available stores by configuration.

50,000nodes verified in load testing
Poolslocation-affinity poller assignment
Partitionride-out with metric backfill
HAcore leader election and failover

Pollers hold no per-target state, so the coordinator assigns nodes across live pollers by consistent hashing and reassigns on heartbeat loss. Standing one up at a remote site is done from the WebUI: one switch encrypts and authenticates the bus, and issuing that poller a token downloads everything the site needs as a single archive — unpack it and start it. Remote pollers dial out to a central bus and buffer results through a network partition — replaying metrics on reconnect, while alerts are never backfilled so a recovered link can’t flood you with stale events.

Security posture

The WebUI is HTTPS out of the box — import your own certificate from the UI, with no restart. Monitoring credentials are envelope-encrypted (AES-256-GCM) with the key held outside the database. Single sign-on via OIDC — with guided setup for Microsoft Entra ID, Okta and Google Workspace that asks only for what each product needs — sign-in against LDAP or Active Directory, role-based access control, an immutable audit log, and per-poller-scoped bus credentials. The advanced distribution and HA features are opt-in — defaults stay conservative and backward-compatible.

Quickstart

One file. No build.

Fetch the Compose file and start it. That pulls the published images and brings up core, a poller, the WebUI and the backing stores (PostgreSQL, Redis, NATS, VictoriaMetrics) — no repository checkout, nothing to compile.

  • WebUIhttps://localhost
  • APIhttp://localhost:8080
Read the getting-started guide →
$ mkdir yagra && cd yagra
$ curl -fsSL -o docker-compose.deploy.yml \
    https://github.com/horryworks/Yagra/releases/latest/download/docker-compose.deploy.yml
$ docker compose -f docker-compose.deploy.yml up -d

First start prints a one-time admin password to the core logs:

docker compose -f docker-compose.deploy.yml logs core

Published images:

ghcr.io/horryworks/yagra-core
ghcr.io/horryworks/yagra-poller
ghcr.io/horryworks/yagra-web
Open source

Built in the open, under AGPL-3.0.

Read the source, run it yourself, and follow every release on GitHub. No sign-up, no telemetry wall. v0.3.0 restructured the backend for the people who do read it: the largest files were split along the lines their contents already followed, and each new boundary is held by a test that fails the build when something crosses it.

Open beta: bug reports and questions go to GitHub Issues, the only contact channel for the project — there is no contact e-mail address. Pull requests are not being accepted at this time.