🔍 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
Metadata
Release files for apimonitor 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| apimonitor-1.0.0.tar.gz | 35.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| apimonitor-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 66.0 kB
Release files / apimonitor-1.0.0.tar.gz
| Download URL | apimonitor-1.0.0.tar.gz |
|---|---|
| Size | 35.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
835526edabcd664a142c5f406119b092f9c3ec7c67db8af8205717a7dc1344e0
|
|
BLAKE2b-256 checksum How to use checksums |
0ea21a74d43b7d9d933bb1018820ee3fe5007d52868657469dbf17716dd25b8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.0
|
Release files / apimonitor-1.0.0-py3-none-any.whl
| Download URL | apimonitor-1.0.0-py3-none-any.whl |
|---|---|
| Size | 30.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e02b0e04e03206aeb998c8e85ef556f25a2ce44ecc6505768944a9ee48db134f
|
|
BLAKE2b-256 checksum How to use checksums |
d0e2de3ee7bb687f2b063e5ea6f7155cfff41c372403a38a20a5ea0ec39debdb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.0
|