The Ultimate Laravel Package for Bulletproof Service Failover
Never let a service failure bring down your application again
π Documentation β’ π Quick Start β’ π‘ Examples β’ π₯ Health Monitoring β’ π€ Contributing
- π― Why SmartFailover?
- β¨ Features
- π Quick Start
- βοΈ Configuration
- π‘ Usage Examples
- π₯ Health Monitoring
- π Notifications & Alerts
- π Dashboard Integration
- π§ͺ Testing
- π Performance
- π Security
- π€ Contributing
- π License
graph TD
A[Your Laravel App] --> B[Single Database]
A --> C[Single Cache]
A --> D[Single Queue]
B --> E[π₯ Database Fails]
C --> F[π₯ Cache Fails]
D --> G[π₯ Queue Fails]
E --> H[π΄ App Crashes]
F --> H
G --> H
style H fill:#ff6b6b
style E fill:#ff6b6b
style F fill:#ff6b6b
style G fill:#ff6b6b
graph TD
A[Your Laravel App] --> B[SmartFailover]
B --> C[Primary DB]
B --> D[Backup DB]
B --> E[Primary Cache]
B --> F[Backup Cache]
B --> G[Primary Queue]
B --> H[Backup Queue]
C --> I[π₯ Fails]
I --> J[β
Auto Switch to Backup]
E --> K[π₯ Fails]
K --> L[β
Auto Switch to Backup]
G --> M[π₯ Fails]
M --> N[β
Auto Switch to Backup]
J --> O[π’ App Stays Online]
L --> O
N --> O
style O fill:#51cf66
style J fill:#51cf66
style L fill:#51cf66
style N fill:#51cf66
SmartFailover transforms your single-point-of-failure Laravel application into a resilient, self-healing system that automatically switches to backup services when primary ones fail.
| Before SmartFailover | After SmartFailover |
|---|---|
| π₯ Single database failure = App down | β Automatic failover to backup database |
| π Manual intervention required | π Zero-downtime automatic switching |
| π° No visibility into service health | π Real-time health monitoring |
| π₯ Panic when services fail | π Sleep peacefully with alerts |
| Service | Primary | Fallbacks | Health Checks |
|---|---|---|---|
| ποΈ Database | MySQL, PostgreSQL | Multiple backups | β Connection tests |
| π Cache | Redis, Memcached | Array, File | β Read/Write tests |
| π¬ Queue | SQS, Redis | Database, Sync | β Job dispatch tests |
| π§ Mail | SMTP, SES | Mailgun, Log | β Connection tests |
| πΎ Storage | S3, GCS | Local, FTP | β File operations |
| π Auto Failover | π₯ Health Monitoring | π Smart Alerts | ποΈ Easy Integration |
|---|---|---|---|
| Instant switching when services fail | Real-time service health checks | Slack, Telegram, Email notifications | Minimal code changes required |
| Exponential backoff retry logic | Performance metrics tracking | Intelligent alert throttling | Fluent API design |
| Graceful degradation support | HTTP health endpoints | Custom notification channels | Laravel-native integration |
# 1οΈβ£ Install the package
composer require mirzaaghazadeh/smart-failover
# 2οΈβ£ Publish configuration
php artisan vendor:publish --provider="Mirzaaghazadeh\SmartFailover\SmartFailoverServiceProvider" --tag="config"
# 3οΈβ£ Configure your services (optional)
php artisan vendor:publish --provider="Mirzaaghazadeh\SmartFailover\SmartFailoverServiceProvider" --tag="migrations"// That's it! Start using SmartFailover immediately:
use Mirzaaghazadeh\SmartFailover\Facades\SmartFailover;
// Wrap your existing code with failover protection
SmartFailover::db('mysql', ['mysql_backup'])
->cache('redis', ['memcached'])
->execute(function() {
// Your existing Laravel code works unchanged!
$user = User::create($userData);
Cache::put('user_' . $user->id, $user, 3600);
return $user;
});The config/smart-failover.php file is your control center:
<?php
return [
// ποΈ Database Failover
'database' => [
'primary' => 'mysql',
'fallbacks' => ['mysql_backup', 'sqlite_fallback'],
'health_check_interval' => 30, // seconds
'retry_attempts' => 3,
'retry_delay' => 1000, // milliseconds
],
// π Cache Failover
'cache' => [
'primary' => 'redis',
'fallbacks' => ['memcached', 'array'],
'health_check_interval' => 15,
'retry_attempts' => 2,
],
// π¬ Queue Failover
'queue' => [
'primary' => 'sqs',
'fallbacks' => ['redis', 'database'],
'health_check_interval' => 60,
'retry_attempts' => 3,
],
// π Notifications
'notifications' => [
'slack' => [
'webhook_url' => env('SMART_FAILOVER_SLACK_WEBHOOK'),
'channel' => '#alerts',
],
'telegram' => [
'bot_token' => env('SMART_FAILOVER_TELEGRAM_BOT_TOKEN'),
'chat_id' => env('SMART_FAILOVER_TELEGRAM_CHAT_ID'),
],
],
];Add these to your .env file:
# Slack Notifications
SMART_FAILOVER_SLACK_WEBHOOK=https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
# Telegram Notifications
SMART_FAILOVER_TELEGRAM_BOT_TOKEN=your_bot_token
SMART_FAILOVER_TELEGRAM_CHAT_ID=your_chat_id
# Health Check Settings
SMART_FAILOVER_HEALTH_ENABLED=true
SMART_FAILOVER_HEALTH_CACHE_TTL=60use Mirzaaghazadeh\SmartFailover\Facades\SmartFailover;
// Protect ALL your services in one beautiful line
SmartFailover::db('mysql', ['mysql_backup'])
->cache('redis', ['memcached', 'array'])
->queue('sqs', ['redis', 'database'])
->execute(function() {
// Your normal Laravel code - unchanged!
$order = Order::create($orderData);
Cache::put('order_' . $order->id, $order, 3600);
ProcessOrderJob::dispatch($order);
return $order;
});π Click to see Database Examples
// β
Simple Database Failover
SmartFailover::db('mysql_primary', ['mysql_backup'])
->execute(function() {
return User::where('active', true)->get();
});
// β
With Graceful Degradation
SmartFailover::db('mysql_primary', ['mysql_backup'])
->gracefulDegradation(function() {
// Return cached data when all databases fail
return Cache::get('users_fallback', collect());
})
->execute(function() {
return User::all();
});
// β
Advanced Retry Logic
SmartFailover::db('mysql_primary', ['mysql_backup'])
->retryAttempts(5)
->retryDelay(2000) // 2 seconds
->retryMultiplier(1.5) // Exponential backoff
->execute(function() {
return User::with('orders')->paginate(50);
});π Click to see Cache Examples
// β
Multi-Level Cache Failover
SmartFailover::cache('redis', ['memcached', 'array'])
->execute(function() {
Cache::put('user_preferences', $preferences, 3600);
return Cache::get('user_preferences');
});
// β
Direct Cache Manager Usage
use Mirzaaghazadeh\SmartFailover\Services\CacheFailoverManager;
$cacheManager = app(CacheFailoverManager::class);
$cacheManager->setStores('redis', ['memcached']);
// Store with automatic failover
$cacheManager->put('user_123', $userData, 3600);
// Retrieve with automatic failover
$userData = $cacheManager->get('user_123');
// β
Cache with Fallback Data
SmartFailover::cache('redis', ['memcached'])
->gracefulDegradation(function() {
return [
'user_preferences' => config('app.default_preferences'),
'settings' => config('app.default_settings'),
];
})
->execute(function() {
return [
'user_preferences' => Cache::get('user_prefs'),
'settings' => Cache::get('app_settings'),
];
});π Click to see Queue Examples
// β
Queue Failover
SmartFailover::queue('sqs', ['redis', 'database'])
->execute(function() {
ProcessOrderJob::dispatch($order);
SendEmailJob::dispatch($user, $email);
});
// β
Direct Queue Manager Usage
use Mirzaaghazadeh\SmartFailover\Services\QueueFailoverManager;
$queueManager = app(QueueFailoverManager::class);
$queueManager->setConnections('sqs', ['redis']);
// Dispatch with failover
$queueManager->push(new ProcessOrderJob($order));
$queueManager->later(60, new SendReminderJob($user));π Click to see Mail & Storage Examples
// β
Mail Failover
use Mirzaaghazadeh\SmartFailover\Services\MailFailoverManager;
$mailManager = app(MailFailoverManager::class);
$mailManager->setMailers('ses', ['smtp', 'mailgun']);
// Send with automatic failover
$mailManager->send(new WelcomeEmail($user));
$mailManager->queue(new NewsletterEmail($subscribers));
// β
Storage Failover
use Mirzaaghazadeh\SmartFailover\Services\StorageFailoverManager;
$storageManager = app(StorageFailoverManager::class);
$storageManager->setDisks('s3', ['local', 'backup_s3']);
// Store file with failover
$storageManager->put('uploads/file.jpg', $fileContents);
// Retrieve file with failover
$contents = $storageManager->get('uploads/file.jpg');
// Sync file across all disks
$results = $storageManager->sync('important/backup.sql', $sqlDump);SmartFailover automatically creates health endpoints for monitoring:
# π HTTP Health Endpoints
GET /health # Overall health status
GET /health/detailed # Detailed health information
GET /health/database # Database-specific health
GET /health/cache # Cache-specific health
GET /health/queue # Queue-specific health{
"status": "healthy",
"timestamp": "2024-01-15T10:30:00Z",
"services": {
"database": {
"mysql_primary": {
"status": "healthy",
"response_time": 12.5,
"last_checked": "2024-01-15T10:30:00Z",
"details": "Connection successful"
},
"mysql_backup": {
"status": "healthy",
"response_time": 15.2,
"last_checked": "2024-01-15T10:30:00Z"
}
},
"cache": {
"redis": {
"status": "healthy",
"response_time": 2.1,
"memory_usage": "45.2MB"
},
"memcached": {
"status": "degraded",
"response_time": 150.5,
"warning": "High response time"
}
}
},
"summary": {
"total_services": 4,
"healthy_services": 3,
"degraded_services": 1,
"unhealthy_services": 0,
"average_response_time": 45.1
}
}# π Check overall health
php artisan smart-failover:health
# π― Check specific service
php artisan smart-failover:health --service=database
# π Detailed health information
php artisan smart-failover:health --detailed
# π JSON output for monitoring tools
php artisan smart-failover:health --json
# π§ͺ Test failover scenarios
php artisan smart-failover:test all
php artisan smart-failover:test database --simulate-failure// config/smart-failover.php
'notifications' => [
'slack' => [
'webhook_url' => env('SMART_FAILOVER_SLACK_WEBHOOK'),
'channel' => '#alerts',
'username' => 'SmartFailover Bot',
'emoji' => ':warning:',
'throttle_minutes' => 5, // Prevent spam
],
],'notifications' => [
'telegram' => [
'bot_token' => env('SMART_FAILOVER_TELEGRAM_BOT_TOKEN'),
'chat_id' => env('SMART_FAILOVER_TELEGRAM_CHAT_ID'),
'throttle_minutes' => 5,
'parse_mode' => 'Markdown',
],
],'notifications' => [
'email' => [
'to' => ['[email protected]', '[email protected]'],
'subject' => 'π¨ SmartFailover Alert',
'throttle_minutes' => 10,
'template' => 'smart-failover::alert',
],
],use Mirzaaghazadeh\SmartFailover\Services\NotificationManager;
$notificationManager = app(NotificationManager::class);
// Add custom notification channel
$notificationManager->addChannel('discord', function($message, $context) {
// Your custom Discord notification logic
Http::post('https://discord.com/api/webhooks/YOUR_WEBHOOK', [
'content' => "π¨ **SmartFailover Alert**\n{$message}",
'embeds' => [
[
'title' => 'Service Status',
'description' => $context['details'],
'color' => $context['status'] === 'healthy' ? 0x00ff00 : 0xff0000,
]
]
]);
});// In your Nova dashboard
use Mirzaaghazadeh\SmartFailover\Services\HealthCheckManager;
use Laravel\Nova\Cards\Help;
public function cards(Request $request)
{
$healthManager = app(HealthCheckManager::class);
$health = $healthManager->getHealthResponse();
return [
(new Help)
->heading('SmartFailover Status')
->content("
<div class='flex items-center space-x-4'>
<div class='flex-1'>
<div class='text-lg font-semibold text-green-600'>
{$health['summary']['healthy_services']}/{$health['summary']['total_services']} Services Healthy
</div>
<div class='text-sm text-gray-600'>
Avg Response Time: {$health['summary']['average_response_time']}ms
</div>
</div>
<div class='w-4 h-4 rounded-full " .
($health['status'] === 'healthy' ? 'bg-green-500' : 'bg-red-500') . "'></div>
</div>
"),
];
}// In your Filament widget
use Mirzaaghazadeh\SmartFailover\Services\HealthCheckManager;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
class SmartFailoverStatsWidget extends BaseWidget
{
protected function getStats(): array
{
$healthManager = app(HealthCheckManager::class);
$health = $healthManager->checkAll();
return [
Stat::make('Service Health', $health['summary']['healthy_services'] . '/' . $health['summary']['total_services'])
->description('Healthy Services')
->descriptionIcon($health['status'] === 'healthy' ? 'heroicon-m-check-circle' : 'heroicon-m-x-circle')
->color($health['status'] === 'healthy' ? 'success' : 'danger'),
Stat::make('Response Time', number_format($health['summary']['average_response_time'], 1) . 'ms')
->description('Average response time')
->descriptionIcon('heroicon-m-clock')
->color('info'),
Stat::make('Uptime', '99.9%')
->description('Last 30 days')
->descriptionIcon('heroicon-m-arrow-trending-up')
->color('success'),
];
}
}# π§ͺ Test all configured services
php artisan smart-failover:test all
# π― Test specific service
php artisan smart-failover:test database --primary=mysql --fallback=mysql_backup
# π₯ Simulate failure scenarios
php artisan smart-failover:test cache --simulate-failure
# π Performance testing
php artisan smart-failover:test queue --performance --iterations=100use Mirzaaghazadeh\SmartFailover\Facades\SmartFailover;
use Tests\TestCase;
class FailoverTest extends TestCase
{
/** @test */
public function it_fails_over_to_backup_database_when_primary_fails()
{
// Simulate primary database failure
DB::shouldReceive('connection')->with('mysql_primary')->andThrow(new Exception('Connection failed'));
DB::shouldReceive('connection')->with('mysql_backup')->andReturn(true);
$result = SmartFailover::db('mysql_primary', ['mysql_backup'])
->execute(function() {
return User::count();
});
$this->assertNotNull($result);
}
/** @test */
public function it_sends_notifications_on_failover()
{
Notification::fake();
// Trigger failover scenario
SmartFailover::db('mysql_primary', ['mysql_backup'])
->execute(function() {
throw new Exception('Primary DB failed');
});
Notification::assertSentTo(
config('smart-failover.notifications.email.to'),
SmartFailoverAlert::class
);
}
}// Benchmark failover performance
$startTime = microtime(true);
SmartFailover::db('mysql_primary', ['mysql_backup'])
->cache('redis', ['memcached'])
->execute(function() {
// Your application logic
return User::with('orders')->limit(1000)->get();
});
$executionTime = (microtime(true) - $startTime) * 1000;
echo "Failover execution time: {$executionTime}ms";| Feature | Performance Impact | Optimization |
|---|---|---|
| π Connection Pooling | -50% overhead | Reuse connections |
| π Async Health Checks | -80% request latency | Background monitoring |
| πΎ Result Caching | -90% repeated checks | Smart caching |
| π― Lazy Loading | -30% memory usage | Load on demand |
// Connections are automatically pooled and reused
SmartFailover::db('mysql_primary', ['mysql_backup'])
->poolConnections(true) // Default: true
->execute(function() {
// Multiple queries use the same connection
User::all();
Order::all();
Product::all();
});// config/smart-failover.php
'health_checks' => [
'async' => true, // Run health checks in background
'interval' => 30, // Check every 30 seconds
'cache_results' => true, // Cache health check results
'cache_ttl' => 60, // Cache for 60 seconds
'parallel_checks' => true, // Check services in parallel
],use Mirzaaghazadeh\SmartFailover\Services\PerformanceMonitor;
$monitor = app(PerformanceMonitor::class);
// Get performance metrics
$metrics = $monitor->getMetrics();
/*
[
'average_response_time' => 45.2,
'total_requests' => 1250,
'failover_count' => 3,
'success_rate' => 99.8,
'services' => [
'database' => ['response_time' => 12.5, 'success_rate' => 100],
'cache' => ['response_time' => 2.1, 'success_rate' => 99.5],
]
]
*/| π Credential Management | π« Access Control | π Audit Logging |
|---|---|---|
| Environment variables only | Rate limit health endpoints | Log all failover events |
| No credentials in logs | IP whitelist for monitoring | Secure log storage |
| Encrypted connection strings | Authentication required | Compliance ready |
// config/smart-failover.php
'security' => [
'health_endpoints' => [
'enabled' => true,
'middleware' => ['auth', 'throttle:60,1'], // Require auth + rate limiting
'ip_whitelist' => ['127.0.0.1', '10.0.0.0/8'], // Restrict access
],
'logging' => [
'log_credentials' => false, // Never log sensitive data
'encrypt_logs' => true, // Encrypt log files
'audit_trail' => true, // Full audit trail
],
'notifications' => [
'encrypt_webhooks' => true, // Encrypt webhook payloads
'verify_ssl' => true, // Verify SSL certificates
],
],// All failover events are automatically logged
use Mirzaaghazadeh\SmartFailover\Services\AuditLogger;
$auditLogger = app(AuditLogger::class);
// Get audit trail
$events = $auditLogger->getEvents([
'service' => 'database',
'event_type' => 'failover',
'date_from' => '2024-01-01',
'date_to' => '2024-01-31',
]);
/*
[
[
'timestamp' => '2024-01-15T10:30:00Z',
'service' => 'database',
'event_type' => 'failover',
'primary' => 'mysql_primary',
'fallback' => 'mysql_backup',
'reason' => 'Connection timeout',
'user_id' => 123,
'ip_address' => '192.168.1.100',
]
]
*/- π΄ Fork the repository
- πΏ Create your feature branch (
git checkout -b feature/amazing-feature) - β
Test your changes (
composer test) - π Commit your changes (
git commit -m 'Add amazing feature') - π Push to the branch (
git push origin feature/amazing-feature) - π Open a Pull Request
# Clone the repository
git clone https://github.com/mirzaaghazadeh/SmartFailover.git
cd SmartFailover
# Install dependencies
composer install
# Run tests
composer test
# Run code quality checks
composer lint
composer analyze- β Write tests for new features
- β Follow PSR-12 coding standards
- β Update documentation
- β Add changelog entries
- β Ensure backward compatibility
MIT License - see the LICENSE.md file for details
Feel free to use SmartFailover in your commercial and open-source projects
- π Documentation
- π Report Issues
- π‘ Feature Requests
- π¬ Discussions
Special Thanks To:
- π Laravel Framework - For providing an excellent foundation
- π₯ Laravel Community - For inspiration and feedback
- π€ All Contributors - Who help improve this package
- β Coffee - For making this possible
Made with β€οΈ for the Laravel Community
Never let a service failure bring down your application again!