A comprehensive uptime monitoring system similar to BetterStack that monitors service availability and sends email notifications when services go down.
- Real-time Service Monitoring: Monitor multiple HTTP/HTTPS endpoints with customizable check intervals
- Health Checks: Automatic periodic health checks with configurable timeouts
- Status Dashboard: Beautiful React-based dashboard showing service status in real-time
- Email Notifications: Receive instant email alerts when services go down or recover
- Incident Tracking: Track and record all incidents with detailed history
- Response Time Monitoring: Monitor and record response times for each service
- SQLite Database: Lightweight database for storing service data and history
The dashboard displays all your monitored services with their current status (Operational, Degraded, or Down) similar to the BetterStack interface.
- Backend: Node.js + TypeScript + Express
- Frontend: React + TypeScript + Vite + Tailwind CSS
- Database: SQLite (better-sqlite3)
- Monitoring: Cron-based scheduler with axios for HTTP checks
- Notifications: Nodemailer for SMTP email notifications
- Node.js 18+
- npm or yarn
git clone <repository-url>
cd UptimeMonitorcd backend
npm installcd ../frontend
npm installCopy the example environment file and configure your settings:
cd ../backend
cp .env.example .envEdit .env and configure your email settings (optional):
# Server Configuration
PORT=3001
# SMTP Email Configuration (Optional)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=[email protected]
SMTP_PASSWORD=your-app-password
# Email Notification Settings
EMAIL_FROM=Uptime Monitor <[email protected]>
EMAIL_TO=[email protected],[email protected]Note: Email notifications are optional. If you don't configure SMTP settings, the monitor will still work but won't send email alerts.
- Enable 2-factor authentication on your Google account
- Generate an App Password: https://myaccount.google.com/apppasswords
- Use the app password in the
SMTP_PASSWORDfield
Terminal 1 - Backend:
cd backend
npm run devTerminal 2 - Frontend:
cd frontend
npm run devThe backend will start on http://localhost:3001 and the frontend on http://localhost:3000.
Build and run backend:
cd backend
npm run build
npm startBuild and serve frontend:
cd frontend
npm run build
npm run preview- Open the dashboard at
http://localhost:3000 - Click the "Add Service" button
- Fill in the service details:
- Name: A friendly name for your service (e.g., "Production API")
- URL: The URL to monitor (e.g., "https://v7q64nlrc4w3am-5002.proxy.runpod.net/v1/activation/single")
- Check Interval: How often to check (in seconds, minimum 30)
- Timeout: Maximum time to wait for response (in seconds)
- Click "Add Service"
The monitor will immediately start checking the service at the specified interval.
For the RunPod endpoint mentioned:
- Name:
Gemma-2-2B Activation - URL:
https://v7q64nlrc4w3am-5002.proxy.runpod.net/v1/activation/single - Check Interval:
60(check every minute) - Timeout:
30(30 second timeout)
The backend provides a REST API:
GET /api/services- Get all servicesGET /api/services/:id- Get service by IDPOST /api/services- Create new servicePUT /api/services/:id- Update serviceDELETE /api/services/:id- Delete servicePOST /api/services/:id/check- Manually trigger a health check
GET /api/status- Get overall system status
GET /api/incidents- Get all incidentsGET /api/services/:id/incidents- Get incidents for a specific service
GET /api/services/:id/checks- Get check history for a serviceGET /api/checks/recent- Get recent checks across all services
The application uses SQLite for data storage. The database file is created at backend/data/uptime.db.
- services: Stores service configurations and current status
- service_checks: Historical record of all health checks
- incidents: Tracks service outages and recoveries
- notification_settings: Notification configuration (future use)
- Operational: HTTP 200-299 response within timeout
- Degraded: Slow response (>80% of timeout) or 3xx/4xx status
- Down: 5xx errors, timeouts, or connection failures
- An incident is created when a service transitions from any status to "down"
- The incident is resolved when the service recovers
- Email notifications are sent for both down and recovery events
- Downtime duration is automatically calculated
UptimeMonitor/
├── backend/
│ ├── src/
│ │ ├── api/
│ │ │ └── routes.ts # API endpoints
│ │ ├── database/
│ │ │ └── schema.ts # Database initialization
│ │ ├── models/
│ │ │ └── Service.ts # Data models
│ │ ├── services/
│ │ │ ├── healthChecker.ts # Health check logic
│ │ │ ├── monitoringService.ts # Monitoring orchestration
│ │ │ └── notificationService.ts # Email notifications
│ │ └── index.ts # Server entry point
│ ├── data/ # SQLite database location
│ └── package.json
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ │ ├── Dashboard.tsx # Main dashboard
│ │ │ ├── ServiceCard.tsx # Service status card
│ │ │ └── AddServiceModal.tsx # Add service form
│ │ ├── api.ts # API client
│ │ ├── types.ts # TypeScript types
│ │ ├── App.tsx # Root component
│ │ └── main.tsx # Entry point
│ └── package.json
└── README.md
The notification system is designed to be extensible. To add new channels (Slack, Discord, etc.):
- Extend
NotificationServiceinbackend/src/services/notificationService.ts - Add configuration in
.env - Implement send methods for new channels
- Check your SMTP credentials in
.env - Ensure your email provider allows SMTP access
- For Gmail, make sure you're using an App Password
- Check the backend logs for error messages
- Wait for the first health check to complete
- Manually trigger a check using the refresh button
- Check that the service URL is accessible
- Ensure the
backend/datadirectory exists - Check file permissions
- Delete
uptime.dbto reset (you'll lose all data)
MIT License - see LICENSE file for details
Contributions are welcome! Please feel free to submit a Pull Request.