toString(); echo " [Cache] get() called for key: {$key}\n"; if (isset($this->data[$key])) { $value = $this->data[$key]; $hits[$key] = $value instanceof CacheItem ? $value->value : $value; echo " [Cache] Cache HIT for key: {$key}\n"; } else { $misses[] = $key; echo " [Cache] Cache MISS for key: {$key}\n"; } } return new CacheResult($hits, $misses); } public function set(CacheItem ...$items): bool { foreach ($items as $item) { $key = $item->key->toString(); $this->data[$key] = $item; echo " [Cache] set() called - stored key: {$key}\n"; } return true; } public function has(CacheIdentifier ...$identifiers): array { return []; } public function forget(CacheIdentifier ...$identifiers): bool { return true; } public function clear(): bool { $this->data = []; return true; } public function remember(CacheKey $key, callable $callback, ?Duration $ttl = null): CacheItem { $keyStr = $key->toString(); if (isset($this->data[$keyStr])) { return $this->data[$keyStr]; } $value = $callback(); $item = CacheItem::forSetting($key, $value, $ttl); $this->data[$keyStr] = $item; return $item; } }; // Create test clock $clock = new class implements Clock { public function now(): \DateTimeImmutable { return new \DateTimeImmutable(); } public function fromTimestamp(Timestamp $timestamp): \DateTimeImmutable { return $timestamp->toDateTime(); } public function fromString(string $dateTime, ?string $format = null): \DateTimeImmutable { return new \DateTimeImmutable($dateTime); } public function today(): \DateTimeImmutable { return new \DateTimeImmutable('today'); } public function yesterday(): \DateTimeImmutable { return new \DateTimeImmutable('yesterday'); } public function tomorrow(): \DateTimeImmutable { return new \DateTimeImmutable('tomorrow'); } public function time(): Timestamp { return Timestamp::now(); } }; echo "Setting up ErrorAggregator...\n"; $storage = new InMemoryErrorStorage(); $alertQueue = new InMemoryQueue(); $errorAggregator = new ErrorAggregator( storage: $storage, cache: $cache, clock: $clock, alertQueue: $alertQueue ); echo "\nCreating exception and context...\n"; $exception = FrameworkException::create( DatabaseErrorCode::QUERY_FAILED, 'Test database query failed' ); echo " Exception created: " . $exception->getMessage() . "\n"; echo " Exception error code: " . $exception->getErrorCode()->value . "\n"; $exceptionContext = ExceptionContext::empty() ->withOperation('test_operation', 'TestComponent') ->withData([ 'test_key' => 'test_value', 'original_exception' => $exception, 'exception_message' => $exception->getMessage() ]); echo " ExceptionContext created with operation: test_operation, component: TestComponent\n"; $requestContext = RequestContext::fromGlobals(); $systemContext = SystemContext::current(); $errorHandlerContext = ErrorHandlerContext::create( $exceptionContext, $requestContext, $systemContext, ['http_status' => 500] ); echo "\nCreating ErrorEvent from ErrorHandlerContext...\n"; $errorEvent = ErrorEvent::fromErrorHandlerContext($errorHandlerContext, $clock); echo " ErrorEvent created:\n"; echo " ID: " . (string) $errorEvent->id . "\n"; echo " Service: {$errorEvent->service}\n"; echo " Component: {$errorEvent->component}\n"; echo " Operation: {$errorEvent->operation}\n"; echo " Message: {$errorEvent->errorMessage}\n"; echo " Severity: {$errorEvent->severity->value}\n"; echo " Fingerprint: " . $errorEvent->getFingerprint() . "\n"; echo "\nProcessing error through ErrorAggregator...\n"; $errorAggregator->processError($errorHandlerContext); echo "\nChecking results...\n"; $recentEvents = $errorAggregator->getRecentEvents(10); echo "Recent events: " . count($recentEvents) . "\n"; $activePatterns = $errorAggregator->getActivePatterns(10); echo "Active patterns: " . count($activePatterns) . "\n"; if (count($activePatterns) > 0) { echo "SUCCESS: Pattern was created!\n"; $pattern = $activePatterns[0]; echo " Pattern ID: " . (string) $pattern->id . "\n"; echo " Fingerprint: {$pattern->fingerprint}\n"; echo " Occurrences: {$pattern->occurrenceCount}\n"; echo " Component: {$pattern->component}\n"; echo " Is Active: " . ($pattern->isActive ? 'true' : 'false') . "\n"; } else { echo "ERROR: Pattern was NOT created!\n"; echo "\nDirect storage check...\n"; // Reflection to access private patterns property $reflectionClass = new ReflectionClass($storage); $patternsProperty = $reflectionClass->getProperty('patterns'); $patternsProperty->setAccessible(true); $patternsArray = $patternsProperty->getValue($storage); echo "Patterns array count: " . count($patternsArray) . "\n"; if (count($patternsArray) > 0) { echo "Patterns exist in storage but getActivePatterns() returns 0!\n"; foreach ($patternsArray as $patternId => $pattern) { echo " Pattern {$patternId}:\n"; echo " isActive: " . ($pattern->isActive ? 'true' : 'false') . "\n"; echo " Component: {$pattern->component}\n"; echo " Occurrences: {$pattern->occurrenceCount}\n"; } } else { echo "No patterns stored at all - storePattern() may not be called or fails silently\n"; } }