feat(Production): Complete production deployment infrastructure

- 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.
This commit is contained in:
2025-10-25 19:18:37 +02:00
parent caa85db796
commit fc3d7e6357
83016 changed files with 378904 additions and 20919 deletions

View File

@@ -0,0 +1,215 @@
<?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,
];
}
}