Skip to content

Scalable API health monitoring system focused on reliability, trust, and secure infrastructure, deployed on AWS using Terraform.

Notifications You must be signed in to change notification settings

sAchin-680/HyperVerge-api-health-monitor-system

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

36 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

HyperVerge API Health Monitor System

A production-grade distributed API health monitoring system with real-time alerting, incident management, and full observability.

Features

  • Real-time Monitoring β€” Continuous health checks at configurable intervals
  • Incident Detection β€” Automatic threshold-based incident creation and tracking
  • Multi-channel Alerts β€” Email and webhook notifications with retry mechanisms
  • Full Observability β€” Prometheus metrics, structured logging, health endpoints
  • Horizontal Scaling β€” Microservices architecture with BullMQ job queues
  • Modern Dashboard β€” Next.js web interface for monitor management

Architecture

System Overview

                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚                        INFRASTRUCTURE                           β”‚
                                    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
                                    β”‚  β”‚                         AWS / Docker                        β”‚β”‚
                                    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                    β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                                                           β”‚                                                           β”‚
        β–Ό                                                           β–Ό                                                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   FRONTEND    β”‚                                          β”‚   BACKEND     β”‚                                          β”‚   WORKERS     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€                                          β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€                                          β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚               β”‚         HTTP/REST                        β”‚               β”‚           Job Queue                      β”‚               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  │────────────────────────────────────────▢│  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  │─────────────────────────────────────────▢│  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ Next.js β”‚  β”‚                                          β”‚  β”‚ Express β”‚  β”‚                                          β”‚  β”‚ Worker  β”‚  β”‚
β”‚  β”‚   Web   β”‚  │◀────────────────────────────────────────│  β”‚   API   β”‚  β”‚                                          β”‚  β”‚ Process β”‚   β”‚
β”‚  β”‚   App   β”‚  β”‚         JSON Response                    β”‚  β”‚ :4000   β”‚  β”‚                                          β”‚  β”‚ :4001   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚                                          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚                                          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚    :3000      β”‚                                          β”‚       β”‚       β”‚                                          β”‚       β”‚       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                          β”‚       β”‚       β”‚                                          β”‚       β”‚       β”‚
                                                           β”‚       β–Ό       β”‚                                          β”‚       β–Ό       β”‚
                                                           β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚                                          β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
                                                           β”‚  β”‚Schedulerβ”‚  β”‚                                          β”‚  β”‚Incident β”‚  β”‚
                                                           β”‚  β”‚ Service β”‚  β”‚                                          β”‚  β”‚ Manager β”‚  β”‚
                                                           β”‚  β”‚ :4002   β”‚  β”‚                                          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
                                                           β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚                                          β”‚       β”‚       β”‚
                                                           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                          β”‚       β–Ό       β”‚
                                                                    β”‚                                                 β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
                                                                    β”‚                                                 β”‚  β”‚Notifier β”‚  β”‚
                                                                    β”‚                                                 β”‚  β”‚ Service β”‚  β”‚
                                                                    β”‚                                                 β”‚  β”‚ :4003   β”‚  β”‚
                                                                    β”‚                                                 β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
                                                                    β”‚                                                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                    β”‚                                                         β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                                                           β”‚
        β–Ό                                                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                    DATA LAYER                                                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                                                               β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”‚
β”‚   β”‚            PostgreSQL               β”‚                              β”‚              Redis                  β”‚                β”‚
β”‚   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€                              β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€                β”‚
β”‚   β”‚  β€’ Users & Authentication           β”‚                              β”‚  β€’ BullMQ Job Queues                β”‚                β”‚
β”‚   β”‚  β€’ Monitors Configuration           β”‚                              β”‚  β€’ health-check-queue               β”‚                β”‚
β”‚   β”‚  β€’ Health Check Results             β”‚                              β”‚  β€’ notification-queue               β”‚                β”‚
β”‚   β”‚  β€’ Incidents & Alerts               β”‚                              β”‚  β€’ Dead Letter Queue (DLQ)          β”‚                β”‚
β”‚   β”‚  β€’ Notification Logs                β”‚                              β”‚  β€’ Rate Limiting (future)           β”‚                β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚
β”‚                                                                                                                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                                                                                              β”‚
β”‚  1️⃣ MONITOR CREATION                    2️⃣ JOB SCHEDULING                    3️⃣ HEALTH CHECK EXECUTION                       β”‚
β”‚  ─────────────────────                   ──────────────────                   ──────────────────────────                     β”‚
β”‚                                                                                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  POST /monitors  β”Œβ”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  Enqueue Job  β”Œβ”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”   HTTP GET   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚  β”‚  User  │─────────────────▢│ API │──▢│ Scheduler │──────────────▢│ Redis │──▢│ Worker │─────────────▢│ Target API   β”‚      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β””β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚                                 β”‚                                                   β”‚                         β”‚              β”‚
β”‚                                 β–Ό                                                   β–Ό                         β”‚              β”‚
β”‚                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚              β”‚
β”‚                          β”‚ PostgreSQL │◀─────────────────────────────────────│Save Result β”‚β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β”‚
β”‚                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                  β”‚
β”‚                                                                                                                              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                                                              β”‚
β”‚  4️⃣ INCIDENT DETECTION                  5️⃣ NOTIFICATION DELIVERY                                                             β”‚
β”‚  ──────────────────────                  ────────────────────────                                                            β”‚
β”‚                                                                                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  Threshold Breach  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”  Dequeue  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚ Worker │───────────────────▢│ Create       │──▢│ Redis │─────────▢│ Notifier │──▢│   Email (Resend)              β”‚      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚ Incident     β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚   Webhook (HTTP POST)         β”‚      β”‚
β”‚       β”‚                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                           β”‚         β”‚   Slack/Discord (future)      β”‚      β”‚
β”‚       β”‚                               β”‚                                   β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚       β”‚                               β–Ό                                   β”‚                                                  β”‚
β”‚       β”‚                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                             β”‚  Retry with Exponential Backoff                  β”‚
β”‚       β”‚                        β”‚ PostgreSQL β”‚                             β”‚  β”Œβ”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”                     β”‚
β”‚       β”‚                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                             └─▢│ 1s  │──▢│ 2s  │──▢│ 4s  │──▢ DLQ              β”‚
β”‚       β–Ό                                                                      β””β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”˜                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚                                          STATE MACHINE                                                              β”‚     β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€     β”‚
β”‚  β”‚   🟒 HEALTHY ──[failures >= threshold]──▢ πŸ”΄ INCIDENT ──[successes >= threshold]──▢ 🟒 RESOLVED                     β”‚     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚                                                                                                                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Service Communication

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                                                                                β”‚
β”‚                                           SERVICE MESH                                                         β”‚
β”‚                                                                                                                β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚    β”‚                                                                                                      β”‚    β”‚
β”‚    β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚    β”‚
β”‚    β”‚   β”‚   Web   β”‚         β”‚   API   β”‚         β”‚Schedulerβ”‚         β”‚ Worker  β”‚         β”‚Notifier β”‚        β”‚    β”‚
β”‚    β”‚   β”‚  :3000  β”‚         β”‚  :4000  β”‚         β”‚  :4002  β”‚         β”‚  :4001  β”‚         β”‚  :4003  β”‚        β”‚    β”‚
β”‚    β”‚   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜        β”‚    β”‚
β”‚    β”‚        β”‚                   β”‚                   β”‚                   β”‚                   β”‚             β”‚    β”‚
β”‚    β”‚        β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚    β”‚
β”‚    β”‚        β”‚    β”‚                                                                                        β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”‚                         OBSERVABILITY LAYER                                 β”‚      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”‚                                                                             β”‚      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”‚    /metrics ────────▢ Prometheus ────────▢ Grafana Dashboards             β”‚      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”‚                                                                             β”‚      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”‚   πŸ’š /health                                                                β”‚      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”‚   πŸ’š /ready                                                                 β”‚      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”‚   πŸ’š /live                                                                  β”‚      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”‚                                                                             β”‚      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”‚   πŸ“ Pino Logs ───────▢ Structured JSON ────────▢ Log Aggregator            β”‚      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β”‚                                                                             β”‚      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚    β”‚
β”‚    β”‚        β”‚    β”‚                                                                                        β”‚    β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚             β”‚    β”‚                                                                                             β”‚
β”‚             β–Ό    β–Ό                                                                                             β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚    β”‚                                     PERSISTENCE LAYER                                                β”‚    β”‚
β”‚    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€     β”‚
β”‚    β”‚                                                                                                      β”‚   β”‚
β”‚    β”‚      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”‚   β”‚
β”‚    β”‚      β”‚       PostgreSQL         β”‚                    β”‚         Redis            β”‚                   β”‚   β”‚
β”‚    β”‚      β”‚      (Primary DB)        β”‚                    β”‚     (Message Broker)     β”‚                   β”‚   β”‚
β”‚    β”‚      β”‚                          β”‚                    β”‚                          β”‚                   β”‚   β”‚
β”‚    β”‚      β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚                    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚                   β”‚   β”‚
β”‚    β”‚      β”‚  β”‚ users              β”‚  β”‚                    β”‚  β”‚ health-check-queue β”‚  β”‚                   β”‚   β”‚
β”‚    β”‚      β”‚  β”‚ monitors           β”‚  β”‚                    β”‚  β”‚ notification-queue β”‚  β”‚                   β”‚   β”‚
β”‚    β”‚      β”‚  β”‚ health_check_results  β”‚                    β”‚  β”‚ dead-letter-queue  β”‚  β”‚                   β”‚   β”‚
β”‚    β”‚      β”‚  β”‚ incidents          β”‚  β”‚                    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚                   β”‚   β”‚
β”‚    β”‚      β”‚  β”‚ notifications      β”‚  β”‚                    β”‚                          β”‚                   β”‚   β”‚
β”‚    β”‚      β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚                    β”‚                          β”‚                   β”‚   β”‚
β”‚    β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β”‚   β”‚
β”‚    β”‚                                                                                                     β”‚   β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                                                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Tech Stack

Category Technology
Runtime Node.js 18+, TypeScript
Backend Express.js
Frontend Next.js, React, Tailwind CSS
Database PostgreSQL, Prisma ORM
Queue Redis, BullMQ
Observability Prometheus, Pino
Auth JWT, bcrypt
Infrastructure Docker, Terraform (AWS)

Quick Start

Prerequisites

  • Node.js 18+
  • PostgreSQL
  • Redis

Installation

# Clone and install
git clone https://github.com/sAchin-680/HyperVerge-api-health-monitor-system.git
cd HyperVerge-api-health-monitor-system
npm install

# Setup database
npx prisma migrate deploy --schema=packages/db/prisma/schema.prisma
npx prisma generate --schema=packages/db/prisma/schema.prisma

# Copy environment template
cp .env.example .env

Environment Variables

# Database
DATABASE_URL="postgresql://user:password@localhost:5432/healthmonitor"

# Redis
REDIS_URL="redis://localhost:6379"

# Auth
JWT_SECRET="your-secret-key"

Run Services

# Using Make (recommended)
make dev

# Or individually
npm run dev --workspace=apps/api        # :4000
npm run dev --workspace=apps/scheduler  # :4002
npm run dev --workspace=apps/worker     # :4001
npm run dev --workspace=apps/notifier   # :4003
npm run dev --workspace=apps/web        # :3000

Docker

docker-compose up

Project Structure

β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ api/                    # REST API service
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ controllers/    # Request handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ routes/         # API route definitions
β”‚   β”‚   β”‚   β”œβ”€β”€ services/       # Business logic
β”‚   β”‚   β”‚   β”œβ”€β”€ middlewares/    # Auth, validation, logging
β”‚   β”‚   β”‚   β”œβ”€β”€ validators/     # Zod schemas
β”‚   β”‚   β”‚   └── lib/            # Shared utilities
β”‚   β”‚   └── prisma/             # Database schema
β”‚   β”‚
β”‚   β”œβ”€β”€ scheduler/              # Job scheduling service
β”‚   β”‚   └── src/
β”‚   β”‚       β”œβ”€β”€ index.ts        # Scheduler entry point
β”‚   β”‚       └── lib/            # Scheduling logic
β”‚   β”‚
β”‚   β”œβ”€β”€ worker/                 # Health check executor
β”‚   β”‚   └── src/
β”‚   β”‚       β”œβ”€β”€ worker.ts       # BullMQ worker
β”‚   β”‚       β”œβ”€β”€ checkExecutor.ts
β”‚   β”‚       β”œβ”€β”€ stateEvaluator.ts
β”‚   β”‚       └── incidentManager.ts
β”‚   β”‚
β”‚   β”œβ”€β”€ notifier/               # Notification service
β”‚   β”‚   └── src/
β”‚   β”‚       β”œβ”€β”€ providers/      # Email, webhook providers
β”‚   β”‚       β”œβ”€β”€ queue/          # Notification queue
β”‚   β”‚       └── services/       # Delivery logic
β”‚   β”‚
β”‚   └── web/                    # Next.js dashboard
β”‚       └── src/
β”‚           β”œβ”€β”€ app/            # App router pages
β”‚           β”œβ”€β”€ components/     # React components
β”‚           └── hooks/          # Custom hooks
β”‚
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ db/                     # Shared Prisma client
β”‚   β”‚   └── prisma/schema.prisma
β”‚   └── shared/                 # Shared types
β”‚       └── src/types.ts
β”‚
β”œβ”€β”€ architecture/               # Architecture documentation
β”œβ”€β”€ runbooks/                   # Operational runbooks
β”œβ”€β”€ terraform/                  # AWS infrastructure (ECS, RDS, etc.)
β”‚   β”œβ”€β”€ modules/
β”‚   β”‚   β”œβ”€β”€ vpc/
β”‚   β”‚   β”œβ”€β”€ ecs/
β”‚   β”‚   β”œβ”€β”€ rds/
β”‚   β”‚   β”œβ”€β”€ alb/
β”‚   β”‚   └── security/
β”‚   └── envs/                   # Environment configs
β”‚
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ Makefile
└── package.json

API Reference

Authentication

Method Endpoint Description
POST /auth/register Register user
POST /auth/login Login user

Monitors

Method Endpoint Description
GET /monitors List monitors
POST /monitors Create monitor
GET /monitors/:id Get monitor
PATCH /monitors/:id Update monitor
DELETE /monitors/:id Delete monitor

Health & Metrics

Method Endpoint Description
GET /health Health check
GET /ready Readiness probe
GET /live Liveness probe
GET /metrics Prometheus metrics

Documentation

Document Description
Architecture Overview System design and data flow
Engineering Log Design decisions and tradeoffs
Runbooks Operational procedures
Deployment Guide Deployment instructions
Terraform Infrastructure as Code

Screenshots

Dashboard Frontend Backend Logs

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Commit your changes (git commit -m 'feat: add feature')
  4. Push to your branch (git push origin feature/your-feature)
  5. Open a Pull Request

License

MIT License - see LICENSE for details

About

Scalable API health monitoring system focused on reliability, trust, and secure infrastructure, deployed on AWS using Terraform.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published