- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
216 lines
6.6 KiB
PHP
216 lines
6.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Queue\MachineLearning;
|
|
|
|
use App\Framework\MachineLearning\ModelManagement\ModelRegistry;
|
|
use App\Framework\MachineLearning\ModelManagement\ModelPerformanceMonitor;
|
|
use App\Framework\MachineLearning\ModelManagement\ValueObjects\ModelMetadata;
|
|
use App\Framework\Core\ValueObjects\Version;
|
|
use App\Framework\Core\ValueObjects\Timestamp;
|
|
use App\Framework\Queue\MachineLearning\ValueObjects\JobFeatures;
|
|
use App\Framework\Queue\MachineLearning\ValueObjects\JobAnomalyResult;
|
|
|
|
/**
|
|
* Queue Job Anomaly Detection Model Management Adapter
|
|
*
|
|
* Integrates JobAnomalyDetector with the ML Model Management System:
|
|
* - Automatic model registration
|
|
* - Real-time performance tracking
|
|
* - Prediction monitoring
|
|
* - Configuration management
|
|
*
|
|
* Usage:
|
|
* ```php
|
|
* $adapter = new QueueAnomalyModelAdapter($registry, $performanceMonitor, $detector);
|
|
*
|
|
* // Register current model version
|
|
* $adapter->registerCurrentModel();
|
|
*
|
|
* // Analyze with tracking
|
|
* $result = $adapter->analyzeWithTracking($features, $groundTruth);
|
|
* ```
|
|
*/
|
|
final readonly class QueueAnomalyModelAdapter
|
|
{
|
|
private const MODEL_NAME = 'queue-anomaly';
|
|
private const CURRENT_VERSION = '1.0.0';
|
|
|
|
public function __construct(
|
|
private ModelRegistry $registry,
|
|
private ModelPerformanceMonitor $performanceMonitor,
|
|
private JobAnomalyDetector $detector
|
|
) {}
|
|
|
|
/**
|
|
* Register current queue anomaly model in registry
|
|
*/
|
|
public function registerCurrentModel(?array $performanceMetrics = null): ModelMetadata
|
|
{
|
|
$version = Version::fromString(self::CURRENT_VERSION);
|
|
|
|
// Check if already registered
|
|
if ($this->registry->exists(self::MODEL_NAME, $version)) {
|
|
return $this->registry->get(self::MODEL_NAME, $version);
|
|
}
|
|
|
|
// Create metadata
|
|
$metadata = ModelMetadata::forQueueAnomaly(
|
|
version: $version,
|
|
configuration: $this->detector->getConfiguration()
|
|
);
|
|
|
|
// Add performance metrics if provided
|
|
if ($performanceMetrics !== null) {
|
|
$metadata = $metadata->withPerformanceMetrics($performanceMetrics);
|
|
}
|
|
|
|
// Register in registry
|
|
$this->registry->register($metadata);
|
|
|
|
return $metadata;
|
|
}
|
|
|
|
/**
|
|
* Analyze job features with automatic performance tracking
|
|
*
|
|
* @param JobFeatures $features Job execution features
|
|
* @param bool|null $groundTruth Ground truth (if known) - true if job is anomalous
|
|
*
|
|
* @return array Analysis result with tracking info
|
|
*/
|
|
public function analyzeWithTracking(
|
|
JobFeatures $features,
|
|
?bool $groundTruth = null
|
|
): array {
|
|
// Perform ML analysis
|
|
$analysisResult = $this->detector->detect($features);
|
|
|
|
// Determine prediction
|
|
$prediction = $analysisResult->isAnomalous;
|
|
$confidence = $analysisResult->anomalyScore->getValue() / 100.0; // Convert 0-100 to 0.0-1.0
|
|
|
|
// Track prediction in performance monitor
|
|
$this->performanceMonitor->trackPrediction(
|
|
modelName: self::MODEL_NAME,
|
|
version: Version::fromString(self::CURRENT_VERSION),
|
|
prediction: $prediction,
|
|
actual: $groundTruth,
|
|
confidence: $confidence,
|
|
features: $this->extractFeatureSummary($analysisResult)
|
|
);
|
|
|
|
// Convert result to array format
|
|
$resultArray = [
|
|
'is_anomalous' => $analysisResult->isAnomalous,
|
|
'anomaly_score' => $analysisResult->anomalyScore->getValue(),
|
|
'feature_scores' => array_map(
|
|
fn($score) => $score->getValue(),
|
|
$analysisResult->featureScores
|
|
),
|
|
'detected_patterns' => $analysisResult->detectedPatterns,
|
|
'primary_indicator' => $analysisResult->primaryIndicator,
|
|
'success' => true
|
|
];
|
|
|
|
// Add tracking info
|
|
$resultArray['tracking'] = [
|
|
'model_name' => self::MODEL_NAME,
|
|
'model_version' => self::CURRENT_VERSION,
|
|
'prediction' => $prediction ? 'anomalous' : 'normal',
|
|
'ground_truth' => $groundTruth,
|
|
'tracked' => true,
|
|
];
|
|
|
|
return $resultArray;
|
|
}
|
|
|
|
/**
|
|
* Get current model performance metrics
|
|
*/
|
|
public function getCurrentPerformanceMetrics(): array
|
|
{
|
|
return $this->performanceMonitor->getCurrentMetrics(
|
|
self::MODEL_NAME,
|
|
Version::fromString(self::CURRENT_VERSION)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if model performance has degraded
|
|
*/
|
|
public function checkPerformanceDegradation(float $thresholdPercent = 0.05): array
|
|
{
|
|
return $this->performanceMonitor->getPerformanceDegradationInfo(
|
|
self::MODEL_NAME,
|
|
Version::fromString(self::CURRENT_VERSION),
|
|
$thresholdPercent
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Update model configuration in registry
|
|
*/
|
|
public function updateConfiguration(array $newConfiguration): void
|
|
{
|
|
$version = Version::fromString(self::CURRENT_VERSION);
|
|
$metadata = $this->registry->get(self::MODEL_NAME, $version);
|
|
|
|
if ($metadata === null) {
|
|
throw new \RuntimeException(
|
|
'Model not registered. Call registerCurrentModel() first.'
|
|
);
|
|
}
|
|
|
|
$updated = $metadata->withConfiguration($newConfiguration);
|
|
$this->registry->update($updated);
|
|
}
|
|
|
|
/**
|
|
* Deploy current model to production
|
|
*/
|
|
public function deployToProduction(): void
|
|
{
|
|
$version = Version::fromString(self::CURRENT_VERSION);
|
|
$metadata = $this->registry->get(self::MODEL_NAME, $version);
|
|
|
|
if ($metadata === null) {
|
|
throw new \RuntimeException(
|
|
'Model not registered. Call registerCurrentModel() first.'
|
|
);
|
|
}
|
|
|
|
$deployed = $metadata->withDeployment(
|
|
environment: 'production',
|
|
deployedAt: Timestamp::now()
|
|
);
|
|
|
|
$this->registry->update($deployed);
|
|
}
|
|
|
|
/**
|
|
* Get model metadata
|
|
*/
|
|
public function getModelMetadata(): ?ModelMetadata
|
|
{
|
|
return $this->registry->get(
|
|
self::MODEL_NAME,
|
|
Version::fromString(self::CURRENT_VERSION)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Extract feature summary for tracking
|
|
*/
|
|
private function extractFeatureSummary(JobAnomalyResult $result): array
|
|
{
|
|
return [
|
|
'feature_count' => count($result->featureScores),
|
|
'pattern_count' => count($result->detectedPatterns),
|
|
'primary_indicator' => $result->primaryIndicator,
|
|
'is_anomalous' => $result->isAnomalous,
|
|
];
|
|
}
|
|
}
|