with(['product', 'node', 'databases', 'user', 'latestOrder']) ->where('type', 'shared') ->whereIn('status', ['active', 'provisioning', 'suspended']) ->when($this->option('account'), fn ($query, $accountId) => $query->where('id', $accountId)) ->get(); $touchedNodeIds = []; foreach ($accounts as $account) { if (! $account->node) { continue; } try { $usage = $sharedNodeProvider->getUsageStats($account); $requestedDiskGb = $account->requestedDiskGb(); $account->update([ 'allocated_disk_gb' => $requestedDiskGb, 'disk_used_bytes' => (int) ($usage['disk_used_bytes'] ?? $account->disk_used_bytes), 'inode_count' => (int) ($usage['inode_count'] ?? $account->inode_count), 'cpu_usage_percent' => $usage['cpu_usage_percent'] ?? $account->cpu_usage_percent, 'memory_used_mb' => (int) ($usage['memory_used_mb'] ?? $account->memory_used_mb), 'process_count' => (int) ($usage['process_count'] ?? $account->process_count), 'io_usage_mb' => $usage['io_usage_mb'] ?? $account->io_usage_mb, 'last_usage_sync_at' => now(), ]); $resourcePolicyService->process($account->fresh(['product', 'node', 'databases', 'user', 'latestOrder'])); $touchedNodeIds[$account->hosting_node_id] = true; $this->line(sprintf( '%s: disk=%dGB inodes=%d cpu=%s%% mem=%dMB proc=%d', $account->username, (int) ceil(((int) ($usage['disk_used_bytes'] ?? 0)) / self::BYTES_PER_GB), (int) ($usage['inode_count'] ?? 0), $usage['cpu_usage_percent'] ?? 'n/a', (int) ($usage['memory_used_mb'] ?? 0), (int) ($usage['process_count'] ?? 0) )); } catch (\Throwable $e) { Log::warning('Failed to sync hosting account usage.', [ 'hosting_account_id' => $account->id, 'username' => $account->username, 'error' => $e->getMessage(), ]); $this->warn("Failed to sync {$account->username}: {$e->getMessage()}"); } } foreach (array_keys($touchedNodeIds) as $nodeId) { $node = HostingNode::query()->find($nodeId); if ($node) { $capacityService->refreshNodeResourceTotals($node); $capacityService->checkNode($node); } } $this->info("Synced {$accounts->count()} hosting account(s)."); return self::SUCCESS; } }