# openHealth

A comprehensive health monitoring tool for backend and frontend services that provides real-time monitoring, alerting, and dashboard capabilities.

## Features

- **Multi-Service Monitoring**: Monitor multiple HTTP/HTTPS endpoints simultaneously
- **Configurable Intervals**: Set custom check intervals for each service
- **Retry Mechanisms**: Automatic retry with exponential backoff
- **Timeout Handling**: Configurable timeouts for health checks
- **Notification Systems**: 
  - Email alerts with SMTP support
  - Slack integration with customizable messages
- **Web Dashboard**: Real-time status dashboard with auto-refresh
- **Comprehensive Logging**: Detailed logging with configurable levels
- **JSON Configuration**: Simple, structured configuration format
- **CLI Tool**: Command-line interface for easy management

## Quick Start

### Installation

```bash
pip install openhealth
```

### Basic Usage

1. **Create a configuration file** (`config.json`):

```json
{
  "services": [
    {
      "name": "Backend API",
      "url": "https://api.example.com",
      "health_endpoint": "/health",
      "interval": 60,
      "timeout": 10,
      "max_retries": 3,
      "expected_status_code": 200,
      "web_interface": {
        "enabled": true
      },
      "email_alert": {
        "enabled": true,
        "recipients": ["admin@example.com"],
        "smtp_server": "smtp.gmail.com",
        "smtp_port": 587,
        "username": "monitor@example.com",
        "app_password": "your-app-password"
      },
      "slack_integration": {
        "enabled": true,
        "channel": "#alerts",
        "api_key": "xoxb-your-slack-api-key",
        "webhook_url": "https://hooks.slack.com/services/service-webhook",
        "message_template": "Service {name} is down. Status: {status}"
      }
    }
  ]
}
```

2. **Use in Python**:

### Traditional Initialization (config_path)

```python
from openHealth import HealthChecker
import time

# Initialize and start monitoring with config file
checker = HealthChecker(config_path="config.json")

try:
    checker.start()
    while True:
      time.sleep(1)
except KeyboardInterrupt:
    print("\nTest interrupted by user. Stopping...")
finally:
    print("\nStopping health checker...")
    checker.stop()
    print("Health checker stopped.")
```

### Flexible Initialization (config dict)

```python
from openHealth import HealthChecker, load_config
import time

# Load configuration first, then initialize
config = load_config(config_path="config.json")
checker = HealthChecker(config=config)

try:
    checker.start()
    while True:
      time.sleep(1)
except KeyboardInterrupt:
    print("\nTest interrupted by user. Stopping...")
finally:
    print("\nStopping health checker...")
    checker.stop()
    print("Health checker stopped.")
```

> **Note**: Both initialization patterns are equivalent. Choose the one that best fits your use case. The `config_path` approach is simpler, while the `config` approach allows for configuration manipulation before initialization.

3. **Use via CLI**:

```bash
# Start monitoring with default config
openhealth start

# Start with custom config
openhealth start -c my_config.json

# Check current status
openhealth status

# Validate configuration
openhealth validate-config

# Create sample configuration
openhealth create-config
```

## Configuration

### Service Configuration

Each service in the configuration supports the following options:

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `name` | string | Yes | - | Human-readable service name |
| `url` | string | Yes | - | Base URL of the service |
| `health_endpoint` | string | Yes | - | Health check endpoint path |
| `interval` | number | No | 60 | Check interval in seconds |
| `timeout` | number | No | 10 | Request timeout in seconds |
| `max_retries` | integer | No | 3 | Maximum retry attempts |
| `expected_status_code` | integer | No | 200 | Expected HTTP status code |

### Notification Configuration

#### Email Alerts

```json
"email_alert": {
  "enabled": true,
  "recipients": ["admin@example.com", "ops@example.com"],
  "smtp_server": "smtp.gmail.com",
  "smtp_port": 587,
  "username": "monitor@example.com",
  "app_password": "your-app-password"
}
```

#### Slack Integration

```json
"slack_integration": {
  "enabled": true,
  "channel": "#alerts",
  "api_key": "xoxb-your-slack-api-key",
  "message_template": "Service {name} is {status}. Error: {error}"
}
```

#### Web Dashboard

```json
"web_interface": {
  "enabled": true
}
```

## Web Dashboard

When enabled, the web dashboard provides:

- **Real-time Status**: Live status of all monitored services
- **Visual Indicators**: Color-coded status (✅ healthy, ⚠️ unhealthy, 🚨 error)
- **Response Times**: Display of response times for each service
- **Auto-refresh**: Automatic refresh every 30 seconds
- **API Endpoints**: JSON API for programmatic access

Access the dashboard at `http://localhost:8080` when monitoring is running.

### API Endpoints

- `GET /` - Main dashboard
- `GET /api/status` - Current status of all services
- `GET /api/summary` - Summary statistics
- `GET /api/history/<service_name>` - Service history

## Advanced Usage

### Custom Callbacks

```python
def custom_callback(result):
    print(f"Service {result.service_name}: {result.status}")
    
checker = HealthChecker(config_path="config.json")
checker.add_status_callback(custom_callback)
checker.start()
```

### Programmatic Status Checking

```python
# Check all services once
results = checker.check_all_services()

# Check specific service
result = checker.check_service("Backend API")

# Get current status
status = checker.get_status()
service_status = checker.get_service_status("Backend API")
```

### Configuration Validation

```python
from openHealth.core.config import ConfigValidator

validator = ConfigValidator()
config = validator.load_config("config.json")
```

### Standalone Configuration Functions

The library provides standalone functions for configuration management:

```python
from openHealth import load_config, validate_config

# Load and validate configuration from file
config = load_config("config.json")

# Validate a pre-loaded configuration dictionary
validate_config(config)
```

These standalone functions are useful when:
- You want to validate configuration before initializing HealthChecker
- You need to manipulate configuration between loading and initialization
- You're building custom configuration management tools

## Error Handling

The package provides detailed error messages for common issues:

- **Invalid URLs**: "Invalid URL format in 'url' field"
- **Missing Fields**: "Missing required field 'health_endpoint'"
- **Email Issues**: "Invalid email format: invalid-email"
- **Connection Problems**: Detailed connection error messages

## Logging

Configure logging levels and output:

```python
# Basic setup
checker = HealthChecker(
    config_path="config.json",
    log_level="INFO",
    log_file="openhealth.log"
)

# Or configure directly
from openHealth.utils.logger import setup_logging

setup_logging(
    level="DEBUG",
    log_file="openhealth.log",
    max_bytes=10*1024*1024,  # 10MB
    backup_count=5
)
```

## Examples

### Simple Service Monitor

```python
from openHealth import HealthChecker

config = {
    "services": [
        {
            "name": "Website",
            "url": "https://example.com",
            "health_endpoint": "/"
        }
    ]
}

# Save config to file
import json
with open("simple_config.json", "w") as f:
    json.dump(config, f)

# Start monitoring
with HealthChecker("simple_config.json") as checker:
    checker.start()
    import time
    time.sleep(60)  # Monitor for 1 minute
```

### Microservices Monitoring

```python
config = {
    "services": [
        {
            "name": "User Service",
            "url": "https://user-service.example.com",
            "health_endpoint": "/health",
            "interval": 30
        },
        {
            "name": "Order Service", 
            "url": "https://order-service.example.com",
            "health_endpoint": "/health",
            "interval": 30
        },
        {
            "name": "Payment Service",
            "url": "https://payment-service.example.com", 
            "health_endpoint": "/health",
            "interval": 30
        }
    ]
}
```

### Production Setup

```python
# Production configuration with all features
config = {
    "services": [
        {
            "name": "Production API",
            "url": "https://api.prod.example.com",
            "health_endpoint": "/health",
            "interval": 60,
            "timeout": 10,
            "max_retries": 3,
            "expected_status_code": 200,
            "web_interface": {"enabled": True},
            "email_alert": {
                "enabled": True,
                "recipients": ["ops@example.com", "devops@example.com"],
                "smtp_server": "smtp.company.com",
                "smtp_port": 587,
                "username": "alerts@company.com",
                "app_password": "secure-password"
            },
            "slack_integration": {
                "enabled": True,
                "channel": "#production-alerts",
                "api_key": "xoxb-production-slack-key",
                "message_template": "🚨 PRODUCTION ALERT: {name} is {status}"
            }
        }
    ]
}
```

## Development

### Running Tests

```bash
# Install development dependencies
pip install -e ".[dev]"

# Run all tests
pytest

# Run with coverage
pytest --cov=openHealth --cov-report=html

# Run specific test file
pytest tests/test_config.py
```

### Code Quality

```bash
# Format code
black openHealth tests

# Lint code
flake8 openHealth tests

# Type checking
mypy openHealth
```

## Configuration Templates

### Minimal Configuration

```json
{
  "services": [
    {
      "name": "My Service",
      "url": "https://api.example.com",
      "health_endpoint": "/health"
    }
  ]
}
```

### Full Configuration

```json
{
  "services": [
    {
      "name": "Critical Service",
      "url": "https://critical.example.com",
      "health_endpoint": "/api/health",
      "interval": 30,
      "timeout": 5,
      "max_retries": 5,
      "expected_status_code": 200,
      "web_interface": {
        "enabled": true
      },
      "email_alert": {
        "enabled": true,
        "recipients": ["admin@example.com"],
        "smtp_server": "smtp.example.com",
        "smtp_port": 587,
        "username": "alerts@example.com",
        "app_password": "secure-password"
      },
      "slack_integration": {
        "enabled": true,
        "channel": "#alerts",
        "api_key": "xoxb-slack-key",
        "message_template": "🚨 CRITICAL: {name} is {status}. Error: {error}"
      }
    }
  ]
}
```

## Troubleshooting

### Common Issues

1. **SSL Certificate Errors**: Configure your service to use valid SSL certificates or reduce security settings in your application.
2. **Timeout Issues**: Increase the `timeout` value for slow services.
3. **Email/Slack Not Working**: Verify API keys, passwords, and network connectivity.
4. **High CPU Usage**: Increase check intervals or reduce the number of concurrent checks.

### Debug Mode

```python
# Enable debug logging for detailed troubleshooting
checker = HealthChecker(
    config_path="config.json",
    log_level="DEBUG"
)
```

## License

MIT License - see LICENSE file for details.

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests for new functionality
5. Ensure all tests pass
6. Submit a pull request

## Support

- **Documentation**: [Full Documentation](https://openhealth.readthedocs.io/)
- **Issues**: [GitHub Issues](https://github.com/openhealth/openhealth/issues)
- **Discussions**: [GitHub Discussions](https://github.com/openhealth/openhealth/discussions)