@64mb/freelens-power 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +5 -1
  2. package/out/main/common/monitoring-history.js +52 -0
  3. package/out/main/common/monitoring-history.js.map +1 -0
  4. package/out/main/common/store/monitoring-preferences-store.js +25 -2
  5. package/out/main/common/store/monitoring-preferences-store.js.map +1 -1
  6. package/out/main/dashboard-views.js +132 -28
  7. package/out/main/dashboard-views.js.map +1 -1
  8. package/out/main/index.js +2 -0
  9. package/out/main/index.js.map +1 -1
  10. package/out/main/monitoring-history-database.js +103 -0
  11. package/out/main/monitoring-history-database.js.map +1 -0
  12. package/out/main/monitoring-history-worker.js +61 -0
  13. package/out/main/monitoring-history-worker.js.map +1 -0
  14. package/out/main/monitoring-history.js +100 -0
  15. package/out/main/monitoring-history.js.map +1 -0
  16. package/out/renderer/_virtual/_global-external_mobx.js +2 -1
  17. package/out/renderer/diagnostics.js +647 -0
  18. package/out/renderer/diagnostics.js.map +1 -0
  19. package/out/renderer/index.js +28 -1
  20. package/out/renderer/index.js.map +1 -1
  21. package/out/renderer/monitoring-collector.js +202 -0
  22. package/out/renderer/monitoring-collector.js.map +1 -0
  23. package/out/renderer/monitoring-history-collection.js +184 -0
  24. package/out/renderer/monitoring-history-collection.js.map +1 -0
  25. package/out/renderer/monitoring-history-view.js +150 -0
  26. package/out/renderer/monitoring-history-view.js.map +1 -0
  27. package/out/renderer/monitoring-history.js +19 -0
  28. package/out/renderer/monitoring-history.js.map +1 -0
  29. package/out/renderer/monitoring.js +98 -125
  30. package/out/renderer/monitoring.js.map +1 -1
  31. package/out/renderer/node-monitoring.js +116 -0
  32. package/out/renderer/node-monitoring.js.map +1 -0
  33. package/out/renderer/pod-monitoring.js +39 -8
  34. package/out/renderer/pod-monitoring.js.map +1 -1
  35. package/out/renderer/preferences/monitoring-preferences.js +55 -10
  36. package/out/renderer/preferences/monitoring-preferences.js.map +1 -1
  37. package/out/renderer/src/common/monitoring-history.js +15 -0
  38. package/out/renderer/src/common/monitoring-history.js.map +1 -0
  39. package/out/renderer/src/common/monitoring-math.js +98 -0
  40. package/out/renderer/src/common/monitoring-math.js.map +1 -0
  41. package/out/renderer/src/common/resource-diagnostics.js +227 -0
  42. package/out/renderer/src/common/resource-diagnostics.js.map +1 -0
  43. package/out/renderer/src/common/store/monitoring-preferences-store.js +25 -2
  44. package/out/renderer/src/common/store/monitoring-preferences-store.js.map +1 -1
  45. package/out/renderer/welcome.js +3 -1
  46. package/out/renderer/welcome.js.map +1 -1
  47. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","names":[],"sources":["../../src/renderer/diagnostics.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { reaction } from \"mobx\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n buildConsumerGroups,\n type ConsumerGroup,\n type DiagnosticsObject,\n diagnosePendingPod,\n effectivePodResource,\n normalizeEvents,\n observeResourceChanges,\n type PodUsage,\n type ResourceSummary,\n type TimelineEntry,\n} from \"../common/resource-diagnostics\";\nimport { MonitoringPreferencesStore } from \"../common/store/monitoring-preferences-store\";\nimport { AiIcon } from \"./ai-icon\";\nimport { MetricChart } from \"./monitoring\";\nimport {\n getCollectedPodUsage,\n getMonitoringSnapshot,\n type MonitoringSnapshot,\n retainMonitoringCollector,\n} from \"./monitoring-collector\";\nimport { isHistoryTracked, setHistoryTracked } from \"./monitoring-history-collection\";\nimport { MonitoringHistoryRange, useMonitoringHistory } from \"./monitoring-history-view\";\n\nimport type { HistoryIdentity } from \"../common/monitoring-history\";\nimport type { MonitoringSample } from \"../common/monitoring-math\";\n\ntype Tab = \"Consumers\" | \"Timeline\" | \"Pending\";\nconst hidden = () => document.visibilityState === \"hidden\";\nconst activeId = () => Renderer.Catalog.activeCluster.get()?.metadata.uid;\nconst groupKey = (group: ConsumerGroup) => `${group.namespace}/${group.identity}`;\nfunction resourceText(value: number | undefined, metric: \"cpu\" | \"memory\"): string {\n if (value === undefined) return \"Unavailable\";\n return metric === \"cpu\" ? `${value.toFixed(3)} cores` : `${(value / 1024 ** 2).toFixed(1)} MiB`;\n}\nfunction summaryText(summary: ResourceSummary, metric: \"cpu\" | \"memory\"): string {\n const request = summary.unknownRequestPods\n ? `partial ${resourceText(summary.requests, metric)} known (${summary.unknownRequestPods} pods unknown)`\n : resourceText(summary.requests, metric);\n const ratio =\n summary.usage !== undefined &&\n summary.requests > 0 &&\n !summary.unknownRequestPods &&\n summary.coveredPods === summary.totalPods\n ? `${((summary.usage / summary.requests) * 100).toFixed(0)}% of requests`\n : \"ratio unavailable\";\n return `${resourceText(summary.usage, metric)} (${summary.coveredPods}/${summary.totalPods} pods covered), requests ${request}, ${ratio}`;\n}\nfunction unscheduledText(summary: ResourceSummary, metric: \"cpu\" | \"memory\"): string {\n return `${summary.unknownRequestPods ? \"Partial known: \" : \"\"}${resourceText(summary.unscheduledRequests, metric)}`;\n}\nconst resources: Record<string, string> = {\n Pod: \"/api/v1\",\n Deployment: \"/apis/apps/v1\",\n ReplicaSet: \"/apis/apps/v1\",\n StatefulSet: \"/apis/apps/v1\",\n DaemonSet: \"/apis/apps/v1\",\n Job: \"/apis/batch/v1\",\n CronJob: \"/apis/batch/v1\",\n};\nconst plurals: Record<string, string> = {\n Pod: \"pods\",\n Deployment: \"deployments\",\n ReplicaSet: \"replicasets\",\n StatefulSet: \"statefulsets\",\n DaemonSet: \"daemonsets\",\n Job: \"jobs\",\n CronJob: \"cronjobs\",\n};\nfunction openResource(object: DiagnosticsObject, clusterId: string): void {\n const kind = object.kind ?? \"Pod\";\n if (activeId() !== clusterId || !object.metadata.name || !object.metadata.namespace || !resources[kind]) return;\n const path = `${resources[kind]}/namespaces/${encodeURIComponent(object.metadata.namespace)}/${plurals[kind]}/${encodeURIComponent(object.metadata.name)}`;\n void Promise.resolve(Renderer.Navigation.showDetails(path)).catch(() => {});\n}\nconst projections = new WeakMap<MonitoringSnapshot, ReturnType<typeof projectSnapshot>>();\nfunction projectSnapshot(data: MonitoringSnapshot) {\n const usage = getCollectedPodUsage(data);\n const groups = buildConsumerGroups(data.pods ?? [], data.owners ?? [], usage);\n const objects = new Map<string, DiagnosticsObject>();\n const children = new Map<string, string[]>();\n for (const object of [...(data.owners ?? []), ...(data.pods ?? [])]) {\n const uid = object.metadata.uid;\n if (!uid) continue;\n objects.set(uid, object);\n const refs = object.metadata.ownerReferences ?? [];\n const parent = refs.find((item) => item.controller) ?? (refs.length === 1 ? refs[0] : undefined);\n if (parent) {\n const siblings = children.get(parent.uid) ?? [];\n siblings.push(uid);\n children.set(parent.uid, siblings);\n }\n }\n const related = new Map<string, Set<string>>();\n for (const group of groups) {\n const seen = new Set<string>();\n const stack = [group.identity];\n while (stack.length) {\n const uid = stack.pop()!;\n if (seen.has(uid)) continue;\n const object = objects.get(uid);\n if (object && object.metadata.namespace !== group.namespace) continue;\n seen.add(uid);\n stack.push(...(children.get(uid) ?? []));\n }\n related.set(groupKey(group), seen);\n }\n return { usage, groups, objects, related };\n}\nfunction projection(data: MonitoringSnapshot) {\n let value = projections.get(data);\n if (!value) {\n value = projectSnapshot(data);\n projections.set(data, value);\n }\n return value;\n}\nexport function DiagnosticsPage() {\n const [tab, setTab] = useState<Tab>(\"Consumers\");\n const [snapshot, setSnapshot] = useState<MonitoringSnapshot>();\n const [error, setError] = useState(\"\");\n const [filter, setFilter] = useState(\"\");\n const [historyTarget, setHistoryTarget] = useState(\"\");\n const [groupMode, setGroupMode] = useState(\"workload\");\n const [namespacesOpen, setNamespacesOpen] = useState<string[]>([]);\n const known = useRef(new Map<string, { group: ConsumerGroup; uids: Set<string> }>());\n const [sort, setSort] = useState(\"cpu\");\n const [expanded, setExpanded] = useState<string[]>([]);\n const [selected, setSelected] = useState(\"\");\n const [pendingUid, setPendingUid] = useState(\"\");\n const [reason, setReason] = useState(\"\");\n const [warningOnly, setWarningOnly] = useState(false);\n const [observed, setObserved] = useState<TimelineEntry[]>([]);\n const previous = useRef<MonitoringSnapshot>();\n useEffect(() => {\n const release = retainMonitoringCollector();\n let disposed = false;\n let generation = 0;\n let loading = false;\n const clear = () => {\n generation++;\n previous.current = undefined;\n known.current.clear();\n setSnapshot(undefined);\n setObserved([]);\n setSelected(\"\");\n setPendingUid(\"\");\n setExpanded([]);\n setError(\"\");\n };\n const load = async () => {\n if (loading || disposed || hidden()) return;\n const cluster = activeId();\n if (!cluster) {\n setError(\"Select a connected cluster\");\n return;\n }\n const current = generation;\n loading = true;\n try {\n const next = await getMonitoringSnapshot(true);\n if (disposed || current !== generation || next.clusterId !== activeId() || hidden()) return;\n const prior = previous.current;\n if (prior === next) return;\n if (prior && prior.clusterId === next.clusterId) {\n const entries: TimelineEntry[] = [];\n if (prior.time !== next.time)\n entries.push(\n ...observeResourceChanges(prior.pods ?? [], next.pods ?? [], new Date(next.time).toISOString()),\n );\n if (prior.owners !== next.owners && next.diagnosticsTime)\n entries.push(\n ...observeResourceChanges(\n prior.owners ?? [],\n next.owners ?? [],\n new Date(next.diagnosticsTime).toISOString(),\n ),\n );\n if (entries.length) setObserved((items) => [...entries, ...items].slice(0, 300));\n }\n const projected = projection(next);\n for (const group of projected.groups) {\n const key = groupKey(group);\n const remembered = known.current.get(key)?.uids ?? new Set<string>();\n for (const uid of projected.related.get(key) ?? []) remembered.add(uid);\n while (remembered.size > 500) remembered.delete(remembered.values().next().value!);\n known.current.set(key, { group, uids: remembered });\n }\n while (known.current.size > 100) known.current.delete(known.current.keys().next().value!);\n previous.current = next;\n setSnapshot(next);\n setError(\"\");\n } catch {\n if (!disposed && current === generation) setError(\"Diagnostics unavailable or access denied\");\n } finally {\n loading = false;\n }\n };\n const stop = reaction(activeId, () => {\n clear();\n void load();\n });\n const visibility = () => {\n if (document.visibilityState !== \"hidden\") void load();\n };\n const timer = window.setInterval(() => void load(), 1000);\n document.addEventListener(\"visibilitychange\", visibility);\n void load();\n return () => {\n disposed = true;\n generation++;\n stop();\n release();\n window.clearInterval(timer);\n document.removeEventListener(\"visibilitychange\", visibility);\n };\n }, []);\n const data = snapshot?.clusterId === activeId() ? snapshot : undefined;\n const projected = useMemo(() => (data ? projection(data) : undefined), [data]);\n const groups = projected?.groups ?? [];\n const filtered = useMemo(\n () =>\n groups\n .filter((group) =>\n `${group.namespace} ${group.name} ${group.kind}`.toLowerCase().includes(filter.toLowerCase()),\n )\n .sort((a, b) =>\n sort === \"name\"\n ? groupKey(a).localeCompare(groupKey(b))\n : sort === \"requests\" || sort === \"memoryRequests\"\n ? b[sort === \"requests\" ? \"cpu\" : \"memory\"].requests - a[sort === \"requests\" ? \"cpu\" : \"memory\"].requests\n : (b[sort === \"memory\" ? \"memory\" : \"cpu\"].usage ?? -1) -\n (a[sort === \"memory\" ? \"memory\" : \"cpu\"].usage ?? -1),\n ),\n [groups, filter, sort],\n );\n const applications = [...known.current.values()].map((item) => item.group);\n const application = applications.find((group) => groupKey(group) === selected);\n const uids = new Set(known.current.get(selected)?.uids ?? []);\n const warningIds = new Set(\n (data?.events ?? []).filter((event) => event.type === \"Warning\").map((event) => event.metadata?.uid),\n );\n const timeline = [...normalizeEvents(data?.events ?? []), ...observed]\n .filter(\n (entry) =>\n !!application &&\n !!entry.objectUid &&\n uids.has(entry.objectUid) &&\n (!reason || `${entry.reason} ${entry.message}`.toLowerCase().includes(reason.toLowerCase())) &&\n (!warningOnly || warningIds.has(entry.id)),\n )\n .sort((a, b) => (Date.parse(b.time ?? \"\") || 0) - (Date.parse(a.time ?? \"\") || 0));\n const pending = (data?.pods ?? []).filter((pod) => pod.status?.phase === \"Pending\");\n const selectedPod = pending.find((pod) => pod.metadata.uid === pendingUid);\n const diagnosis = selectedPod\n ? diagnosePendingPod(selectedPod, data?.nodes ?? [], data?.events ?? [], data?.pvcs)\n : undefined;\n return (\n <div className=\"power-diagnostics\" style={{ padding: 20, overflow: \"auto\", height: \"100%\" }}>\n <style>{`.power-diagnostics table{width:100%;border-collapse:collapse}.power-diagnostics th,.power-diagnostics td{text-align:left;padding:9px;border-bottom:1px solid var(--borderColor);vertical-align:top}.power-diagnostics button,.power-diagnostics select,.power-diagnostics input{margin:4px;padding:6px}.power-diagnostics .toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.power-diagnostics small{display:block;opacity:.75}.power-diagnostics button{cursor:pointer;display:inline-flex;align-items:center;gap:6px;border-radius:4px;border:1px solid var(--borderColor);background:var(--contentColor);color:var(--textColorPrimary);font:inherit}.power-diagnostics button:hover{border-color:var(--primary)}.power-diagnostics button[aria-pressed=true]{color:var(--primary);border-color:var(--primary)}.power-diagnostics button:disabled{opacity:.5;cursor:default}.power-diagnostics select,.power-diagnostics input{border-radius:4px;border:1px solid var(--borderColor);background:var(--contentColor);color:var(--textColorPrimary);font:inherit}.power-diagnostics :is(button,select,input):focus-visible{outline:2px solid var(--primary);outline-offset:2px}.power-diagnostics input[type=checkbox]{accent-color:var(--primary)}.power-diagnostics th{color:var(--textColorSecondary);font-weight:500}.power-diagnostics nav{display:flex;gap:8px;flex-wrap:wrap}`}</style>\n <h2>Resource diagnostics</h2>\n <nav aria-label=\"Diagnostics views\">\n {([\"Consumers\", \"Timeline\", \"Pending\"] as Tab[]).map((name) => (\n <button\n key={name}\n type=\"button\"\n title={`Show ${name.toLowerCase()}`}\n aria-pressed={tab === name}\n onClick={() => setTab(name)}\n >\n <AiIcon\n material={name === \"Consumers\" ? \"account_tree\" : name === \"Timeline\" ? \"timeline\" : \"hourglass_empty\"}\n />\n {name}\n </button>\n ))}\n </nav>\n <p>\n Read-only cluster snapshot\n {data ? ` · ${new Date(data.time).toLocaleTimeString([], { hourCycle: \"h23\" })}` : \" · Loading\"}\n </p>\n {error && <p role=\"status\">{error}</p>}\n {data?.errors.map((message) => (\n <p role=\"status\" key={message}>\n {message}\n </p>\n ))}\n {tab === \"Consumers\" && (\n <>\n <div className=\"toolbar\">\n <label>\n Group by{\" \"}\n <select\n aria-label=\"Group consumers\"\n value={groupMode}\n onChange={(event) => setGroupMode(event.target.value)}\n >\n <option value=\"workload\">Workload</option>\n <option value=\"namespace\">Namespace</option>\n </select>\n </label>\n <input\n aria-label=\"Filter consumers\"\n placeholder=\"Namespace or workload\"\n value={filter}\n onChange={(event) => setFilter(event.target.value)}\n />\n <label>\n Sort{\" \"}\n <select aria-label=\"Sort consumers\" value={sort} onChange={(event) => setSort(event.target.value)}>\n <option value=\"cpu\">CPU usage</option>\n <option value=\"memory\">Memory usage</option>\n <option value=\"requests\">CPU requests</option>\n <option value=\"memoryRequests\">Memory requests</option>\n <option value=\"name\">Namespace / name</option>\n </select>\n </label>\n </div>\n <p>\n Usage coverage is per resource. Missing metrics are unavailable. Unscheduled requests are listed separately.\n </p>\n <table>\n <thead>\n <tr>\n <th>Namespace / consumer</th>\n <th>CPU</th>\n <th>Memory</th>\n <th>Unscheduled requests</th>\n </tr>\n </thead>\n <tbody>\n {(groupMode === \"namespace\" ? [...new Set(filtered.map((group) => group.namespace))] : [\"\"]).map(\n (namespace) => (\n <NamespaceRows\n key={namespace}\n namespace={namespace}\n groups={namespace ? filtered.filter((group) => group.namespace === namespace) : filtered}\n clusterId={data?.clusterId ?? \"\"}\n usage={projected?.usage ?? []}\n viewHistory={setHistoryTarget}\n open={!namespace || namespacesOpen.includes(namespace)}\n toggleNamespace={() =>\n setNamespacesOpen((items) =>\n items.includes(namespace) ? items.filter((item) => item !== namespace) : [...items, namespace],\n )\n }\n expanded={expanded}\n toggleGroup={(key) =>\n setExpanded((items) =>\n items.includes(key) ? items.filter((item) => item !== key) : [...items, key],\n )\n }\n />\n ),\n )}\n </tbody>\n </table>\n {!filtered.length && <p>No consumers available</p>}\n {data && historyTarget && (\n <ApplicationHistory\n key={`${data.clusterId}/${historyTarget}`}\n data={data}\n group={groups.find((group) => groupKey(group) === historyTarget)}\n />\n )}\n </>\n )}\n {tab === \"Timeline\" && (\n <>\n <div className=\"toolbar\">\n <label>\n Application{\" \"}\n <select\n aria-label=\"Timeline application\"\n value={selected}\n onChange={(event) => setSelected(event.target.value)}\n >\n <option value=\"\">Select a workload or standalone pod</option>\n {applications.map((group) => (\n <option key={groupKey(group)} value={groupKey(group)}>\n {group.namespace} / {group.kind} / {group.name}\n </option>\n ))}\n </select>\n </label>\n <input\n aria-label=\"Filter timeline reason\"\n placeholder=\"Reason or message\"\n value={reason}\n onChange={(event) => setReason(event.target.value)}\n />\n <label>\n <input type=\"checkbox\" checked={warningOnly} onChange={(event) => setWarningOnly(event.target.checked)} />\n Warnings only\n </label>\n </div>\n <p>\n Kubernetes events have limited retention. Observed changes begin with this open view, retain at most 300\n entries, and have unknown transition times between snapshots. Related identities observed in this view are\n retained for at most 100 applications and 500 identities per application; older identity coverage can be\n incomplete.\n </p>\n <table>\n <thead>\n <tr>\n <th>Time / certainty</th>\n <th>Reason</th>\n <th>Evidence</th>\n </tr>\n </thead>\n <tbody>\n {timeline.map((entry) => (\n <tr key={entry.id}>\n <td>\n {entry.time ? new Date(entry.time).toLocaleString([], { hourCycle: \"h23\" }) : \"Time unknown\"}\n <small>\n {entry.certainty}, count {entry.count}\n {entry.firstTime\n ? `, first ${new Date(entry.firstTime).toLocaleString([], { hourCycle: \"h23\" })}`\n : \"\"}\n </small>\n </td>\n <td>{entry.reason}</td>\n <td>\n {entry.message}\n {(() => {\n const object = entry.objectUid ? projected?.objects.get(entry.objectUid) : undefined;\n return object && data ? (\n <button\n type=\"button\"\n title=\"Open exact resource details\"\n onClick={() => openResource(object, data.clusterId)}\n >\n <AiIcon material=\"open_in_new\" />\n Open resource\n </button>\n ) : null;\n })()}\n <small>{entry.gap}</small>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n {!timeline.length && (\n <p>\n {application\n ? \"No matching retained events or observed changes\"\n : \"Select an application to inspect its exact resource identities\"}\n </p>\n )}\n </>\n )}\n {tab === \"Pending\" && (\n <>\n <label>\n Pending pod{\" \"}\n <select aria-label=\"Pending pod\" value={pendingUid} onChange={(event) => setPendingUid(event.target.value)}>\n <option value=\"\">Select a pod</option>\n {pending.map((pod) => (\n <option key={pod.metadata.uid} value={pod.metadata.uid}>\n {pod.metadata.namespace} / {pod.metadata.name}\n </option>\n ))}\n </select>\n </label>\n {selectedPod && diagnosis ? (\n <>\n <h3>{diagnosis.state === \"assigned-waiting\" ? \"Assigned and waiting\" : \"Unscheduled\"}</h3>\n <p>\n Requested CPU: {podRequest(selectedPod, \"cpu\")} · Requested memory: {podRequest(selectedPod, \"memory\")}\n </p>\n <p>\n Node selector:{\" \"}\n {Object.entries(selectedPod.spec?.nodeSelector ?? {})\n .map(([key, value]) => `${key}=${value}`)\n .join(\", \") || \"None\"}\n </p>\n <p>\n Tolerations:{\" \"}\n {(selectedPod.spec?.tolerations ?? [])\n .map(\n (item) =>\n `${item.key || \"all keys\"} ${item.operator ?? \"Equal\"}${item.value ? ` ${item.value}` : \"\"} (${item.effect || \"all effects\"})`,\n )\n .join(\", \") || \"None\"}\n </p>\n <p>\n Required node affinity:{\" \"}\n {selectedPod.spec?.affinity?.nodeAffinity?.requiredDuringSchedulingIgnoredDuringExecution\n ? JSON.stringify(\n selectedPod.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution,\n ).slice(0, 2000)\n : \"None\"}\n </p>\n\n <button type=\"button\" title=\"Open pod details\" onClick={() => openResource(selectedPod, data!.clusterId)}>\n <AiIcon material=\"open_in_new\" />\n Open pod\n </button>\n <p>\n {selectedPod.status?.conditions\n ?.map(\n (condition) =>\n `${condition.type}: ${condition.status}${condition.message ? ` (${condition.message})` : \"\"}`,\n )\n .join(\" · \")}\n </p>\n <table>\n <thead>\n <tr>\n <th>Evidence source</th>\n <th>Node</th>\n <th>Finding</th>\n </tr>\n </thead>\n <tbody>\n {diagnosis.evidence.map((entry, index) => (\n <tr key={`${entry.node}/${index}`}>\n <td>{entry.source === \"event\" ? \"Reported Kubernetes event\" : \"Local hard constraint\"}</td>\n <td>{entry.node ?? \"—\"}</td>\n <td>{entry.message}</td>\n </tr>\n ))}\n </tbody>\n </table>\n {!diagnosis.evidence.length && <p>No retained evidence is available for this pod</p>}\n {diagnosis.limitations.map((message) => (\n <p key={message}>{message}</p>\n ))}\n </>\n ) : (\n <p>{pending.length ? \"Select a pending pod\" : \"No pending pods available\"}</p>\n )}\n </>\n )}\n </div>\n );\n}\nfunction ConsumerRows({\n group,\n clusterId,\n expanded,\n toggle,\n usage,\n viewHistory,\n}: {\n group: ConsumerGroup;\n clusterId: string;\n expanded: boolean;\n toggle: () => void;\n usage: PodUsage[];\n viewHistory: (key: string) => void;\n}) {\n return (\n <>\n <tr>\n <td>\n <button\n type=\"button\"\n title={expanded ? \"Collapse pods\" : \"Expand pods\"}\n aria-expanded={expanded}\n onClick={toggle}\n >\n <AiIcon material={expanded ? \"expand_less\" : \"expand_more\"} />\n {group.namespace} / {group.kind} / {group.name}\n </button>\n <small>\n {group.pods.length} pods{group.ownerResolved ? \"\" : \" · Owner chain incomplete\"}\n </small>\n <TrackButton\n identity={{ clusterId, scope: group.kind === \"Pod\" ? \"pod\" : \"workload\", uid: group.identity }}\n />\n <button type=\"button\" title=\"View resource history\" onClick={() => viewHistory(groupKey(group))}>\n <AiIcon material=\"timeline\" />\n View history\n </button>\n </td>\n <td>{summaryText(group.cpu, \"cpu\")}</td>\n <td>{summaryText(group.memory, \"memory\")}</td>\n <td>\n {unscheduledText(group.cpu, \"cpu\")} / {unscheduledText(group.memory, \"memory\")}\n </td>\n </tr>\n {expanded &&\n group.pods.map((pod) => (\n <tr key={pod.metadata.uid}>\n <td>\n <button type=\"button\" title=\"Open pod details\" onClick={() => openResource(pod, clusterId)}>\n <AiIcon material=\"open_in_new\" />\n {pod.metadata.name}\n </button>{\" \"}\n {pod.metadata.uid && <TrackButton identity={{ clusterId, scope: \"pod\", uid: pod.metadata.uid }} />}\n {pod.status?.phase ?? \"Unknown\"} ·{\" \"}\n {pod.spec?.nodeName ? `Assigned to ${pod.spec.nodeName}` : \"Unscheduled\"}\n </td>\n <td>{podSummary(pod, usage, \"cpu\")}</td>\n <td>{podSummary(pod, usage, \"memory\")}</td>\n <td>{pod.spec?.nodeName ? \"—\" : \"Included above\"}</td>\n </tr>\n ))}\n </>\n );\n}\n\nfunction TrackButton({ identity }: { identity: HistoryIdentity }) {\n const preferences = MonitoringPreferencesStore.getInstanceOrCreate<MonitoringPreferencesStore>();\n const [, update] = useState(0);\n useEffect(\n () =>\n reaction(\n () => [preferences.historyEnabled, isHistoryTracked(identity)],\n () => update((value) => value + 1),\n ),\n [identity.clusterId, identity.scope, identity.uid, preferences],\n );\n const tracked = isHistoryTracked(identity);\n return (\n <button\n type=\"button\"\n disabled={!preferences.historyEnabled}\n title={\n preferences.historyEnabled\n ? \"Track numeric resource history locally\"\n : \"Enable local history in extension preferences\"\n }\n aria-pressed={tracked}\n onClick={() => {\n if (activeId() !== identity.clusterId || !preferences.historyEnabled) return;\n setHistoryTracked(identity, !tracked);\n update((value) => value + 1);\n }}\n >\n <AiIcon material={tracked ? \"visibility\" : \"visibility_off\"} />\n {tracked ? \"Stop tracking\" : \"Track history\"}\n </button>\n );\n}\n\nfunction podRequest(pod: DiagnosticsObject, metric: \"cpu\" | \"memory\"): string {\n try {\n return resourceText(effectivePodResource(pod, metric), metric);\n } catch {\n return \"Unavailable\";\n }\n}\nfunction podSummary(pod: DiagnosticsObject, usage: PodUsage[], metric: \"cpu\" | \"memory\"): string {\n let request: number | undefined;\n try {\n request = effectivePodResource(pod, metric);\n } catch {}\n const value = usage.find((item) => item.uid === pod.metadata.uid)?.[metric];\n return `${resourceText(value, metric)}, requests ${resourceText(request, metric)}${value !== undefined && request ? `, ${((value / request) * 100).toFixed(0)}% of requests` : \", ratio unavailable\"}`;\n}\nfunction NamespaceRows({\n namespace,\n groups,\n clusterId,\n usage,\n open,\n toggleNamespace,\n expanded,\n toggleGroup,\n viewHistory,\n}: {\n namespace: string;\n groups: ConsumerGroup[];\n clusterId: string;\n usage: PodUsage[];\n viewHistory: (key: string) => void;\n open: boolean;\n toggleNamespace: () => void;\n expanded: string[];\n toggleGroup: (key: string) => void;\n}) {\n const sum = (metric: \"cpu\" | \"memory\"): ResourceSummary =>\n groups.reduce(\n (total, group) => {\n const next = group[metric];\n return {\n requests: total.requests + next.requests,\n scheduledRequests: total.scheduledRequests + next.scheduledRequests,\n unscheduledRequests: total.unscheduledRequests + next.unscheduledRequests,\n usage:\n total.usage === undefined && next.usage === undefined ? undefined : (total.usage ?? 0) + (next.usage ?? 0),\n coveredPods: total.coveredPods + next.coveredPods,\n totalPods: total.totalPods + next.totalPods,\n unknownRequestPods: total.unknownRequestPods + next.unknownRequestPods,\n };\n },\n {\n requests: 0,\n scheduledRequests: 0,\n unscheduledRequests: 0,\n coveredPods: 0,\n totalPods: 0,\n unknownRequestPods: 0,\n } as ResourceSummary,\n );\n return (\n <>\n {namespace && (\n <tr>\n <td>\n <button type=\"button\" title=\"Expand namespace workloads\" aria-expanded={open} onClick={toggleNamespace}>\n <AiIcon material={open ? \"expand_less\" : \"expand_more\"} />\n {namespace}\n </button>\n <small>{groups.length} consumers</small>\n </td>\n <td>{summaryText(sum(\"cpu\"), \"cpu\")}</td>\n <td>{summaryText(sum(\"memory\"), \"memory\")}</td>\n <td>\n {unscheduledText(sum(\"cpu\"), \"cpu\")} / {unscheduledText(sum(\"memory\"), \"memory\")}\n </td>\n </tr>\n )}\n {open &&\n groups.map((group) => (\n <ConsumerRows\n key={groupKey(group)}\n group={group}\n clusterId={clusterId}\n expanded={expanded.includes(groupKey(group))}\n toggle={() => toggleGroup(groupKey(group))}\n usage={usage}\n viewHistory={viewHistory}\n />\n ))}\n </>\n );\n}\n\nfunction ApplicationHistory({ data, group }: { data: MonitoringSnapshot; group?: ConsumerGroup }) {\n const live = useMemo((): MonitoringSample[] => {\n if (\n !group ||\n group.cpu.coveredPods !== group.cpu.totalPods ||\n group.memory.coveredPods !== group.memory.totalPods ||\n group.cpu.usage === undefined ||\n group.memory.usage === undefined\n )\n return [];\n const names = new Set(group.pods.map((pod) => `${pod.metadata.namespace}/${pod.metadata.name}`));\n const times = (data.podMetrics ?? [])\n .filter((metric) => names.has(`${metric.metadata.namespace}/${metric.metadata.name}`))\n .map((metric) => Date.parse(metric.timestamp));\n if (!times.length || times.some((time) => !Number.isFinite(time))) return [];\n return [\n {\n time: Math.min(...times),\n cpu: group.cpu.usage,\n memory: group.memory.usage,\n resources: {\n cpu: { requests: group.cpu.unknownRequestPods ? undefined : group.cpu.requests },\n memory: { requests: group.memory.unknownRequestPods ? undefined : group.memory.requests },\n },\n },\n ];\n }, [data, group]);\n const history = useMonitoringHistory(\n group\n ? { clusterId: data.clusterId, scope: group.kind === \"Pod\" ? \"pod\" : \"workload\", uid: group.identity }\n : undefined,\n live,\n );\n return (\n <section aria-label=\"Application resource history\">\n <h3>{group?.name ?? \"Unavailable application\"} resource history</h3>\n <MonitoringHistoryRange range={history.range} onChange={history.setRange} />\n <p role=\"status\">{history.status}</p>\n <p>\n {live.length\n ? \"Live usage includes every current pod; source metric timestamps are used\"\n : \"Complete current usage unavailable; missing coverage remains a gap\"}\n </p>\n {([\"cpu\", \"memory\"] as const).map((metric) => (\n <MetricChart\n key={metric}\n metric={metric}\n samples={history.samples}\n scope=\"pod\"\n status={live.length ? \"\" : \"Complete live usage unavailable\"}\n />\n ))}\n </section>\n );\n}\n"],"mappings":"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"}
@@ -20,8 +20,12 @@ const require_appearance = require("./appearance.js");
20
20
  const require_button_styles = require("./button-styles.js");
21
21
  const require_dashboard = require("./dashboard.js");
22
22
  const require_secret_certificate_details = require("./details/secret-certificate-details.js");
23
- const require_secure_node_shell_menu = require("./menus/secure-node-shell-menu.js");
23
+ const require_monitoring_collector = require("./monitoring-collector.js");
24
24
  const require_monitoring = require("./monitoring.js");
25
+ const require_monitoring_history_collection = require("./monitoring-history-collection.js");
26
+ const require_diagnostics = require("./diagnostics.js");
27
+ const require_secure_node_shell_menu = require("./menus/secure-node-shell-menu.js");
28
+ const require_node_monitoring = require("./node-monitoring.js");
25
29
  const require_pod_monitoring = require("./pod-monitoring.js");
26
30
  const require_preferences = require("./preferences/preferences.js");
27
31
  const require_read_only = require("./read-only.js");
@@ -60,6 +64,8 @@ var FreelensPowerRenderer = class extends require_extensions.Renderer.LensExtens
60
64
  disposers = [];
61
65
  if (enabled) for (const start of [
62
66
  require_read_only.startReadOnlyMode,
67
+ require_monitoring_collector.startMonitoringCollector,
68
+ require_monitoring_history_collection.startMonitoringHistoryCollection,
63
69
  require_monitoring.startMonitoring,
64
70
  require_pod_monitoring.startPodMonitoring,
65
71
  require_button_styles.startPowerButtonStyles,
@@ -94,6 +100,19 @@ var FreelensPowerRenderer = class extends require_extensions.Renderer.LensExtens
94
100
  id: "dashboard",
95
101
  components: { Page: () => /* @__PURE__ */ require_jsx_runtime.jsx(PowerEnabled, { children: /* @__PURE__ */ require_jsx_runtime.jsx(require_dashboard.DashboardPage, { onOpenPreferences: () => this.navigateToPreferences() }) }) }
96
102
  }];
103
+ clusterPages = [{
104
+ id: "diagnostics",
105
+ components: { Page: () => /* @__PURE__ */ require_jsx_runtime.jsx(PowerEnabled, { children: /* @__PURE__ */ require_jsx_runtime.jsx(require_diagnostics.DiagnosticsPage, {}) }) }
106
+ }];
107
+ clusterPageMenus = [{
108
+ visible: require__global_external_mobx.computed(() => require_power_preferences_store.PowerPreferencesStore.getInstanceOrCreate().enabled),
109
+ target: { pageId: "diagnostics" },
110
+ title: "Diagnostics",
111
+ components: { Icon: () => /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Icon, {
112
+ material: "insights",
113
+ tooltip: "Resource diagnostics"
114
+ }) }
115
+ }];
97
116
  topBarItems = [{ components: { Item: () => /* @__PURE__ */ require_jsx_runtime.jsx(PowerEnabled, { children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Icon, {
98
117
  material: "battery_charging_full",
99
118
  className: "freelens-power-settings-icon",
@@ -101,6 +120,14 @@ var FreelensPowerRenderer = class extends require_extensions.Renderer.LensExtens
101
120
  onClick: () => this.navigateToPreferences()
102
121
  }) }) } }];
103
122
  kubeObjectDetailItems = [{
123
+ kind: "Node",
124
+ apiVersions: ["v1"],
125
+ priority: 10,
126
+ components: { Details: (props) => /* @__PURE__ */ require_jsx_runtime.jsx(PowerEnabled, { children: /* @__PURE__ */ require_jsx_runtime.jsx(require_node_monitoring.NodeMonitoringDetails, {
127
+ ...props,
128
+ object: props.object
129
+ }) }) }
130
+ }, {
104
131
  kind: "Secret",
105
132
  apiVersions: ["v1"],
106
133
  priority: 10,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/renderer/index.tsx"],"sourcesContent":["/**\n * Copyright (c) Freelens Authors. All rights reserved.\n * Licensed under MIT License. See THIRD_PARTY_LICENSES for more information.\n */\n\nimport { Common, Renderer } from \"@freelensapp/extensions\";\nimport { reaction } from \"mobx\";\nimport { observer } from \"mobx-react\";\nimport { EXTENSION_DISPLAY_NAME, EXTENSION_ID } from \"../common/extension-info\";\nimport { AiPreferencesStore } from \"../common/store/ai-preferences-store\";\nimport { AiShortcutsStore } from \"../common/store/ai-shortcuts-store\";\nimport { AppearancePreferencesStore } from \"../common/store/appearance-preferences-store\";\nimport { DashboardPreferencesStore } from \"../common/store/dashboard-preferences-store\";\nimport { MonitoringPreferencesStore } from \"../common/store/monitoring-preferences-store\";\nimport { NodeShellPreferencesStore } from \"../common/store/node-shell-preferences-store\";\nimport { PowerPreferencesStore } from \"../common/store/power-preferences-store\";\nimport { ReadOnlyPreferencesStore } from \"../common/store/read-only-preferences-store\";\nimport { startAiChat } from \"./ai\";\nimport { startAppearanceOverride } from \"./appearance\";\nimport { startPowerButtonStyles } from \"./button-styles\";\nimport { DashboardPage } from \"./dashboard\";\nimport { SecretCertificateDetails } from \"./details/secret-certificate-details\";\nimport { SecureNodeShellMenu } from \"./menus/secure-node-shell-menu\";\nimport { startMonitoring } from \"./monitoring\";\nimport { startPodMonitoring } from \"./pod-monitoring\";\nimport { PowerPreferences } from \"./preferences/preferences\";\nimport { startReadOnlyMode } from \"./read-only\";\nimport { startWelcomeOverride } from \"./welcome\";\n\nimport type { ReactNode } from \"react\";\n\nconst PowerEnabled = observer(({ children }: { children: ReactNode }) =>\n PowerPreferencesStore.getInstanceOrCreate<PowerPreferencesStore>().enabled ? <>{children}</> : null,\n);\n\nexport default class FreelensPowerRenderer extends Renderer.LensExtension {\n get name() {\n return EXTENSION_DISPLAY_NAME;\n }\n get sanitizedExtensionId() {\n return EXTENSION_ID;\n }\n get storeName() {\n return this.manifest.storeName || EXTENSION_ID;\n }\n\n private stopFeatures?: () => void;\n\n onActivate() {\n const power = PowerPreferencesStore.getInstanceOrCreate<PowerPreferencesStore>();\n power.loadExtension(this);\n AiPreferencesStore.getInstanceOrCreate().loadExtension(this);\n AiShortcutsStore.getInstanceOrCreate().loadExtension(this);\n ReadOnlyPreferencesStore.getInstanceOrCreate().loadExtension(this);\n NodeShellPreferencesStore.getInstanceOrCreate().loadExtension(this);\n MonitoringPreferencesStore.getInstanceOrCreate().loadExtension(this);\n AppearancePreferencesStore.getInstanceOrCreate().loadExtension(this);\n DashboardPreferencesStore.getInstanceOrCreate().loadExtension(this);\n this.stopFeatures?.();\n let disposers: (() => void)[] = [];\n const stop = reaction(\n () => power.enabled,\n (enabled) => {\n for (const dispose of disposers) dispose();\n disposers = [];\n if (enabled) {\n for (const start of [\n startReadOnlyMode,\n startMonitoring,\n startPodMonitoring,\n startPowerButtonStyles,\n startAppearanceOverride,\n startWelcomeOverride,\n startAiChat,\n ]) {\n try {\n disposers.push(start());\n } catch {\n Common.logger.warn(\"[Freelens Power] feature could not start\", { feature: start.name });\n }\n }\n }\n },\n { fireImmediately: true },\n );\n this.stopFeatures = () => {\n stop();\n for (const dispose of disposers) dispose();\n disposers = [];\n };\n }\n\n onDeactivate() {\n this.stopFeatures?.();\n this.stopFeatures = undefined;\n }\n\n appPreferences = [\n {\n id: \"freelens-power-settings\",\n title: \"\",\n components: { Input: PowerPreferences, Hint: () => null },\n },\n ];\n\n globalPages = [\n {\n id: \"dashboard\",\n components: {\n Page: () => (\n <PowerEnabled>\n <DashboardPage onOpenPreferences={() => this.navigateToPreferences()} />\n </PowerEnabled>\n ),\n },\n },\n ];\n\n topBarItems = [\n {\n components: {\n Item: () => (\n <PowerEnabled>\n <Renderer.Component.Icon\n material=\"battery_charging_full\"\n className=\"freelens-power-settings-icon\"\n tooltip=\"Freelens Power settings\"\n onClick={() => this.navigateToPreferences()}\n />\n </PowerEnabled>\n ),\n },\n },\n ];\n\n kubeObjectDetailItems: Renderer.LensExtension[\"kubeObjectDetailItems\"] = [\n {\n kind: \"Secret\",\n apiVersions: [\"v1\"],\n priority: 10,\n components: {\n Details: (props) => (\n <PowerEnabled>\n <SecretCertificateDetails {...props} object={props.object as Renderer.K8sApi.Secret} />\n </PowerEnabled>\n ),\n },\n },\n ];\n\n kubeObjectMenuItems = [\n {\n kind: \"Node\",\n apiVersions: [\"v1\"],\n components: {\n MenuItem: (props: Renderer.Component.KubeObjectMenuProps<Renderer.K8sApi.Node>) => (\n <PowerEnabled>\n <SecureNodeShellMenu {...props} />\n </PowerEnabled>\n ),\n },\n },\n ];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/renderer/index.tsx"],"sourcesContent":["/**\n * Copyright (c) Freelens Authors. All rights reserved.\n * Licensed under MIT License. See THIRD_PARTY_LICENSES for more information.\n */\n\nimport { Common, Renderer } from \"@freelensapp/extensions\";\nimport { computed, reaction } from \"mobx\";\nimport { observer } from \"mobx-react\";\nimport { EXTENSION_DISPLAY_NAME, EXTENSION_ID } from \"../common/extension-info\";\nimport { AiPreferencesStore } from \"../common/store/ai-preferences-store\";\nimport { AiShortcutsStore } from \"../common/store/ai-shortcuts-store\";\nimport { AppearancePreferencesStore } from \"../common/store/appearance-preferences-store\";\nimport { DashboardPreferencesStore } from \"../common/store/dashboard-preferences-store\";\nimport { MonitoringPreferencesStore } from \"../common/store/monitoring-preferences-store\";\nimport { NodeShellPreferencesStore } from \"../common/store/node-shell-preferences-store\";\nimport { PowerPreferencesStore } from \"../common/store/power-preferences-store\";\nimport { ReadOnlyPreferencesStore } from \"../common/store/read-only-preferences-store\";\nimport { startAiChat } from \"./ai\";\nimport { startAppearanceOverride } from \"./appearance\";\nimport { startPowerButtonStyles } from \"./button-styles\";\nimport { DashboardPage } from \"./dashboard\";\nimport { SecretCertificateDetails } from \"./details/secret-certificate-details\";\nimport { DiagnosticsPage } from \"./diagnostics\";\nimport { SecureNodeShellMenu } from \"./menus/secure-node-shell-menu\";\nimport { startMonitoring } from \"./monitoring\";\nimport { startMonitoringCollector } from \"./monitoring-collector\";\nimport { startMonitoringHistoryCollection } from \"./monitoring-history-collection\";\nimport { NodeMonitoringDetails } from \"./node-monitoring\";\nimport { startPodMonitoring } from \"./pod-monitoring\";\nimport { PowerPreferences } from \"./preferences/preferences\";\nimport { startReadOnlyMode } from \"./read-only\";\nimport { startWelcomeOverride } from \"./welcome\";\n\nimport type { ReactNode } from \"react\";\n\nconst PowerEnabled = observer(({ children }: { children: ReactNode }) =>\n PowerPreferencesStore.getInstanceOrCreate<PowerPreferencesStore>().enabled ? <>{children}</> : null,\n);\n\nexport default class FreelensPowerRenderer extends Renderer.LensExtension {\n get name() {\n return EXTENSION_DISPLAY_NAME;\n }\n get sanitizedExtensionId() {\n return EXTENSION_ID;\n }\n get storeName() {\n return this.manifest.storeName || EXTENSION_ID;\n }\n\n private stopFeatures?: () => void;\n\n onActivate() {\n const power = PowerPreferencesStore.getInstanceOrCreate<PowerPreferencesStore>();\n power.loadExtension(this);\n AiPreferencesStore.getInstanceOrCreate().loadExtension(this);\n AiShortcutsStore.getInstanceOrCreate().loadExtension(this);\n ReadOnlyPreferencesStore.getInstanceOrCreate().loadExtension(this);\n NodeShellPreferencesStore.getInstanceOrCreate().loadExtension(this);\n MonitoringPreferencesStore.getInstanceOrCreate().loadExtension(this);\n AppearancePreferencesStore.getInstanceOrCreate().loadExtension(this);\n DashboardPreferencesStore.getInstanceOrCreate().loadExtension(this);\n this.stopFeatures?.();\n let disposers: (() => void)[] = [];\n const stop = reaction(\n () => power.enabled,\n (enabled) => {\n for (const dispose of disposers) dispose();\n disposers = [];\n if (enabled) {\n for (const start of [\n startReadOnlyMode,\n startMonitoringCollector,\n startMonitoringHistoryCollection,\n startMonitoring,\n startPodMonitoring,\n startPowerButtonStyles,\n startAppearanceOverride,\n startWelcomeOverride,\n startAiChat,\n ]) {\n try {\n disposers.push(start());\n } catch {\n Common.logger.warn(\"[Freelens Power] feature could not start\", { feature: start.name });\n }\n }\n }\n },\n { fireImmediately: true },\n );\n this.stopFeatures = () => {\n stop();\n for (const dispose of disposers) dispose();\n disposers = [];\n };\n }\n\n onDeactivate() {\n this.stopFeatures?.();\n this.stopFeatures = undefined;\n }\n\n appPreferences = [\n {\n id: \"freelens-power-settings\",\n title: \"\",\n components: { Input: PowerPreferences, Hint: () => null },\n },\n ];\n\n globalPages = [\n {\n id: \"dashboard\",\n components: {\n Page: () => (\n <PowerEnabled>\n <DashboardPage onOpenPreferences={() => this.navigateToPreferences()} />\n </PowerEnabled>\n ),\n },\n },\n ];\n\n clusterPages = [\n {\n id: \"diagnostics\",\n components: {\n Page: () => (\n <PowerEnabled>\n <DiagnosticsPage />\n </PowerEnabled>\n ),\n },\n },\n ];\n\n clusterPageMenus = [\n {\n visible: computed(() => PowerPreferencesStore.getInstanceOrCreate<PowerPreferencesStore>().enabled),\n target: { pageId: \"diagnostics\" },\n title: \"Diagnostics\",\n components: { Icon: () => <Renderer.Component.Icon material=\"insights\" tooltip=\"Resource diagnostics\" /> },\n },\n ];\n\n topBarItems = [\n {\n components: {\n Item: () => (\n <PowerEnabled>\n <Renderer.Component.Icon\n material=\"battery_charging_full\"\n className=\"freelens-power-settings-icon\"\n tooltip=\"Freelens Power settings\"\n onClick={() => this.navigateToPreferences()}\n />\n </PowerEnabled>\n ),\n },\n },\n ];\n\n kubeObjectDetailItems: Renderer.LensExtension[\"kubeObjectDetailItems\"] = [\n {\n kind: \"Node\",\n apiVersions: [\"v1\"],\n priority: 10,\n components: {\n Details: (props) => (\n <PowerEnabled>\n <NodeMonitoringDetails {...props} object={props.object as Renderer.K8sApi.Node} />\n </PowerEnabled>\n ),\n },\n },\n {\n kind: \"Secret\",\n apiVersions: [\"v1\"],\n priority: 10,\n components: {\n Details: (props) => (\n <PowerEnabled>\n <SecretCertificateDetails {...props} object={props.object as Renderer.K8sApi.Secret} />\n </PowerEnabled>\n ),\n },\n },\n ];\n\n kubeObjectMenuItems = [\n {\n kind: \"Node\",\n apiVersions: [\"v1\"],\n components: {\n MenuItem: (props: Renderer.Component.KubeObjectMenuProps<Renderer.K8sApi.Node>) => (\n <PowerEnabled>\n <SecureNodeShellMenu {...props} />\n </PowerEnabled>\n ),\n },\n },\n ];\n}\n"],"mappings":"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"}
@@ -0,0 +1,202 @@
1
+ const require_extensions = require("./_virtual/_global-external_@freelensapp/extensions.js");
2
+ const require__global_external_mobx = require("./_virtual/_global-external_mobx.js");
3
+ const require_monitoring_preferences_store = require("./src/common/store/monitoring-preferences-store.js");
4
+ const require_monitoring_math = require("./src/common/monitoring-math.js");
5
+ //#region src/renderer/monitoring-collector.ts
6
+ var snapshot;
7
+ var pending;
8
+ var extraPending;
9
+ var extraTime = 0;
10
+ var epoch = 0;
11
+ var collectingCluster;
12
+ var retained = 0;
13
+ var listeners = /* @__PURE__ */ new Set();
14
+ function resetMonitoringCollector() {
15
+ epoch++;
16
+ snapshot = void 0;
17
+ pending = void 0;
18
+ extraPending = void 0;
19
+ extraTime = 0;
20
+ collectingCluster = void 0;
21
+ }
22
+ function retainMonitoringCollector() {
23
+ retained++;
24
+ let released = false;
25
+ return () => {
26
+ if (released) return;
27
+ released = true;
28
+ if (--retained === 0) resetMonitoringCollector();
29
+ };
30
+ }
31
+ function onMonitoringSnapshot(listener) {
32
+ listeners.add(listener);
33
+ return () => listeners.delete(listener);
34
+ }
35
+ async function getMonitoringSnapshot(diagnostics = false) {
36
+ const clusterId = require_extensions.Renderer.Catalog.activeCluster.get()?.metadata.uid;
37
+ if (!clusterId) throw new Error("Select a connected cluster");
38
+ if ((snapshot?.clusterId ?? collectingCluster) && (snapshot?.clusterId ?? collectingCluster) !== clusterId) resetMonitoringCollector();
39
+ collectingCluster = clusterId;
40
+ if (!snapshot || Date.now() - snapshot.time >= 3e4) {
41
+ if (!pending) {
42
+ const current = epoch;
43
+ pending = (async () => {
44
+ const results = await Promise.allSettled([
45
+ Promise.resolve().then(() => require_extensions.Renderer.K8sApi.nodesMetricsApi.list()),
46
+ Promise.resolve().then(() => require_extensions.Renderer.K8sApi.nodesApi.list()),
47
+ Promise.resolve().then(() => require_extensions.Renderer.K8sApi.podsApi.list()),
48
+ Promise.resolve().then(() => require_extensions.Renderer.K8sApi.podsMetricsApi.list())
49
+ ]);
50
+ if (current !== epoch || require_extensions.Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId) throw new Error("Cluster changed during collection");
51
+ const [metrics, nodes, pods, podMetrics] = results;
52
+ const next = {
53
+ owners: snapshot?.owners,
54
+ events: snapshot?.events,
55
+ pvcs: snapshot?.pvcs,
56
+ diagnosticsTime: snapshot?.diagnosticsTime,
57
+ clusterId,
58
+ time: Date.now(),
59
+ nodeMetrics: metrics.status === "fulfilled" ? metrics.value ?? void 0 : void 0,
60
+ nodes: nodes.status === "fulfilled" ? nodes.value ?? void 0 : void 0,
61
+ pods: pods.status === "fulfilled" ? pods.value ?? void 0 : void 0,
62
+ podMetrics: podMetrics.status === "fulfilled" ? podMetrics.value ?? void 0 : void 0,
63
+ errors: results.flatMap((result, i) => result.status === "rejected" || result.value === null ? [`${[
64
+ "Node metrics",
65
+ "Nodes",
66
+ "Pods",
67
+ "Pod metrics"
68
+ ][i]} unavailable or access denied`] : [])
69
+ };
70
+ snapshot = next;
71
+ for (const listener of listeners) listener(next);
72
+ return next;
73
+ })().finally(() => {
74
+ if (current === epoch) pending = void 0;
75
+ });
76
+ }
77
+ await pending;
78
+ }
79
+ if (!snapshot || snapshot.clusterId !== clusterId) throw new Error("Cluster changed during collection");
80
+ if (diagnostics && (!extraTime || Date.now() - extraTime >= 3e4)) {
81
+ if (!extraPending) {
82
+ const current = epoch;
83
+ const base = snapshot;
84
+ extraPending = (async () => {
85
+ const apis = [
86
+ require_extensions.Renderer.K8sApi.replicaSetApi,
87
+ require_extensions.Renderer.K8sApi.deploymentApi,
88
+ require_extensions.Renderer.K8sApi.statefulSetApi,
89
+ require_extensions.Renderer.K8sApi.daemonSetApi,
90
+ require_extensions.Renderer.K8sApi.jobApi,
91
+ require_extensions.Renderer.K8sApi.cronJobApi
92
+ ];
93
+ const results = await Promise.allSettled([
94
+ ...apis.map((api) => Promise.resolve().then(() => api.list())),
95
+ Promise.resolve().then(() => require_extensions.Renderer.K8sApi.eventApi.list()),
96
+ Promise.resolve().then(() => require_extensions.Renderer.K8sApi.pvcApi.list())
97
+ ]);
98
+ if (current !== epoch || require_extensions.Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId) throw new Error("Cluster changed during collection");
99
+ const owners = results.slice(0, apis.length).flatMap((result) => result.status === "fulfilled" ? result.value ?? [] : []);
100
+ const events = results[apis.length];
101
+ const pvcs = results[apis.length + 1];
102
+ snapshot = {
103
+ ...snapshot ?? base,
104
+ diagnosticsTime: Date.now(),
105
+ owners,
106
+ events: events.status === "fulfilled" ? events.value : void 0,
107
+ pvcs: pvcs.status === "fulfilled" ? pvcs.value : void 0,
108
+ errors: [...(snapshot ?? base).errors, ...results.flatMap((result, index) => result.status === "rejected" ? [`${[
109
+ "ReplicaSets",
110
+ "Deployments",
111
+ "StatefulSets",
112
+ "DaemonSets",
113
+ "Jobs",
114
+ "CronJobs",
115
+ "Events",
116
+ "PVCs"
117
+ ][index]} unavailable or access denied`] : [])]
118
+ };
119
+ extraTime = Date.now();
120
+ for (const listener of listeners) listener(snapshot);
121
+ return snapshot;
122
+ })().finally(() => {
123
+ if (current === epoch) extraPending = void 0;
124
+ });
125
+ }
126
+ await extraPending;
127
+ }
128
+ if (!snapshot || require_extensions.Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId) throw new Error("Cluster changed during collection");
129
+ return snapshot;
130
+ }
131
+ function getNodeSample(data, name, uid) {
132
+ const node = data.nodes?.find((item) => item.metadata.name === name && (!uid || item.metadata.uid === uid));
133
+ const metric = data.nodeMetrics?.filter((item) => item.metadata.name === name);
134
+ if (!node || metric?.length !== 1) return;
135
+ if (metric[0].metadata.uid && node.metadata.uid && metric[0].metadata.uid !== node.metadata.uid) return;
136
+ const sample = require_monitoring_math.aggregateMetrics(metric);
137
+ sample.time = Date.parse(metric[0].timestamp);
138
+ const created = Date.parse(node.metadata.creationTimestamp ?? "");
139
+ if (Number.isFinite(created) && sample.time < created) return;
140
+ try {
141
+ sample.resources = require_monitoring_math.aggregateResources([node], data.pods);
142
+ } catch {
143
+ sample.resourceStatus = "Resource totals unavailable: incomplete node/pod data";
144
+ }
145
+ if (!data.pods) sample.resourceStatus = "Pod inventory unavailable; requests unavailable";
146
+ return sample;
147
+ }
148
+ function getCollectedPodUsage(data) {
149
+ const index = /* @__PURE__ */ new Map();
150
+ for (const metric of data.podMetrics ?? []) {
151
+ const key = `${metric.metadata.namespace}/${metric.metadata.name}`;
152
+ index.set(key, index.has(key) ? void 0 : metric);
153
+ }
154
+ return (data.pods ?? []).flatMap((pod) => {
155
+ if (!pod.metadata.uid) return [];
156
+ const metric = index.get(`${pod.metadata.namespace}/${pod.metadata.name}`);
157
+ if (!metric) return [];
158
+ if (metric.metadata.uid && metric.metadata.uid !== pod.metadata.uid) return [];
159
+ const time = Date.parse(metric.timestamp);
160
+ const created = Date.parse(pod.metadata.creationTimestamp ?? "");
161
+ if (!Number.isFinite(time) || time < Date.now() - 12e4 || time > Date.now() + 3e4 || Number.isFinite(created) && time < created) return [];
162
+ try {
163
+ if (!metric.containers.length || new Set(metric.containers.map((container) => container.name)).size !== metric.containers.length) return [];
164
+ const sample = require_monitoring_math.aggregateMetrics(metric.containers.map((container) => ({
165
+ ...container,
166
+ timestamp: metric.timestamp
167
+ })));
168
+ return [{
169
+ uid: pod.metadata.uid,
170
+ cpu: sample.cpu,
171
+ memory: sample.memory
172
+ }];
173
+ } catch {
174
+ return [];
175
+ }
176
+ });
177
+ }
178
+ function startMonitoringCollector() {
179
+ const retain = retainMonitoringCollector();
180
+ const preferences = require_monitoring_preferences_store.MonitoringPreferencesStore.getInstanceOrCreate();
181
+ const stop = require__global_external_mobx.reaction(() => preferences.enabled, () => resetMonitoringCollector());
182
+ const collect = () => {
183
+ if (preferences.enabled && document.visibilityState !== "hidden" && require_extensions.Renderer.Catalog.activeCluster.get()) getMonitoringSnapshot(preferences.historyEnabled && preferences.trackedHistory.some((item) => item.scope === "workload")).catch(() => {});
184
+ };
185
+ const timer = window.setInterval(collect, 1e3);
186
+ collect();
187
+ return () => {
188
+ window.clearInterval(timer);
189
+ stop();
190
+ retain();
191
+ };
192
+ }
193
+ //#endregion
194
+ exports.getCollectedPodUsage = getCollectedPodUsage;
195
+ exports.getMonitoringSnapshot = getMonitoringSnapshot;
196
+ exports.getNodeSample = getNodeSample;
197
+ exports.onMonitoringSnapshot = onMonitoringSnapshot;
198
+ exports.resetMonitoringCollector = resetMonitoringCollector;
199
+ exports.retainMonitoringCollector = retainMonitoringCollector;
200
+ exports.startMonitoringCollector = startMonitoringCollector;
201
+
202
+ //# sourceMappingURL=monitoring-collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitoring-collector.js","names":[],"sources":["../../src/renderer/monitoring-collector.ts"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { reaction } from \"mobx\";\nimport {\n aggregateMetrics,\n aggregateResources,\n MONITORING_INTERVAL,\n type MonitoringSample,\n} from \"../common/monitoring-math\";\nimport { MonitoringPreferencesStore } from \"../common/store/monitoring-preferences-store\";\n\nimport type { DiagnosticsEvent, DiagnosticsObject, PodUsage } from \"../common/resource-diagnostics\";\n\ntype NodeMetric = NonNullable<Awaited<ReturnType<typeof Renderer.K8sApi.nodesMetricsApi.list>>>[number];\ntype PodMetric = NonNullable<Awaited<ReturnType<typeof Renderer.K8sApi.podsMetricsApi.list>>>[number];\nexport interface MonitoringSnapshot {\n clusterId: string;\n time: number;\n diagnosticsTime?: number;\n nodes?: Renderer.K8sApi.Node[];\n pods?: Renderer.K8sApi.Pod[];\n nodeMetrics?: NodeMetric[];\n podMetrics?: PodMetric[];\n owners?: DiagnosticsObject[];\n events?: DiagnosticsEvent[];\n pvcs?: DiagnosticsObject[];\n errors: string[];\n}\n\nlet snapshot: MonitoringSnapshot | undefined;\nlet pending: Promise<MonitoringSnapshot> | undefined;\nlet extraPending: Promise<MonitoringSnapshot> | undefined;\nlet extraTime = 0;\nlet epoch = 0;\nlet collectingCluster: string | undefined;\nlet retained = 0;\nconst listeners = new Set<(snapshot: MonitoringSnapshot) => void>();\n\nexport function resetMonitoringCollector(): void {\n epoch++;\n snapshot = undefined;\n pending = undefined;\n extraPending = undefined;\n extraTime = 0;\n collectingCluster = undefined;\n}\n\nexport function retainMonitoringCollector(): () => void {\n retained++;\n let released = false;\n return () => {\n if (released) return;\n released = true;\n if (--retained === 0) resetMonitoringCollector();\n };\n}\n\nexport function onMonitoringSnapshot(listener: (snapshot: MonitoringSnapshot) => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\n// one snapshot is shared by all views in this cluster renderer\nexport async function getMonitoringSnapshot(diagnostics = false): Promise<MonitoringSnapshot> {\n const clusterId = Renderer.Catalog.activeCluster.get()?.metadata.uid;\n if (!clusterId) throw new Error(\"Select a connected cluster\");\n if ((snapshot?.clusterId ?? collectingCluster) && (snapshot?.clusterId ?? collectingCluster) !== clusterId)\n resetMonitoringCollector();\n collectingCluster = clusterId;\n if (!snapshot || Date.now() - snapshot.time >= MONITORING_INTERVAL) {\n if (!pending) {\n const current = epoch;\n pending = (async () => {\n const results = await Promise.allSettled([\n Promise.resolve().then(() => Renderer.K8sApi.nodesMetricsApi.list()),\n Promise.resolve().then(() => Renderer.K8sApi.nodesApi.list()),\n Promise.resolve().then(() => Renderer.K8sApi.podsApi.list()),\n Promise.resolve().then(() => Renderer.K8sApi.podsMetricsApi.list()),\n ]);\n if (current !== epoch || Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId)\n throw new Error(\"Cluster changed during collection\");\n const [metrics, nodes, pods, podMetrics] = results;\n const next: MonitoringSnapshot = {\n owners: snapshot?.owners,\n events: snapshot?.events,\n pvcs: snapshot?.pvcs,\n diagnosticsTime: snapshot?.diagnosticsTime,\n clusterId,\n time: Date.now(),\n nodeMetrics: metrics.status === \"fulfilled\" ? (metrics.value ?? undefined) : undefined,\n nodes: nodes.status === \"fulfilled\" ? (nodes.value ?? undefined) : undefined,\n pods: pods.status === \"fulfilled\" ? (pods.value ?? undefined) : undefined,\n podMetrics: podMetrics.status === \"fulfilled\" ? (podMetrics.value ?? undefined) : undefined,\n errors: results.flatMap((result, i) =>\n result.status === \"rejected\" || result.value === null\n ? [`${[\"Node metrics\", \"Nodes\", \"Pods\", \"Pod metrics\"][i]} unavailable or access denied`]\n : [],\n ),\n };\n snapshot = next;\n for (const listener of listeners) listener(next);\n return next;\n })().finally(() => {\n if (current === epoch) pending = undefined;\n });\n }\n await pending;\n }\n if (!snapshot || snapshot.clusterId !== clusterId) throw new Error(\"Cluster changed during collection\");\n if (diagnostics && (!extraTime || Date.now() - extraTime >= MONITORING_INTERVAL)) {\n if (!extraPending) {\n const current = epoch;\n const base = snapshot;\n extraPending = (async () => {\n const apis = [\n Renderer.K8sApi.replicaSetApi,\n Renderer.K8sApi.deploymentApi,\n Renderer.K8sApi.statefulSetApi,\n Renderer.K8sApi.daemonSetApi,\n Renderer.K8sApi.jobApi,\n Renderer.K8sApi.cronJobApi,\n ];\n const results = await Promise.allSettled([\n ...apis.map((api) =>\n Promise.resolve().then<DiagnosticsObject[] | null>(() => api.list() as Promise<DiagnosticsObject[] | null>),\n ),\n Promise.resolve().then(() => Renderer.K8sApi.eventApi.list()),\n Promise.resolve().then(() => Renderer.K8sApi.pvcApi.list()),\n ]);\n if (current !== epoch || Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId)\n throw new Error(\"Cluster changed during collection\");\n const owners = results\n .slice(0, apis.length)\n .flatMap((result) =>\n result.status === \"fulfilled\" ? ((result.value ?? []) as DiagnosticsObject[]) : [],\n ) as DiagnosticsObject[];\n const events = results[apis.length];\n const pvcs = results[apis.length + 1];\n snapshot = {\n ...(snapshot ?? base),\n diagnosticsTime: Date.now(),\n owners,\n events: events.status === \"fulfilled\" ? (events.value as DiagnosticsEvent[]) : undefined,\n pvcs: pvcs.status === \"fulfilled\" ? (pvcs.value as DiagnosticsObject[]) : undefined,\n errors: [\n ...(snapshot ?? base).errors,\n ...results.flatMap((result, index) =>\n result.status === \"rejected\"\n ? [\n `${[\"ReplicaSets\", \"Deployments\", \"StatefulSets\", \"DaemonSets\", \"Jobs\", \"CronJobs\", \"Events\", \"PVCs\"][index]} unavailable or access denied`,\n ]\n : [],\n ),\n ],\n };\n extraTime = Date.now();\n for (const listener of listeners) listener(snapshot);\n return snapshot;\n })().finally(() => {\n if (current === epoch) extraPending = undefined;\n });\n }\n await extraPending;\n }\n if (!snapshot || Renderer.Catalog.activeCluster.get()?.metadata.uid !== clusterId)\n throw new Error(\"Cluster changed during collection\");\n return snapshot;\n}\n\nexport function getNodeSample(data: MonitoringSnapshot, name: string, uid?: string): MonitoringSample | undefined {\n const node = data.nodes?.find((item) => item.metadata.name === name && (!uid || item.metadata.uid === uid));\n const metric = data.nodeMetrics?.filter((item) => item.metadata.name === name);\n if (!node || metric?.length !== 1) return;\n if (metric[0].metadata.uid && node.metadata.uid && metric[0].metadata.uid !== node.metadata.uid) return;\n const sample = aggregateMetrics(metric);\n sample.time = Date.parse(metric[0].timestamp);\n const created = Date.parse(node.metadata.creationTimestamp ?? \"\");\n if (Number.isFinite(created) && sample.time < created) return;\n try {\n sample.resources = aggregateResources([node], data.pods);\n } catch {\n sample.resourceStatus = \"Resource totals unavailable: incomplete node/pod data\";\n }\n if (!data.pods) sample.resourceStatus = \"Pod inventory unavailable; requests unavailable\";\n return sample;\n}\n\nexport function getCollectedPodUsage(data: MonitoringSnapshot): PodUsage[] {\n const index = new Map<string, PodMetric | undefined>();\n for (const metric of data.podMetrics ?? []) {\n const key = `${metric.metadata.namespace}/${metric.metadata.name}`;\n index.set(key, index.has(key) ? undefined : metric);\n }\n return (data.pods ?? []).flatMap((pod) => {\n if (!pod.metadata.uid) return [];\n const metric = index.get(`${pod.metadata.namespace}/${pod.metadata.name}`);\n if (!metric) return [];\n if (metric.metadata.uid && metric.metadata.uid !== pod.metadata.uid) return [];\n const time = Date.parse(metric.timestamp);\n const created = Date.parse(pod.metadata.creationTimestamp ?? \"\");\n if (\n !Number.isFinite(time) ||\n time < Date.now() - 120_000 ||\n time > Date.now() + 30_000 ||\n (Number.isFinite(created) && time < created)\n )\n return [];\n try {\n if (\n !metric.containers.length ||\n new Set(metric.containers.map((container) => container.name)).size !== metric.containers.length\n )\n return [];\n const sample = aggregateMetrics(\n metric.containers.map((container) => ({ ...container, timestamp: metric.timestamp })),\n );\n return [{ uid: pod.metadata.uid, cpu: sample.cpu, memory: sample.memory }];\n } catch {\n return [];\n }\n });\n}\n\nexport function startMonitoringCollector(): () => void {\n const retain = retainMonitoringCollector();\n const preferences = MonitoringPreferencesStore.getInstanceOrCreate<MonitoringPreferencesStore>();\n const stop = reaction(\n () => preferences.enabled,\n () => resetMonitoringCollector(),\n );\n const collect = () => {\n if (preferences.enabled && document.visibilityState !== \"hidden\" && Renderer.Catalog.activeCluster.get())\n void getMonitoringSnapshot(\n preferences.historyEnabled && preferences.trackedHistory.some((item) => item.scope === \"workload\"),\n ).catch(() => {});\n };\n const timer = window.setInterval(collect, 1000);\n collect();\n return () => {\n window.clearInterval(timer);\n stop();\n retain();\n };\n}\n"],"mappings":"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"}