Skip to content

Latest commit

Β 

History

69 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PulseWatch β€” Self-hosted uptime monitoring with Telegram alerts, AI-explained incidents, public status pages, and Azure deployment

πŸ”­ PulseWatch

Self-hosted uptime monitoring with Telegram alerts, AI-explained incidents, and public status pages.

License: MIT Python React FastAPI Azure PostgreSQL AI



✨ What is PulseWatch?

PulseWatch Dashboard β€” real-time monitor fleet with KPI cards, status pills, and uptime metrics

PulseWatch is a self-hosted full-stack uptime monitoring platform for developers who want to know when their services break before users notice.

It continuously probes your endpoints, tracks uptime history, detects repeated failures, automatically opens and resolves incidents, sends alerts through multiple channels, and provides a public status page you can share with users.

PulseWatch also uses OpenRouter-powered AI to analyze the monitoring evidence collected when an incident occurs and generate a concise, plain-English explanation of the observed failure pattern.

πŸ”” Instant Alerts πŸ“Š Live Dashboard 🌐 Public Status πŸ€– AI Analysis
Telegram, Email, Discord, Slack, Webhooks Real-time KPIs, uptime %, response time Shareable status board with 3 themes OpenRouter-powered incident analysis
Notifications β†’ Dashboard β†’ Status Pages β†’ AI Explanations β†’

πŸš€ Quick Start

1. Clone the repository

git clone https://github.com/Robibiruk/PulseWatch.git
cd PulseWatch

2. Backend

cd backend

python3 -m venv .venv
source .venv/bin/activate

pip install -r requirements.txt

cp .env.example .env
nano .env

At minimum, configure:

DATABASE_URL=postgresql+asyncpg://...
SECRET_KEY=<long-random-secret>
CORS_ORIGINS=http://localhost:5173

Start FastAPI:

uvicorn main:app --reload --port 8000

The API runs at:

http://localhost:8000

Interactive API documentation:

http://localhost:8000/docs

3. Frontend

Open another terminal:

cd frontend
npm install
npm run dev

Open:

http://localhost:5173

Register an account and add your first monitor.


πŸ“Έ See It in Action

PulseWatch Login β€” dark theme with GitHub OAuth and email/password
Login
JWT authentication + GitHub OAuth
PulseWatch Dashboard β€” live monitor fleet with KPI cards
Dashboard
Real-time KPIs + monitor fleet
PulseWatch Public Status β€” shareable status board with service cards
Public Status Page
Auth-free shareable board with neon, light, and minimal themes

⚑ Features

Category What you get
HTTP Monitoring HTTP/HTTPS checks, configurable intervals, timeouts, redirects, HTTP methods, authentication, and status-code rules
Heartbeat Monitoring Push-based monitoring for cron jobs, workers, and background services
SSL Monitoring SSL/TLS error detection and certificate expiry monitoring
Domain Monitoring Domain expiry reminders
Alerts Telegram, Email, Discord, Slack, and generic JSON webhooks
Dashboard Real-time KPIs, uptime percentage, response times, filters, and monitor fleet
Incidents Automatic incident creation, recovery detection, duration tracking, and incident history
AI Analysis OpenRouter-powered incident explanations based on actual monitoring evidence
Status Pages Public, authentication-free status pages with three visual themes
Telegram Bot /status, /monitors, /incidents, /pause, /resume, and /help
Authentication Email/password, JWT authentication, bcrypt password hashing, GitHub OAuth, and API tokens
Monitor Configuration Timeout, redirects, IP version, authentication, HTTP method, accepted status codes, and tags

πŸ— Architecture

PulseWatch production architecture β€” Vercel frontend, Azure Linux VM backend, PostgreSQL, OpenRouter AI, Telegram and notification services

Production architecture

PulseWatch currently runs as a self-hosted production deployment on an Azure Linux VM.

The frontend is deployed separately and communicates with the FastAPI backend running on the Azure VM.

The Azure VM provides the persistent compute required for:

  • FastAPI
  • The continuous monitoring worker
  • Telegram long-polling
  • Incident processing
  • Notification dispatch

The production deployment uses a fresh PostgreSQL database for persistent application and monitoring data.

Neon is not used by the current production deployment.

OpenRouter is connected to the backend for AI-powered incident analysis.

@startuml

skinparam backgroundColor #0a0a0a skinparam componentStyle rectangle

rectangle "Vercel\nReact + Vite + TypeScript" as FE

rectangle "Azure Linux VM" { component "FastAPI API" as API component "Monitoring Worker" as Worker database "PostgreSQL\nProduction Database" as DB component "Telegram Bot" as TG }

component "OpenRouter\nGPT-OSS-20B" as AI component "Notifications" as N

FE --> API : REST + JWT API --> DB Worker --> DB Worker --> TG Worker --> AI Worker --> N

@enduml

Azure VM

The Azure VM is the persistent compute layer of the current production deployment.

Unlike a sleeping application instance, the VM provides a continuously running environment for the monitoring engine.

The VM currently hosts:

Azure Linux VM
β”œβ”€β”€ FastAPI backend
β”œβ”€β”€ Continuous monitoring worker
β”œβ”€β”€ Telegram bot
└── PostgreSQL

This allows PulseWatch to continuously monitor external services without depending on a sleeping free-tier worker.

Monitoring pipeline

Scheduler
    ↓
Find due monitors
    ↓
Claim monitor
    ↓
HTTP / HTTPS / Heartbeat probe
    ↓
Save check result
    ↓
Update monitor state
    ↓
Failure threshold reached?
    β”œβ”€β”€ No β†’ schedule confirmation check
    β”‚
    └── Yes
          ↓
      Create incident
          ↓
      Analyze monitoring evidence
          ↓
      OpenRouter AI explanation
          ↓
      Send notifications

Claim-based worker design

The monitoring scheduler uses database-backed monitor claims.

For PostgreSQL deployments, due monitors use row-level locking with SKIP LOCKED. A short lease prevents another worker from processing the same monitor simultaneously.

This provides a foundation for horizontal worker scaling without producing duplicate checks or duplicate alerts.


🚒 Production Deployment

Current production stack

Component Host Purpose
Frontend Vercel React + Vite web application
Backend API Azure Linux VM FastAPI REST API
Monitoring Worker Azure Linux VM Continuous uptime checks and incident detection
Telegram Bot Azure Linux VM Long-polling commands and Telegram alerts
Database PostgreSQL Persistent application and monitoring data
AI OpenRouter Incident explanation and analysis
Email Resend Email notifications
Notifications Discord / Slack / Webhooks Additional alert channels

Azure deployment

The production backend is hosted on an Azure Linux virtual machine.

Azure provides the persistent compute environment for PulseWatch's API, monitoring worker, Telegram bot, and production database.

The VM is particularly important for PulseWatch because uptime monitoring requires a process that stays alive continuously.

The architecture therefore avoids depending on a sleeping application instance for the core monitoring loop.

Production database

The current deployment uses a fresh PostgreSQL database.

It is not connected to Neon.

The database stores:

  • User accounts
  • Monitors
  • Historical checks
  • Incidents
  • AI explanations
  • Telegram connections
  • Notification settings
  • Public status pages
  • API tokens

Frontend deployment

The React frontend is deployed separately and communicates with the Azure-hosted API through:

VITE_API_BASE=https://your-api-domain

Backend deployment

The Azure VM runs the backend services required for PulseWatch:

Azure VM
β”‚
β”œβ”€β”€ FastAPI API
β”œβ”€β”€ Monitoring Worker
β”œβ”€β”€ Telegram Bot
└── PostgreSQL

A production process manager such as systemd can be used to keep services alive and automatically restart them after failures or reboots.


πŸ€– AI Incident Explanations

PulseWatch uses OpenRouter to analyze the evidence collected when a monitor enters an incident state.

The AI is not responsible for detecting outages. The monitoring engine detects the outage first.

The flow is:

Monitor failure
      ↓
Failure threshold reached
      ↓
Incident created
      ↓
Monitoring evidence collected
      ↓
OpenRouter
      ↓
AI explanation
      ↓
Incident alert

Current model

openai/gpt-oss-20b

The model is configured through:

OPENROUTER_MODEL=openai/gpt-oss-20b

Evidence sent to the model

When an incident is created, PulseWatch can provide evidence such as:

  • Current HTTP status code
  • Current error
  • Recent HTTP status codes
  • Failure pattern

For example:

Current HTTP status: 503
Current error: Service unavailable
Recent HTTP status codes: [200, 200, 503, 503, 503]

The model can recognize the observed transition:

200 β†’ 200 β†’ 503 β†’ 503 β†’ 503

and explain that the monitored service was previously responding successfully before returning consecutive 503 responses.

What the AI can and cannot know

The AI explanation is evidence-based, not a magical root-cause detector.

PulseWatch does not currently provide the model with:

  • Application logs from the monitored service
  • CPU metrics from the monitored service
  • Memory metrics
  • Database internals
  • Server process information
  • Cloud infrastructure metrics

Therefore, the AI should not claim that it knows the exact root cause.

For example, a sequence of 503 responses may be consistent with:

  • Application failure
  • Resource exhaustion
  • Dependency failure
  • Temporary service unavailability

These are possible explanations, not confirmed facts unless the monitoring evidence supports them.

Example AI output

For:

HTTP 503
Error: Service unavailable
Recent: [200, 200, 503, 503, 503]

the AI may produce an explanation identifying:

  1. The currently observed 503 failure.
  2. The transition from successful responses to consecutive failures.
  3. Plausible underlying causes.
  4. What evidence is missing.
  5. A practical recovery estimate.

This makes the AI output useful while avoiding false certainty.

Graceful fallback

If OpenRouter is unavailable, misconfigured, or no API key is provided, PulseWatch falls back to deterministic rule-based explanations.

Supported fallback conditions include:

  • HTTP 500
  • HTTP 502
  • HTTP 503
  • HTTP 504
  • Connection failures
  • DNS failures
  • Request timeouts

The monitoring engine and incident system therefore continue functioning even when the AI service is unavailable.


πŸ”§ Environment Variables

Core

Variable Default Description
DATABASE_URL (required) PostgreSQL async URL or SQLite development URL
SECRET_KEY dev-insecure-change-me JWT signing secret
CORS_ORIGINS http://localhost:5173 Comma-separated allowed browser origins

Worker / Scheduler

Variable Default Description
POLL_INTERVAL 15 Scheduler tick interval in seconds
WORKER_CONCURRENCY 20 Maximum concurrent monitor checks
NO_WORKER false Disable the built-in worker
FAILURE_THRESHOLD 3 Consecutive failures required before opening an incident
CONFIRMATION_DELAY 10 Delay before confirmation/recovery checks

Telegram

Variable Default Description
TELEGRAM_BOT_TOKEN "" Telegram bot token from BotFather
NO_TELEGRAM_BOT false Disable the Telegram bot

Email

Variable Default Description
RESEND_API_KEY "" Resend API key
ALERT_FROM_EMAIL alerts@yourdomain.com Verified sender address

AI

Variable Default Description
OPENROUTER_API_KEY "" OpenRouter API key
OPENROUTER_MODEL openai/gpt-oss-20b Model used for incident analysis

Frontend

Variable Default Description
VITE_API_BASE http://localhost:8000 Backend API base URL

Full configuration is available in backend/.env.example.


πŸ“‘ API Reference

All authenticated routes require:

Authorization: Bearer <jwt>
Method Path Description
POST /auth/register Register account
POST /auth/token Login and obtain JWT
GET /auth/me Get current user
GET /monitors List monitors
POST /monitors Create monitor
PATCH /monitors/:id Update monitor
DELETE /monitors/:id Delete monitor
GET /monitors/summary Monitor fleet KPIs
GET /monitors/incidents Recent incidents
GET /status/:userId Public status board
POST /api/heartbeat/:token Send heartbeat
GET /status/health API health check
POST /api/platform/tokens Create API token
POST /api/platform/account/password Change password

Interactive Swagger documentation:

http://localhost:8000/docs

πŸ€– Telegram Bot

PulseWatch's Telegram bot uses long-polling, so no webhook configuration is required.

Command Description
/start <token> Connect Telegram to your PulseWatch account
/status Show monitor status
/monitors List monitors
/incidents Show recent incidents
/pause Pause alerts
/resume Resume alerts
/help Show available commands

Connecting Telegram

Dashboard
    ↓
Settings
    ↓
Connect Telegram
    ↓
Open Telegram deep link
    ↓
Press Start
    ↓
Account linked

πŸ“¬ Notifications

PulseWatch can send incident and recovery notifications through:

  • Telegram
  • Email
  • Discord
  • Slack
  • Generic JSON webhooks

When a monitor reaches the failure threshold:

Monitor failure
      ↓
Failure threshold reached
      ↓
Incident created
      ↓
AI explanation generated
      ↓
Notification dispatched

When the monitor recovers:

Service recovers
      ↓
Incident resolved
      ↓
Recovery duration calculated
      ↓
Recovery notification sent

πŸ§ͺ Monitor Types

HTTP / HTTPS

HTTP monitors support:

  • Configurable check interval
  • Request timeout
  • HTTP methods
  • Redirect following
  • IPv4 / IPv6 / automatic selection
  • Basic authentication
  • Bearer authentication
  • Accepted status-code groups
  • SSL/TLS checks
  • SSL certificate expiry reminders
  • Domain expiry reminders
  • Response-time tracking

Heartbeat

Heartbeat monitoring is designed for services that cannot be continuously probed through a normal HTTP endpoint.

Your application sends a request to:

POST /api/heartbeat/:token

If PulseWatch does not receive a heartbeat within the expected interval, the monitor is considered down and an incident can be opened.

This is useful for:

  • Cron jobs
  • Background workers
  • Scheduled scripts
  • Data pipelines
  • Internal services

❀️ Reliability

PulseWatch uses a failure threshold to reduce false alarms.

With the default configuration:

Failure #1 β†’ no incident
Failure #2 β†’ no incident
Failure #3 β†’ incident opened

A temporary one-request failure therefore does not immediately trigger an outage alert.

When the service starts responding again:

Service recovers
      ↓
Incident resolved
      ↓
Recovery duration calculated
      ↓
Recovery notification sent

πŸ” Production Security Checklist

Before exposing a deployment publicly:

  • Set SECRET_KEY to a long random value
  • Set CORS_ORIGINS to the real frontend domain
  • Never use CORS_ORIGINS=* in production
  • Use PostgreSQL for production
  • Keep .env out of Git
  • Rotate API keys if they are accidentally exposed
  • Keep TELEGRAM_BOT_TOKEN private
  • Keep OPENROUTER_API_KEY private
  • Put the API behind HTTPS
  • Use a reverse proxy such as Nginx or Caddy
  • Add rate limiting to authentication and public endpoints
  • Keep the Azure VM and system packages updated
  • Configure automatic service restart with systemd
  • Restrict unnecessary Azure VM inbound ports
  • Configure PostgreSQL backups
  • Monitor the PulseWatch worker itself

Generate a strong secret with:

python3 -c "import secrets; print(secrets.token_urlsafe(48))"

πŸ“ Project Layout

PulseWatch/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ main.py              # FastAPI app + lifespan
β”‚   β”œβ”€β”€ worker.py            # Monitoring scheduler and incident engine
β”‚   β”œβ”€β”€ checker.py           # HTTP, SSL and domain checks
β”‚   β”œβ”€β”€ telegram_bot.py      # Telegram bot + account linking
β”‚   β”œβ”€β”€ notifications.py     # Alert dispatch and notification formatting
β”‚   β”œβ”€β”€ emailer.py           # HTML email templates
β”‚   β”œβ”€β”€ ai_explain.py        # OpenRouter AI incident analysis
β”‚   β”œβ”€β”€ models.py            # SQLAlchemy ORM models
β”‚   β”œβ”€β”€ schemas.py           # Pydantic schemas
β”‚   β”œβ”€β”€ database.py          # Database engine and initialization
β”‚   β”œβ”€β”€ config.py            # Application configuration
β”‚   β”œβ”€β”€ requirements.txt      # Python dependencies
β”‚   └── routers/
β”‚       β”œβ”€β”€ auth.py
β”‚       β”œβ”€β”€ monitors.py
β”‚       β”œβ”€β”€ status.py
β”‚       β”œβ”€β”€ telegram.py
β”‚       β”œβ”€β”€ heartbeat.py
β”‚       β”œβ”€β”€ statuspage.py
β”‚       β”œβ”€β”€ notifications.py
β”‚       └── platform.py
β”‚
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ App.tsx
β”‚   β”‚   β”œβ”€β”€ api.ts
β”‚   β”‚   β”œβ”€β”€ auth.tsx
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   └── pages/
β”‚   └── vite.config.ts
β”‚
β”œβ”€β”€ docs-site/
β”‚   β”œβ”€β”€ docs/
β”‚   └── blog/
β”‚
β”œβ”€β”€ docs/
β”‚   β”œβ”€β”€ diagrams/
β”‚   └── screenshots/
β”‚
└── README.md

πŸ—Ί Roadmap

Reliability

  • Alembic migrations
  • Durable job queue
  • Second-region confirmation
  • Rate limiting
  • Better worker supervision
  • Monitoring worker health
  • Automated PostgreSQL backups

Features

  • Incident acknowledgement
  • Maintenance windows
  • Escalation policies
  • Monitor tags and groups
  • Longer-term SLA charts
  • Team accounts and RBAC
  • More notification integrations

Infrastructure

  • Docker / Docker Compose deployment
  • Automated Azure deployment
  • Automated PostgreSQL backup and recovery
  • Multi-region monitoring
  • Distributed workers

Scaling

Current
β”‚
β”œβ”€β”€ Azure Linux VM
β”œβ”€β”€ PostgreSQL
β”œβ”€β”€ 1 monitoring worker
└── Continuous monitoring
        β”‚
        β–Ό
Next
β”‚
β”œβ”€β”€ Durable queue
β”œβ”€β”€ Multiple workers
└── Better failure isolation
        β”‚
        β–Ό
Future
β”‚
β”œβ”€β”€ Multiple regions
β”œβ”€β”€ Distributed workers
└── Large-scale monitoring

πŸ‘€ Built by


πŸ“„ License

License: MIT

MIT License β€” see LICENSE for details.


⬆ Back to top

About

Self-hosted uptime monitoring with Telegram alerts, AI-explained incidents, and public status pages. Built with FastAPI + React/Vite/TypeScript and deployed on an **Azure Linux VM** with a dedicated PostgreSQL database.

Topics

Resources

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages