$this->getCacheMetrics(), 'registry' => $this->getRegistryStats(), 'timestamp' => time(), 'system' => [ 'memory_usage' => memory_get_usage(true), 'peak_memory' => memory_get_peak_usage(true), ], ]; // Include processor performance if tracking is enabled if ($this->performanceTracker !== null && $this->performanceTracker->isEnabled()) { $metrics['processors'] = $this->performanceTracker->generateReport()->toArray(); } return new JsonResult($metrics); } /** * Get health status * * Quick health check for monitoring systems. * Returns 200 if healthy, 503 if unhealthy. * * @route GET /api/livecomponents/health */ #[Route('/api/livecomponents/health', method: Method::GET)] public function health(): JsonResult { $hasIssues = $this->metricsCollector->hasPerformanceIssues(); $warnings = $this->metricsCollector->getPerformanceWarnings(); $status = [ 'status' => $hasIssues ? 'degraded' : 'healthy', 'components' => [ 'registry' => $this->isRegistryHealthy(), 'cache' => ! $hasIssues, ], 'warnings' => $warnings, 'timestamp' => time(), ]; // Return 503 if unhealthy for monitoring systems $httpStatus = $hasIssues ? 503 : 200; return new JsonResult($status, $httpStatus); } /** * Get cache performance summary * * Focused metrics for cache system performance. * * @route GET /api/livecomponents/metrics/cache */ #[Route('/api/livecomponents/metrics/cache', method: Method::GET)] #[Auth(roles: ['admin'])] public function cacheMetrics(): JsonResult { return new JsonResult($this->getCacheMetrics()); } /** * Get registry statistics * * Component registry stats and metadata. * * @route GET /api/livecomponents/metrics/registry */ #[Route('/api/livecomponents/metrics/registry', method: Method::GET)] #[Auth(roles: ['admin'])] public function registryMetrics(): JsonResult { return new JsonResult($this->getRegistryStats()); } /** * Reset metrics (development only) * * Resets all collected metrics. Only available in development. * * @route POST /api/livecomponents/metrics/reset */ #[Route('/api/livecomponents/metrics/reset', method: Method::POST)] #[Auth(roles: ['admin'])] public function resetMetrics(): JsonResult { // Only allow in development if (getenv('APP_ENV') !== 'development') { return new JsonResult( ['error' => 'Metric reset only available in development'], 403 ); } $this->metricsCollector->reset(); if ($this->performanceTracker !== null) { $this->performanceTracker->reset(); } return new JsonResult([ 'message' => 'Metrics reset successfully', 'timestamp' => time(), ]); } /** * Get cache metrics data */ private function getCacheMetrics(): array { return $this->metricsCollector->getSummary(); } /** * Get registry statistics */ private function getRegistryStats(): array { $componentNames = $this->registry->getAvailableComponentNames(); return [ 'total_components' => count($componentNames), 'component_names' => $componentNames, 'memory_estimate' => $this->estimateRegistryMemoryUsage(), ]; } /** * Check if registry is healthy */ private function isRegistryHealthy(): bool { try { $components = $this->registry->getAvailableComponentNames(); return ! empty($components); } catch (\Throwable $e) { return false; } } /** * Estimate registry memory usage */ private function estimateRegistryMemoryUsage(): int { // Rough estimate: ~5KB per component $componentCount = count($this->registry->getAvailableComponentNames()); return $componentCount * 5 * 1024; // bytes } /** * Inspect specific component * * Returns detailed information about a specific component instance * for debugging and development purposes. * * @route GET /api/livecomponents/inspect/{componentId} */ #[Route('/api/livecomponents/inspect/{componentId}', method: Method::GET)] #[Auth(roles: ['admin'])] public function inspectComponent(string $componentId): JsonResult { try { // Parse component ID $id = ComponentId::fromString($componentId); [$componentName, $instanceId] = explode(':', $componentId, 2); // Get component class name $className = $this->registry->getClassName($componentName); if ($className === null) { return new JsonResult([ 'error' => 'Component not found', 'component_id' => $componentId, ], 404); } // Get metadata $metadata = $this->metadataCache->get($className); // Try to get cached state $cachedState = $this->stateCache->get($id); // Build inspection data $inspection = [ 'component' => [ 'id' => $componentId, 'name' => $componentName, 'instance_id' => $instanceId, 'class' => $className, ], 'metadata' => [ 'properties' => array_map( fn ($prop) => [ 'name' => $prop->name, 'type' => $prop->type, 'nullable' => $prop->nullable, 'hasDefault' => $prop->hasDefaultValue, ], $metadata->properties ), 'actions' => array_map( fn ($action) => [ 'name' => $action->name, 'parameters' => $action->parameters, ], $metadata->actions ), 'constructor_params' => $metadata->constructorParams, 'compiled_at' => date('Y-m-d H:i:s', $metadata->compiledAt), ], 'state' => $cachedState !== null ? [ 'cached' => true, 'data' => $cachedState->toArray(), ] : [ 'cached' => false, 'message' => 'No cached state found', ], 'cache_info' => [ 'metadata_cached' => $this->metadataCache->has($className), 'state_cached' => $cachedState !== null, ], 'timestamp' => time(), ]; return new JsonResult($inspection); } catch (\Throwable $e) { return new JsonResult([ 'error' => 'Inspection failed', 'message' => $e->getMessage(), 'component_id' => $componentId, ], 500); } } /** * List all component instances * * Returns a list of all active component instances with their IDs. * Useful for discovering what components to inspect. * * @route GET /api/livecomponents/instances */ #[Route('/api/livecomponents/instances', method: Method::GET)] #[Auth(roles: ['admin'])] public function listInstances(): JsonResult { $componentNames = $this->registry->getAvailableComponentNames(); $instances = []; foreach ($componentNames as $name) { $className = $this->registry->getClassName($name); if ($className !== null) { $instances[] = [ 'name' => $name, 'class' => $className, 'metadata_cached' => $this->metadataCache->has($className), ]; } } return new JsonResult([ 'total' => count($instances), 'instances' => $instances, 'timestamp' => time(), ]); } }