Skip to content

Harshjosh361/GopherPing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GopherPing

Lightweight website uptime monitoring service built with Go (Gin + GORM) and a Next.js frontend.

Features

  • Authenticated REST API (JWT) with middleware-based protection
  • Create, list, update, and delete monitors per user
  • Background worker periodically checks endpoints and stores logs
  • Email alerts via SendGrid on status change (DOWN and back UP)
  • Frontend dashboard with mini uptime charts and monitor management

Quick start (Backend)

  1. Environment

    • JWT_SECRET=your_secret
    • Database (configure in config/db.go); run migrations via migrations/migrations.go
    • Optional for email alerts: SENDGRID_API_KEY (configured in config/sendgrid.go)
  2. Run

go mod download
go run ./main.go

The API defaults to http://localhost:8080 with routes under /api (see routes/).

Key architecture

  • middlewares/checkAuth.go: validates JWT and injects user_id into the Gin context
  • models/: GORM models and DB helpers
  • service/: application logic (monitor worker, monitor CRUD, uptime logs)
  • controller/: HTTP handlers, request binding, and responses
  • routes/: route groups; monitors are behind auth middleware

Singleton monitor worker (How it’s used)

We use a singleton to coordinate all background checks across the app. This ensures only one in-memory worker owns and schedules monitor jobs, even if multiple code paths try to start it.

Implementation: service/monitor_worker.go

  • GetMonitorWorker() uses sync.Once to create exactly one MonitorWorker instance and returns it thereafter.
  • The worker maintains an in-memory registry map[uint]*MonitorJob for active monitors, each with its own ticker and stop channel.
  • On startup (Start), the worker loads existing monitors from the database and adds jobs with parsed intervals.
  • The main loop (Run) periodically triggers checks, and runMonitorJob runs a persistent goroutine per monitor for continuous checks.
  • On status change (UP ↔ DOWN), sendMonitorAlert sends emails when SendGrid is configured.

Why singleton?

  • Prevents duplicate scheduling and race conditions
  • Centralizes lifecycle management (add/update/delete jobs)
  • Simple, process-local coordination without external brokers

Relevant snippets:

// service/monitor_worker.go
var (
    worker *MonitorWorker
    once   sync.Once
)

func GetMonitorWorker() *MonitorWorker {
    once.Do(func() {
        ctx, cancel := context.WithCancel(context.Background())
        worker = &MonitorWorker{ Monitors: make(map[uint]*MonitorJob), Ctx: ctx, Cancel: cancel }
    })
    return worker
}

Worker-aware updates:

  • When a monitor is created, service.CreateMonitor parses its interval and AddMonitor registers a job.
  • When a monitor is deleted, service.DeleteMonitor calls DeleteMonitor to stop and remove the job.
  • When a monitor is updated, service.UpdateMonitor persists changes and, if the interval changed, removes and re-adds the job with the new schedule.

API overview (monitors)

  • POST /api/monitors/ create
  • GET /api/monitors/user/:userId list for current user
  • GET /api/monitors/:id get
  • PUT /api/monitors/:id update
  • DELETE /api/monitors/:id delete
  • GET /api/monitors/:id/uptime last 24h uptime samples

All monitor routes require Authorization: Bearer <token>.

Frontend

The Next.js app (in GopherPingFrontend/) reads NEXT_PUBLIC_API_BASE_URL and uses the JWT from localStorage. The dashboard includes:

  • Monitor list with mini uptime charts (last 24 samples)
  • Edit and destructive delete (with URL confirmation)

License

MIT

About

Website Uptime Monitoring Service

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages