Skip to content

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

Packages

Contributors

Languages