Enable Discovery debug logging for production troubleshooting

- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -0,0 +1,205 @@
<?php
declare(strict_types=1);
namespace App\Framework\Discovery\Memory;
use App\Framework\Core\ValueObjects\Byte;
/**
* Memory guard for continuous memory monitoring during discovery operations
*
* Provides real-time memory monitoring with automatic emergency handling
* to prevent out-of-memory conditions during long-running operations.
*/
final class MemoryGuard
{
private array $memoryHistory = [];
private int $checkCounter = 0;
private bool $emergencyMode = false;
private mixed $emergencyCallback = null;
public function __construct(
private readonly DiscoveryMemoryManager $memoryManager,
?callable $emergencyCallback = null
) {
$this->emergencyCallback = $emergencyCallback;
}
/**
* Check memory status and take action if needed
*/
public function check(): GuardResult
{
$this->checkCounter++;
$memoryStatus = $this->memoryManager->getMemoryStatus();
// Track memory history for leak detection
$this->memoryHistory[] = $memoryStatus->currentUsage;
// Keep only recent history to prevent memory growth
if (count($this->memoryHistory) > 100) {
$this->memoryHistory = array_slice($this->memoryHistory, -50);
}
$actions = [];
// Handle critical memory situations
if ($memoryStatus->status === MemoryStatus::CRITICAL && ! $this->emergencyMode) {
$this->emergencyMode = true;
$actions[] = GuardAction::EMERGENCY_CLEANUP;
if ($this->emergencyCallback) {
($this->emergencyCallback)();
}
// Perform immediate cleanup
$cleanupResult = $this->memoryManager->performCleanup();
$actions[] = $cleanupResult->wasEffective()
? GuardAction::CLEANUP_SUCCESSFUL
: GuardAction::CLEANUP_FAILED;
}
// Handle warning conditions
if ($memoryStatus->status === MemoryStatus::WARNING) {
$actions[] = GuardAction::WARNING_ISSUED;
// Suggest cleanup if it's time
if ($this->memoryManager->shouldCleanup($this->checkCounter)) {
$actions[] = GuardAction::CLEANUP_SUGGESTED;
}
}
// Check for memory leaks periodically
if ($this->checkCounter % 20 === 0) {
$leakInfo = $this->memoryManager->checkForMemoryLeaks($this->memoryHistory);
if ($leakInfo !== null) {
$actions[] = match ($leakInfo->severity) {
LeakSeverity::CRITICAL => GuardAction::CRITICAL_LEAK_DETECTED,
LeakSeverity::HIGH => GuardAction::HIGH_LEAK_DETECTED,
LeakSeverity::MEDIUM => GuardAction::MEDIUM_LEAK_DETECTED,
LeakSeverity::LOW => GuardAction::LOW_LEAK_DETECTED
};
}
}
// Reset emergency mode if memory is back to normal
if ($this->emergencyMode && $memoryStatus->status === MemoryStatus::NORMAL) {
$this->emergencyMode = false;
$actions[] = GuardAction::EMERGENCY_MODE_RESET;
}
return new GuardResult(
memoryStatus: $memoryStatus,
actions: $actions,
checkNumber: $this->checkCounter,
emergencyMode: $this->emergencyMode
);
}
/**
* Force emergency cleanup
*/
public function forceEmergencyCleanup(): MemoryCleanupResult
{
$this->emergencyMode = true;
if ($this->emergencyCallback) {
($this->emergencyCallback)();
}
return $this->memoryManager->performCleanup();
}
/**
* Get current memory statistics
*/
public function getStatistics(): GuardStatistics
{
$memoryStatus = $this->memoryManager->getMemoryStatus();
$historyCount = count($this->memoryHistory);
$averageUsage = $historyCount > 0
? Byte::fromBytes((int) (array_sum(array_map(fn ($byte) => $byte->toBytes(), $this->memoryHistory)) / $historyCount))
: Byte::zero();
$peakUsage = $historyCount > 0
? array_reduce($this->memoryHistory, fn ($max, $current) => $current->greaterThan($max ?? Byte::zero()) ? $current : $max, Byte::zero())
: Byte::zero();
return new GuardStatistics(
totalChecks: $this->checkCounter,
currentStatus: $memoryStatus,
averageUsage: $averageUsage,
peakUsage: $peakUsage,
historySize: $historyCount,
emergencyMode: $this->emergencyMode
);
}
/**
* Reset guard state
*/
public function reset(): void
{
$this->memoryHistory = [];
$this->checkCounter = 0;
$this->emergencyMode = false;
}
/**
* Check if it's safe to continue processing
*/
public function isSafeToProcess(): bool
{
$memoryStatus = $this->memoryManager->getMemoryStatus();
return $memoryStatus->status !== MemoryStatus::CRITICAL;
}
/**
* Get recommendations for current memory state
* @return string[]
*/
public function getRecommendations(): array
{
$memoryStatus = $this->memoryManager->getMemoryStatus();
$recommendations = [];
switch ($memoryStatus->status) {
case MemoryStatus::CRITICAL:
$recommendations[] = 'Immediate action required: Reduce batch size or stop processing';
$recommendations[] = 'Consider switching to STREAMING memory strategy';
$recommendations[] = 'Force garbage collection and cleanup caches';
break;
case MemoryStatus::WARNING:
$recommendations[] = 'Consider reducing batch size';
$recommendations[] = 'Enable more frequent cleanup cycles';
$recommendations[] = 'Monitor for memory leaks';
break;
case MemoryStatus::NORMAL:
if ($memoryStatus->memoryPressure->toDecimal() > 0.5) {
$recommendations[] = 'Memory usage is moderate - consider optimization';
}
break;
}
// Check for potential leaks
if (count($this->memoryHistory) > 10) {
$leakInfo = $this->memoryManager->checkForMemoryLeaks($this->memoryHistory);
if ($leakInfo !== null) {
$recommendations[] = "Memory leak detected ({$leakInfo->severity->value}): Review object retention";
}
}
return $recommendations;
}
}