Skip to content

Repository files navigation

PulseCheck: Distributed Service Health Monitor

A high-performance, concurrent health monitoring system built in Go demonstrating worker-pool architecture for monitoring HTTP services in real-time.

🚀 Features

  • Concurrent Monitoring: Worker pools to monitor multiple endpoints simultaneously
  • Flexible Configuration: Custom intervals, timeouts, and keyword validation
  • Multi-Channel Notifications: Slack, Discord, and Email alerts
  • Data Persistence: SQLite database for historical tracking
  • RESTful API: Query system health and performance metrics
  • CLI Management: Terminal-based monitor management

🏗️ Architecture

Producer-Consumer pattern with:

  • Scheduler: Generates check tasks based on intervals
  • Worker Pool: Goroutines that perform HTTP health checks
  • Results Processor: Updates database and triggers alerts
  • Notification System: Interface-based alerting

🛠️ Tech Stack

  • Language: Go 1.25+
  • Database: SQLite (pure Go driver - no CGO required!)
  • CLI Framework: Cobra
  • HTTP Router: Gorilla Mux
  • Testing: Go's built-in testing + httptest

📦 Quick Start

Configuration

PulseCheck uses a YAML configuration file for production-grade settings. Copy the example and customize:

cp config.example.yaml config.yaml
# Edit config.yaml to set your preferences

Configuration file locations (searched in order):

  1. --config flag path
  2. ./config.yaml (current directory)
  3. ~/.pulsecheck/config.yaml (home directory)
  4. /etc/pulsecheck/config.yaml (system directory)

Environment variable overrides: Any configuration value can be overridden with environment variables:

export PULSECHECK_SERVER_PORT=9090
export PULSECHECK_WORKER_POOL_NUM_WORKERS=20
export PULSECHECK_NOTIFICATIONS_SLACK_WEBHOOK_URL="https://hooks.slack.com/..."
export PULSECHECK_LOGGING_LEVEL=debug

Building

# Build both binaries
make build

# This creates:
# - pulsecheck-cli (CLI tool)
# - pulsecheck-server-api (REST API server)

Usage

CLI Commands:

# Add URL to monitor
./pulsecheck-cli add https://example.com --frequency=60 --keywords="healthy,ok"

# List all monitored URLs
./pulsecheck-cli list

# Check a specific URL immediately
./pulsecheck-cli check 1

# Start continuous monitoring (uses config.yaml settings)
./pulsecheck-cli start

# Start with custom config file
./pulsecheck-cli start --config=/path/to/config.yaml

# Override config with flags
./pulsecheck-cli start --workers=20 --interval=30

# View monitoring statistics
./pulsecheck-cli status --limit=20

API Server:

# Start server (reads config.yaml)
./pulsecheck-server-api

# Start with custom config
./pulsecheck-server-api --config=/path/to/config.yaml

# Example API calls
curl http://localhost:8080/api/urls
curl http://localhost:8080/api/status
curl "http://localhost:8080/api/results?limit=10"

Testing

# Run all tests
make test

# Clean build artifacts
make clean

📚 Documentation

⚙️ Configuration Options

Core Settings

Section Setting Default Description
database.path Path ./pulsecheck.db SQLite database file location
database.enable_wal Boolean true Enable WAL mode for better concurrency
server.port Number 8080 HTTP server port
server.read_timeout Duration 30s HTTP read timeout
worker_pool.num_workers Number 10 Concurrent worker goroutines
worker_pool.check_interval Duration 10s How often to poll for checks
logging.level String info Log level: debug, info, warn, error
features.enable_ssrf_protection Boolean true Block private IPs and metadata endpoints

Notifications

Enable and configure notification channels:

notifications:
  slack:
    enabled: true
    webhook_url: "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"

  discord:
    enabled: true
    webhook_url: "https://discord.com/api/webhooks/YOUR/WEBHOOK"

  email:
    enabled: true
    smtp_server: "smtp.gmail.com"
    port: 587
    username: "your-email@gmail.com"
    password: "your-app-password"
    recipients:
      - "oncall@example.com"

TLS/HTTPS

Enable secure connections for the API server:

server:
  tls:
    enabled: true
    cert_file: "/path/to/cert.pem"
    key_file: "/path/to/key.pem"

🔒 Security Features

  • SSRF Protection: Blocks private IPs and metadata endpoints
  • HTTP Timeouts: Prevents goroutine hangs
  • URL Validation: Strict scheme and hostname checks
  • Resource Limits: Configurable worker pools and connection limits

🚦 Key Components

Worker Pool (internal/checker/)

  • Fixed goroutine pool prevents resource exhaustion
  • Buffered channels for work distribution
  • Context-based cancellation for clean shutdown

Scheduler (internal/scheduler/)

  • Time-based check scheduling
  • Integrates with worker pool
  • Per-URL frequency configuration

Database (internal/database/)

  • Pure Go SQLite (no C dependencies)
  • Transaction support for atomic updates
  • Prepared queries for security

Notifications (internal/notifier/)

  • Interface-based design for extensibility
  • Webhook support (Slack, Discord)
  • SMTP email notifications

📊 Performance

  • Small (<100 URLs): 10 workers, 30s interval
  • Medium (100-1000 URLs): 50 workers, 60s interval
  • Large (>1000 URLs): 100 workers, 120s interval

🤝 Contributing

See CONTRIBUTING.md for development guidelines and architecture details.

📝 License

MIT License - see LICENSE file for details.


Built with ❤️ using Go's concurrency primitives

About

Distributed service health monitoring system built in Go — concurrent worker pools, multi-channel alerts (Slack/Discord/Email), SQLite persistence, REST API & CLI

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages