Skip to content
Biraj-SarkarPublic

About

Lightweight infrastructure monitor

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

NetPulse — Lightweight Infrastructure Monitor

Python Agent → Flask Server → Live Dashboard
A self-hosted, real-time machine monitoring system built from scratch.


Overview

NetPulse collects live CPU, memory, disk, and process data from any number of machines and displays them on a web dashboard — similar in concept to Datadog or Grafana, but built entirely from scratch in Python and vanilla JavaScript.


Architecture

[Machine A: agent.py]  ──┐
[Machine B: agent.py]  ──┼──►  app.py  (POST /heartbeat)  ──►  live_servers{}
[Machine C: agent.py]  ──┘      Flask   (GET  /servers)   ──►  dashboard.html
Component File Technology Role
Agent agent.py Python + psutil Collects metrics, POSTs to server every 5s
Server app.py Python + Flask Receives data, serves API and dashboard
Alert logic alert.py Python Evaluates thresholds, returns OK / WARNING / CRITICAL
Frontend templates/ + static/ HTML + CSS + JS Polls /servers, renders live charts and tables

File Structure

netpulse/
├── agent.py            # Runs on every machine you want to monitor
├── alert.py            # Alert threshold logic (called by app.py)
├── app.py              # Flask server — API + serves the dashboard
├── config.py           # All configuration in one place
├── requirements.txt    # Python dependencies
├── README.md
├── static/
│   ├── charts.js       # Fetch, charts, and table logic
│   └── style.css       # Styles
└── templates/
    └── dashboard.html  # Main UI

Configuration

All settings live in config.py. Both agent.py and app.py import from it.

# config.py
CPU_THRESHOLD    = 80   # % — triggers CRITICAL alert
MEMORY_THRESHOLD = 85   # % — triggers WARNING alert
DISK_THRESHOLD   = 90   # % — reserved for future disk alerting
REFRESH_INTERVAL = 5    # seconds between dashboard polls

Note: SERVER_URL is no longer in config.py. The agent automatically detects its own LAN IP and builds the URL at runtime. See the Agent section below.


Requirements

Install all Python dependencies:

pip install -r requirements.txt

requirements.txt:

flask
flask-cors
psutil
requests

The dashboard has no dependencies — Chart.js loads from CDN automatically.


Running the Project

Step 1 — Start the Flask server

Run this once, on the machine that acts as your central server:

python app.py

⚠️ Always use python app.py, not flask run. The flask run command ignores the host="0.0.0.0" setting in the code and defaults to 127.0.0.1, which makes the server unreachable from other machines on the network.

Flask binds to 0.0.0.0:5000 — meaning it listens on all network interfaces, including your LAN IP. Open http://localhost:5000 in a browser to view the dashboard.

Step 2 — Start the agent on each machine

On every machine you want to monitor, run:

python agent.py

On startup, the agent prints its detected IP and the server URL it will POST to:

[NetPulse Agent] Starting — DESKTOP-ABC (192.168.0.107)  → http://192.168.0.107:5000/heartbeat

Machine cards appear on the dashboard automatically within one poll cycle.

Step 3 — View the dashboard

Open a browser and go to:

http://<server-ip>:5000

The Agent & SERVER_URL

agent.py automatically detects its own LAN IP using a UDP socket trick — no data is sent, it just forces the OS to reveal which network interface it uses for outbound traffic:

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]   # actual LAN IP, not 127.0.0.1

It then builds SERVER_URL from that IP:

SERVER_URL = f"http://{IP}:5000/heartbeat"

This works automatically when the agent and server run on the same machine. If you run the agent on a different machine, change the line to point at the server's LAN IP:

# agent.py — for remote machines
SERVER_URL = "http://192.168.0.107:5000/heartbeat"

Dashboard Features

Feature Description
Summary bar Total / Online / Offline / Critical counts, always visible at top
Machine cards One card per agent — live CPU, Memory, Disk bars with colour thresholds
Status badge ONLINE / OFFLINE — machine marked offline after 15s with no heartbeat
Alert indicator OK (green) · WARNING >75% memory (yellow) · CRITICAL >85% CPU or offline (red)
Detail panel Click any card — opens CPU and Memory line graphs (last 20 readings)
Process table Top 15 processes by CPU inside the detail panel, with inline bar chart
Overview table All machines in one scrollable table at the bottom — also clickable

Alert Logic

Evaluated server-side in alert.py on every GET /servers request. Thresholds are read from config.py.

Level Condition Colour
CRITICAL CPU > CPU_THRESHOLD or machine is offline 🔴 Red
WARNING Memory > MEMORY_THRESHOLD 🟡 Yellow
OK All metrics within thresholds and machine online 🟢 Green

API Reference

POST /heartbeat

Called by agent.py every REFRESH_INTERVAL seconds. Registers or updates a machine.

Request body:

{
  "name":      "DESKTOP-ABC",
  "ip":        "192.168.0.107",
  "cpu":       42.5,
  "memory":    67.2,
  "disk":      55.0,
  "processes": [{ "name": "python.exe", "cpu": 12.3 }]
}

Response: { "message": "received" } — HTTP 200


GET /servers

Called by the dashboard every REFRESH_INTERVAL seconds. Returns all known machines.

Response:

[
  {
    "name":      "DESKTOP-ABC",
    "ip":        "192.168.0.107",
    "cpu":       42.5,
    "memory":    67.2,
    "disk":      55.0,
    "status":    "online",
    "alert":     "OK",
    "processes": [...]
  }
]

GET /config

Called once by the dashboard on load to read the refresh interval.

Response: { "refresh_interval": 5 }


Troubleshooting

Agent says "Server not reachable"

  • Make sure you started the server with python app.py, not flask run
  • Confirm the server is running by opening http://<server-ip>:5000 in a browser
  • Check your firewall — port 5000 must be open for inbound TCP

Machine shows Offline immediately

  • Offline timeout is 15 seconds; the agent sends every 5s so this should not trigger normally
  • Check the agent terminal — it logs a timestamped line for every successful send

Process table shows "No process data"

  • On Linux, some processes require the agent to run with sudo to read CPU data

CPU always shows 0%

  • psutil always returns 0 on the very first cpu_percent() call — the agent primes it on startup with a 1-second sleep to fix this

Dashboard not loading charts.js or style.css

  • Make sure static/ and templates/ are in the same directory as app.py
  • Do not pass static_folder or template_folder arguments to Flask() — the default names are picked up automatically

Ideas for Extending

  • Persistent storage — Add SQLite or InfluxDB to keep history and plot graphs over hours or days
  • Email / Slack alerts — Fire a notification from alert.py when a machine hits CRITICAL
  • Authentication — Add Flask-Login so only you can view the dashboard
  • Docker — Package the server in a container for one-command deployment
  • Windows disk path — Change '/' in agent.py to 'C:\\' for Windows support
  • Public access — Deploy app.py to a VPS and point all agents at its public IP

About

Lightweight infrastructure monitor

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages