147 lines
5.8 KiB
PHP
147 lines
5.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\ErrorAggregation;
|
|
|
|
use App\Framework\Cache\Cache;
|
|
use App\Framework\Config\Environment;
|
|
use App\Framework\Database\ConnectionInterface;
|
|
use App\Framework\DateTime\Clock;
|
|
use App\Framework\DI\Container;
|
|
use App\Framework\DI\Initializer;
|
|
use App\Framework\ErrorAggregation\Alerting\AlertManager;
|
|
use App\Framework\ErrorAggregation\Alerting\EmailAlertChannel;
|
|
use App\Framework\ErrorAggregation\Storage\DatabaseErrorStorage;
|
|
use App\Framework\ErrorAggregation\Storage\ErrorStorageInterface;
|
|
use App\Framework\Logging\Logger;
|
|
use App\Framework\Queue\Queue;
|
|
use App\Framework\Mail\TransportInterface;
|
|
|
|
/**
|
|
* Initializer for Error Aggregation services
|
|
*/
|
|
final readonly class ErrorAggregationInitializer
|
|
{
|
|
public function __construct(
|
|
private Environment $env,
|
|
){}
|
|
|
|
#[Initializer]
|
|
public function initErrorAggregator(Container $container): ErrorAggregatorInterface
|
|
{
|
|
$enabled = $this->env->getBool('ERROR_AGGREGATION_ENABLED', true);
|
|
|
|
if(!$enabled) {
|
|
return new NullErrorAggregator();
|
|
}
|
|
|
|
return new ErrorAggregator(
|
|
storage: $container->get(ErrorStorageInterface::class),
|
|
cache: $container->get(Cache::class),
|
|
clock: $container->get(Clock::class),
|
|
alertQueue: $container->get(Queue::class),
|
|
logger: $container->get(Logger::class),
|
|
batchSize: $this->env->getInt('ERROR_AGGREGATION_BATCH_SIZE', 100),
|
|
maxRetentionDays: $this->env->getInt('ERROR_AGGREGATION_MAX_RETENTION_DAYS', 90)
|
|
);
|
|
}
|
|
|
|
#[Initializer]
|
|
public function initialize(Container $container): void
|
|
{
|
|
$env = $container->get(Environment::class);
|
|
$enabled = $env->getBool('ERROR_AGGREGATION_ENABLED', true);
|
|
|
|
// Storage
|
|
$container->bind(ErrorStorageInterface::class, function (Container $container) use ($enabled) {
|
|
if (! $enabled) {
|
|
// Return a no-op storage if disabled
|
|
return new DatabaseErrorStorage(
|
|
connection: $container->get(ConnectionInterface::class)
|
|
);
|
|
}
|
|
|
|
return new DatabaseErrorStorage(
|
|
connection: $container->get(ConnectionInterface::class)
|
|
);
|
|
});
|
|
|
|
// Error Aggregator Interface - bind to concrete or Null implementation
|
|
// $container->bind(ErrorAggregatorInterface::class, function (Container $container) use ($enabled) {
|
|
// if (! $enabled) {
|
|
// return new NullErrorAggregator();
|
|
// }
|
|
//
|
|
// $env = $container->get(Environment::class);
|
|
// return new ErrorAggregator(
|
|
// storage: $container->get(ErrorStorageInterface::class),
|
|
// cache: $container->get(Cache::class),
|
|
// clock: $container->get(Clock::class),
|
|
// alertQueue: $container->get(Queue::class),
|
|
// logger: $container->get(Logger::class),
|
|
// batchSize: $env->getInt('ERROR_AGGREGATION_BATCH_SIZE', 100),
|
|
// maxRetentionDays: $env->getInt('ERROR_AGGREGATION_MAX_RETENTION_DAYS', 90)
|
|
// );
|
|
// });
|
|
|
|
// Error Aggregator (concrete class) - delegate to interface
|
|
$container->bind(ErrorAggregator::class, function (Container $container) use ($enabled) {
|
|
if (! $enabled) {
|
|
throw new \RuntimeException('ErrorAggregator is disabled. Use ErrorAggregatorInterface instead.');
|
|
}
|
|
|
|
$env = $container->get(Environment::class);
|
|
return new ErrorAggregator(
|
|
storage: $container->get(ErrorStorageInterface::class),
|
|
cache: $container->get(Cache::class),
|
|
clock: $container->get(Clock::class),
|
|
alertQueue: $container->get(Queue::class),
|
|
logger: $container->get(Logger::class),
|
|
batchSize: $env->getInt('ERROR_AGGREGATION_BATCH_SIZE', 100),
|
|
maxRetentionDays: $env->getInt('ERROR_AGGREGATION_MAX_RETENTION_DAYS', 90)
|
|
);
|
|
});
|
|
|
|
// Alert Manager
|
|
$container->bind(AlertManager::class, function (Container $container) {
|
|
$env = $container->get(Environment::class);
|
|
$channels = [];
|
|
|
|
// Email channel (if configured)
|
|
$emailRecipients = $env->get('ALERT_EMAIL_RECIPIENTS');
|
|
if (! empty($emailRecipients)) {
|
|
$recipients = explode(',', $emailRecipients);
|
|
$channels[] = new EmailAlertChannel(
|
|
transport: $container->get(TransportInterface::class),
|
|
recipients: array_map('trim', $recipients),
|
|
fromEmail: $env->get('ALERT_FROM_EMAIL', 'alerts@example.com'),
|
|
fromName: $env->get('ALERT_FROM_NAME', 'Error Alert System')
|
|
);
|
|
}
|
|
|
|
return new AlertManager(
|
|
cache: $container->get(Cache::class),
|
|
clock: $container->get(Clock::class),
|
|
retryQueue: $container->get(Queue::class),
|
|
logger: $container->get(Logger::class),
|
|
channels: $channels,
|
|
throttleConfig: [
|
|
'urgent' => $env->getInt('ALERT_THROTTLE_URGENT', 300),
|
|
'high' => $env->getInt('ALERT_THROTTLE_HIGH', 900),
|
|
'medium' => $env->getInt('ALERT_THROTTLE_MEDIUM', 3600),
|
|
'low' => $env->getInt('ALERT_THROTTLE_LOW', 86400),
|
|
]
|
|
);
|
|
});
|
|
|
|
// Middleware
|
|
$container->bind(ErrorAggregationMiddleware::class, function (Container $container) use ($enabled) {
|
|
return new ErrorAggregationMiddleware(
|
|
errorAggregator: $container->get(ErrorAggregator::class),
|
|
enabled: $enabled
|
|
);
|
|
});
|
|
}
|
|
}
|