add app monitoring charts and runtime metrics
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-07-09 13:09:41 +09:00
parent f142de8763
commit fbefc08b85
+45
View File
@@ -62,6 +62,7 @@ export class RuntimeService {
} }
async listPodMetrics(namespace?: string) { async listPodMetrics(namespace?: string) {
try {
const output = await this.kubectl([ const output = await this.kubectl([
'top', 'top',
'pods', 'pods',
@@ -70,6 +71,50 @@ export class RuntimeService {
]); ]);
return parsePodMetrics(output, Boolean(namespace), namespace); return parsePodMetrics(output, Boolean(namespace), namespace);
} catch {
return this.listRunningPodMetrics(namespace);
}
}
private async listRunningPodMetrics(namespace?: string) {
const pods = await this.kubectlJson([
'get',
'pods',
'-o',
'json',
...(namespace ? ['-n', namespace] : ['--all-namespaces']),
]);
const runningPods = (pods.items ?? [])
.filter((pod: KubectlJson) => pod.status?.phase === 'Running')
.map((pod: KubectlJson) => ({
namespace: pod.metadata?.namespace,
name: pod.metadata?.name,
}))
.filter((pod: { namespace?: string; name?: string }) => pod.namespace && pod.name);
if (!runningPods.length) {
return [];
}
const byNamespace = new Map<string, string[]>();
runningPods.forEach((pod: { namespace: string; name: string }) => {
byNamespace.set(pod.namespace, [...(byNamespace.get(pod.namespace) ?? []), pod.name]);
});
const outputs = await Promise.all([...byNamespace.entries()].map(([podNamespace, podNames]) => (
this.kubectl([
'top',
'pods',
...podNames,
'-n',
podNamespace,
'--no-headers',
])
.then((output) => parsePodMetrics(output, true, podNamespace))
.catch(() => [])
)));
return outputs.flat();
} }
async getClusterMetrics() { async getClusterMetrics() {