A fast and flexible API health monitoring tool
Project description
🔍 ApiMonitor
A fast, flexible, and powerful API health monitoring tool for Python. Monitor your APIs, track response times, get alerts when things go wrong, and ensure your services stay online.
✨ Features
- 🚀 Fast Async Monitoring: Built with aiohttp for high-performance concurrent checks
- 📊 Comprehensive Metrics: Response times, status codes, uptime percentages, SLA tracking
- 🚨 Multiple Alert Channels: Slack, Discord, Email, Webhooks, Console notifications
- 🎛️ Flexible Configuration: YAML/JSON config files or programmatic setup
- 📈 Built-in Dashboard: Web interface for real-time monitoring (optional)
- 🐳 Docker Ready: Easy deployment with Docker support
- 💻 CLI & Python API: Use from command line or integrate into your applications
- 🔧 Highly Configurable: Custom headers, request bodies, health checks, retry logic
🚀 Quick Start
Installation
pip install apimonitor
Command Line Usage
# Check endpoints once
apimonitor check https://api.example.com/health https://api2.example.com/status
# Monitor continuously
apimonitor run https://api.example.com/health --interval 60
# Monitor with Slack notifications
apimonitor run https://api.example.com/health --slack-webhook YOUR_WEBHOOK_URL
# Use configuration file
apimonitor init # Create example config
apimonitor run --config-file apimonitor_config.yaml
# Start with dashboard
apimonitor run --config-file config.yaml --dashboard --dashboard-port 8080
Python API
from apimonitor import ApiMonitor
# Quick health check
from apimonitor import quick_check
result = await quick_check("https://api.example.com/health")
print(f"Status: {result.health_status}, Response time: {result.response_time_ms}ms")
# Continuous monitoring
monitor = ApiMonitor()
monitor.add_endpoint("https://api.example.com/health", "api_health")
monitor.add_notification_channel("slack", "slack", {
"webhook_url": "YOUR_SLACK_WEBHOOK_URL"
})
# Start monitoring
await monitor.start()
📋 Configuration
YAML Configuration Example
# Basic settings
log_level: "INFO"
max_history_days: 30
dashboard_enabled: true
dashboard_port: 8080
# Endpoints to monitor
endpoints:
- id: "api_health"
url: "https://api.example.com/health"
method: "GET"
check_interval_seconds: 60
timeout_seconds: 10
expected_status_codes: [200]
headers:
Authorization: "Bearer your-token"
- id: "api_users"
url: "https://api.example.com/users"
method: "GET"
check_interval_seconds: 300
timeout_seconds: 5
expected_status_codes: [200, 201]
sla_response_time_ms: 1000
response_contains: "users"
# Notification channels
notifications:
console:
type: "console"
enabled: true
on_failure: true
on_recovery: true
slack:
type: "slack"
enabled: true
config:
webhook_url: "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
on_failure: true
on_recovery: true
max_notifications_per_hour: 10
cooldown_minutes: 5
email:
type: "email"
enabled: false
config:
smtp_host: "smtp.gmail.com"
smtp_port: 587
username: "your-email@gmail.com"
password: "your-app-password"
from_email: "monitoring@yourcompany.com"
to_emails: ["admin@yourcompany.com", "ops@yourcompany.com"]
use_tls: true
Environment Variables
You can also configure ApiMonitor using environment variables:
export APIMONITOR_URL="https://api.example.com/health"
export APIMONITOR_INTERVAL=300
export APIMONITOR_TIMEOUT=10
export APIMONITOR_SLACK_WEBHOOK="https://hooks.slack.com/services/..."
export APIMONITOR_LOG_LEVEL="INFO"
export APIMONITOR_DASHBOARD=true
apimonitor run
🔧 Advanced Usage
Custom Health Checks
from apimonitor import ApiMonitor
from apimonitor.models import EndpointConfig, HttpMethod
# Advanced endpoint configuration
endpoint = EndpointConfig(
id="api_advanced",
url="https://api.example.com/data",
method=HttpMethod.POST,
headers={"Authorization": "Bearer token", "Content-Type": "application/json"},
body='{"query": "test"}',
expected_status_codes=[200, 201],
expected_response_time_ms=500,
response_contains="success",
response_not_contains="error",
check_interval_seconds=120,
max_retries=3,
sla_uptime_percentage=99.9,
sla_response_time_ms=1000
)
monitor = ApiMonitor()
monitor.config.add_endpoint(endpoint)
Custom Notifications
# Webhook notification
monitor.add_notification_channel("webhook", "webhook", {
"url": "https://your-webhook.com/alerts",
"headers": {"Authorization": "Bearer webhook-token"}
})
# Discord notification
monitor.add_notification_channel("discord", "discord", {
"webhook_url": "https://discord.com/api/webhooks/YOUR_WEBHOOK"
})
# Email notification
monitor.add_notification_channel("email", "email", {
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"username": "alerts@yourcompany.com",
"password": "your-password",
"from_email": "alerts@yourcompany.com",
"to_emails": ["admin@yourcompany.com"]
})
Monitoring with Context Manager
async with ApiMonitor() as monitor:
monitor.add_endpoint("https://api.example.com/health", "api_health")
# Check once
result = await monitor.check_endpoint("api_health")
print(f"Health: {result.health_status}")
# Get statistics
stats = monitor.get_endpoint_stats("api_health")
print(f"Uptime: {stats.uptime_percentage:.2f}%")
📊 Dashboard
ApiMonitor includes an optional web dashboard for real-time monitoring:
# Install dashboard dependencies
pip install apimonitor[dashboard]
# Start with dashboard
apimonitor run --config-file config.yaml --dashboard --dashboard-port 8080
Visit http://localhost:8080 to see:
- Real-time endpoint status
- Response time graphs
- Uptime statistics
- Recent alerts and events
- SLA compliance tracking
🐳 Docker Deployment
Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY config.yaml .
COPY . .
CMD ["apimonitor", "run", "--config-file", "config.yaml"]
Docker Compose
version: '3.8'
services:
apimonitor:
build: .
volumes:
- ./config.yaml:/app/config.yaml
- ./logs:/app/logs
ports:
- "8080:8080"
environment:
- APIMONITOR_LOG_LEVEL=INFO
restart: unless-stopped
📚 CLI Reference
Commands
apimonitor run- Start continuous monitoringapimonitor check- Check endpoints onceapimonitor init- Create example configurationapimonitor validate- Validate configuration fileapimonitor stats- Show monitoring statistics
Global Options
--config,-c- Configuration file path--verbose,-v- Verbose output--version- Show version
Run Command Options
--config-file,-c- Configuration file--interval,-i- Check interval in seconds--timeout,-t- Request timeout in seconds--slack-webhook- Slack webhook URL--discord-webhook- Discord webhook URL--email-config- Email configuration (JSON)--dashboard- Enable web dashboard--dashboard-port- Dashboard port--background,-b- Run in background
Check Command Options
--timeout,-t- Request timeout in seconds--method,-m- HTTP method--headers,-H- HTTP headers (key:value)--expected-status- Expected status codes--json-output,-j- Output as JSON--quiet,-q- Quiet mode
🧪 Testing
# Install test dependencies
pip install apimonitor[dev]
# Run tests
pytest tests/ -v
# Run with coverage
pytest tests/ --cov=apimonitor --cov-report=html
🔄 Integration Examples
CI/CD Pipeline Health Check
# GitHub Actions example
- name: Check API Health
run: |
pip install apimonitor
apimonitor check https://api.staging.example.com/health --expected-status 200
Kubernetes Health Check
apiVersion: batch/v1
kind: CronJob
metadata:
name: api-health-check
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: apimonitor
image: your-registry/apimonitor:latest
command: ["apimonitor", "check", "https://api.example.com/health"]
restartPolicy: OnFailure
Serverless Monitoring (AWS Lambda)
import json
import asyncio
from apimonitor import quick_check
def lambda_handler(event, context):
async def check_apis():
urls = ["https://api1.example.com/health", "https://api2.example.com/health"]
results = []
for url in urls:
result = await quick_check(url)
results.append({
"url": url,
"status": result.health_status.value,
"response_time": result.response_time_ms,
"success": result.success
})
return results
results = asyncio.run(check_apis())
return {
'statusCode': 200,
'body': json.dumps(results)
}
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
# Clone repository
git clone https://github.com/abderrahimghazali/apimonitor.git
cd apimonitor
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black apimonitor/ tests/
isort apimonitor/ tests/
# Lint code
flake8 apimonitor/ tests/
🐛 Troubleshooting
Common Issues
1. SSL Certificate Errors
# Disable SSL verification (not recommended for production)
endpoint_config = EndpointConfig(
id="test",
url="https://self-signed-cert-site.com",
# Add custom session configuration in future versions
)
2. Timeout Issues
endpoints:
- id: "slow_api"
url: "https://slow-api.example.com"
timeout_seconds: 30 # Increase timeout
max_retries: 5 # Increase retries
3. Rate Limiting
endpoints:
- id: "rate_limited_api"
url: "https://api.example.com"
check_interval_seconds: 600 # Check less frequently
4. Memory Usage
# Limit history retention
max_history_days: 7
🙏 Acknowledgments
- Built with aiohttp for fast async HTTP requests
- Uses pydantic for configuration validation
- CLI powered by click
- Dashboard built with FastAPI (optional)
Need help?
Example Configuration Files
config/basic.yaml
log_level: "INFO"
dashboard_enabled: false
endpoints:
- id: "google"
url: "https://www.google.com"
check_interval_seconds: 300
timeout_seconds: 10
expected_status_codes: [200]
notifications:
console:
type: "console"
enabled: true
on_failure: true
on_recovery: true
config/advanced.yaml
log_level: "INFO"
log_file: "logs/apimonitor.log"
max_history_days: 30
dashboard_enabled: true
dashboard_port: 8080
# Default settings for all endpoints
default_timeout: 10.0
default_interval: 300
default_retries: 3
endpoints:
- id: "api_health"
url: "https://api.example.com/health"
method: "GET"
check_interval_seconds: 60
timeout_seconds: 5
expected_status_codes: [200]
expected_response_time_ms: 500
headers:
User-Agent: "ApiMonitor/1.0"
Authorization: "Bearer token123"
sla_uptime_percentage: 99.9
sla_response_time_ms: 1000
- id: "api_users_post"
url: "https://api.example.com/users"
method: "POST"
check_interval_seconds: 300
timeout_seconds: 10
expected_status_codes: [200, 201]
headers:
Content-Type: "application/json"
Authorization: "Bearer token123"
body: '{"test": true}'
response_contains: "success"
max_retries: 5
retry_delay_seconds: 2.0
- id: "slow_api"
url: "https://httpbin.org/delay/3"
check_interval_seconds: 600
timeout_seconds: 15
expected_status_codes: [200]
expected_response_time_ms: 5000
notifications:
console:
type: "console"
enabled: true
on_failure: true
on_recovery: true
on_degraded: true
slack_critical:
type: "slack"
enabled: true
config:
webhook_url: "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
on_failure: true
on_recovery: true
on_degraded: false
max_notifications_per_hour: 20
cooldown_minutes: 2
discord_alerts:
type: "discord"
enabled: true
config:
webhook_url: "https://discord.com/api/webhooks/YOUR_WEBHOOK"
on_failure: true
on_recovery: true
max_notifications_per_hour: 10
cooldown_minutes: 5
email_alerts:
type: "email"
enabled: false
config:
smtp_host: "smtp.gmail.com"
smtp_port: 587
username: "alerts@yourcompany.com"
password: "your-app-password"
from_email: "apimonitor@yourcompany.com"
to_emails:
- "admin@yourcompany.com"
- "ops@yourcompany.com"
use_tls: true
on_failure: true
on_recovery: true
max_notifications_per_hour: 5
cooldown_minutes: 10
webhook_integration:
type: "webhook"
enabled: false
config:
url: "https://your-webhook-service.com/alerts"
headers:
Authorization: "Bearer webhook-token"
Content-Type: "application/json"
on_failure: true
on_recovery: true
max_notifications_per_hour: 50
config/microservices.yaml
log_level: "INFO"
dashboard_enabled: true
dashboard_port: 8080
endpoints:
# Frontend services
- id: "web_frontend"
url: "https://app.example.com/health"
check_interval_seconds: 60
timeout_seconds: 5
expected_status_codes: [200]
sla_uptime_percentage: 99.9
# API Gateway
- id: "api_gateway"
url: "https://api.example.com/health"
check_interval_seconds: 30
timeout_seconds: 5
expected_status_codes: [200]
sla_uptime_percentage: 99.95
# User service
- id: "user_service"
url: "https://users.example.com/health"
check_interval_seconds: 120
timeout_seconds: 10
expected_status_codes: [200]
headers:
Authorization: "Bearer service-token"
# Payment service (critical)
- id: "payment_service"
url: "https://payments.example.com/health"
check_interval_seconds: 30
timeout_seconds: 5
expected_status_codes: [200]
sla_uptime_percentage: 99.99
sla_response_time_ms: 200
# Email service
- id: "email_service"
url: "https://email.example.com/health"
check_interval_seconds: 300
timeout_seconds: 10
expected_status_codes: [200]
# Database health check
- id: "database_proxy"
url: "https://db-proxy.example.com/health"
check_interval_seconds: 60
timeout_seconds: 3
expected_status_codes: [200]
response_contains: "database_ok"
notifications:
console:
type: "console"
enabled: true
on_failure: true
on_recovery: true
slack_ops:
type: "slack"
enabled: true
config:
webhook_url: "https://hooks.slack.com/services/YOUR/OPS/WEBHOOK"
on_failure: true
on_recovery: true
on_degraded: true
max_notifications_per_hour: 30
slack_critical:
type: "slack"
enabled: true
config:
webhook_url: "https://hooks.slack.com/services/YOUR/CRITICAL/WEBHOOK"
on_failure: true
on_recovery: false # Only failures for critical channel
max_notifications_per_hour: 50
docker-compose.yaml
version: '3.8'
services:
apimonitor:
build: .
container_name: apimonitor
volumes:
- ./config/production.yaml:/app/config.yaml:ro
- ./logs:/app/logs
- ./data:/app/data
ports:
- "8080:8080"
environment:
- APIMONITOR_LOG_LEVEL=INFO
- APIMONITOR_CONFIG=/app/config.yaml
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Optional: Redis for shared state (future enhancement)
redis:
image: redis:7-alpine
container_name: apimonitor-redis
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
redis_data:
Kubernetes Deployment
k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: apimonitor-config
data:
config.yaml: |
log_level: "INFO"
dashboard_enabled: true
dashboard_port: 8080
endpoints:
- id: "frontend"
url: "http://frontend-service/health"
check_interval_seconds: 60
timeout_seconds: 5
expected_status_codes: [200]
notifications:
console:
type: "console"
enabled: true
on_failure: true
on_recovery: true
k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: apimonitor
spec:
replicas: 1
selector:
matchLabels:
app: apimonitor
template:
metadata:
labels:
app: apimonitor
spec:
containers:
- name: apimonitor
image: your-registry/apimonitor:latest
ports:
- containerPort: 8080
volumeMounts:
- name: config
mountPath: /app/config.yaml
subPath: config.yaml
env:
- name: APIMONITOR_CONFIG
value: "/app/config.yaml"
livenessProbe:
httpGet:
path: /api/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 30
readinessProbe:
httpGet:
path: /api/health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: config
configMap:
name: apimonitor-config
k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
name: apimonitor-service
spec:
selector:
app: apimonitor
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file apimonitor-1.0.0.tar.gz.
File metadata
- Download URL: apimonitor-1.0.0.tar.gz
- Upload date:
- Size: 35.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
835526edabcd664a142c5f406119b092f9c3ec7c67db8af8205717a7dc1344e0
|
|
| MD5 |
1164c17ee42a58617e73179d1c2a3499
|
|
| BLAKE2b-256 |
0ea21a74d43b7d9d933bb1018820ee3fe5007d52868657469dbf17716dd25b8a
|
File details
Details for the file apimonitor-1.0.0-py3-none-any.whl.
File metadata
- Download URL: apimonitor-1.0.0-py3-none-any.whl
- Upload date:
- Size: 30.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e02b0e04e03206aeb998c8e85ef556f25a2ce44ecc6505768944a9ee48db134f
|
|
| MD5 |
4d0fe408ba36534d0fb4bc63b0f488d0
|
|
| BLAKE2b-256 |
d0e2de3ee7bb687f2b063e5ea6f7155cfff41c372403a38a20a5ea0ec39debdb
|