feat: add a runtime diagnostics page
CI / checks (pull_request) Failing after 13m18s

Adds GET /api/clouds/:cloud/diagnostics and a Diagnostics page in the
General nav. The report combines, in one call:

- runtime reachability, latency, version and edition from /_floci/health
- every service the runtime emulates, with the console pages backed by it
- per-console-service probes (the existing status check)
- EC2 instance containers from /_floci/diagnose
- console uptime, sign-in mode and active session count

Each source is optional, so a down runtime still yields a partial report.
This commit is contained in:
Zakaria
2026-10-23 11:29:48 -04:00
parent 432d9d4ce1
commit 953ba951db
13 changed files with 793 additions and 2 deletions
+8
View File
@@ -13,6 +13,7 @@ export const apiEndpointKeys = {
list: "clouds.list",
services: "clouds.services.list",
status: "clouds.status.get",
diagnostics: "clouds.diagnostics.get",
serviceStatus: "clouds.services.status.get",
schema: "clouds.services.schema.get",
dependencies: "clouds.services.dependencies.get",
@@ -323,6 +324,13 @@ export const endpointRegistry: EndpointRegistry = new Map([
method: "GET",
},
],
[
apiEndpointKeys.clouds.diagnostics,
{
path: "/clouds/:cloud/diagnostics",
method: "GET",
},
],
[
apiEndpointKeys.clouds.serviceStatus,
{
@@ -6,6 +6,7 @@ import type {
CloudServiceStatus,
CloudServiceType,
CloudStatus,
RuntimeDiagnostics,
} from "@/types/cloud";
import type {
AppConfigConfigurationProfile,
@@ -86,6 +87,18 @@ export async function getCloudStatus(
return res.data;
}
export async function getCloudDiagnostics(
cloud: CloudProvider,
signal?: AbortSignal,
): Promise<RuntimeDiagnostics> {
const res = await apiClient.call<RuntimeDiagnostics>(
apiEndpointKeys.clouds.diagnostics,
requestOptions(cloud, "cloud-proxy", { signal }),
{ cloud },
);
return res.data;
}
export async function getCloudServiceStatus(
cloud: CloudProvider,
service: CloudServiceType,
@@ -1,5 +1,6 @@
import {useQuery} from '@tanstack/react-query'
import {
getCloudDiagnostics,
getCloudResource,
getCloudServiceStatus,
getCloudStatus,
@@ -20,6 +21,7 @@ export const cloudQueryKeys = {
clouds: ['clouds'] as const,
services: (cloud: CloudProvider) => ['cloud-services', cloud] as const,
status: (cloud: CloudProvider) => ['cloud-status', cloud] as const,
diagnostics: (cloud: CloudProvider) => ['cloud-diagnostics', cloud] as const,
serviceStatus: (cloud: CloudProvider, service: CloudServiceType) =>
['cloud-service-status', cloud, service] as const,
resources: (cloud: CloudProvider, service: CloudServiceType) =>
@@ -53,6 +55,15 @@ export function useCloudStatusQuery(cloud: CloudProvider, options: {refetchInter
})
}
/** Full runtime report; polled slowly because it probes every console service. */
export function useCloudDiagnosticsQuery(cloud: CloudProvider) {
return useQuery({
queryKey: cloudQueryKeys.diagnostics(cloud),
queryFn: ({signal}) => getCloudDiagnostics(cloud, signal),
refetchInterval: 30_000,
})
}
/** Health of the single service being viewed, rather than of the whole cloud. */
export function useCloudServiceStatusQuery(
cloud: CloudProvider,