feat: improve resource reconciliation and observability
This commit is contained in:
+34
-18
@@ -6,6 +6,7 @@ import {
|
||||
type V1LabelSelector,
|
||||
} from "@kubernetes/client-node";
|
||||
import { PassThrough } from "node:stream";
|
||||
import { logKubernetesRequest } from "../lib/request-log";
|
||||
import {
|
||||
KubernetesLogError,
|
||||
type ContainerLogRequest,
|
||||
@@ -19,7 +20,9 @@ function selector(labels: Readonly<Record<string, string>>): string {
|
||||
.join(",");
|
||||
}
|
||||
|
||||
function matchLabels(value: V1LabelSelector | undefined): Record<string, string> {
|
||||
function matchLabels(
|
||||
value: V1LabelSelector | undefined,
|
||||
): Record<string, string> {
|
||||
if (value?.matchExpressions?.length) return {};
|
||||
return value?.matchLabels ?? {};
|
||||
}
|
||||
@@ -62,7 +65,9 @@ export class KubernetesLogs implements KubernetesLogsBackend {
|
||||
return deployments.items.flatMap((deployment) => {
|
||||
const name = deployment.metadata?.name;
|
||||
const labels = matchLabels(deployment.spec?.selector);
|
||||
return name && Object.keys(labels).length ? [{ name, selector: labels }] : [];
|
||||
return name && Object.keys(labels).length
|
||||
? [{ name, selector: labels }]
|
||||
: [];
|
||||
});
|
||||
} catch (error) {
|
||||
throw logError(error);
|
||||
@@ -71,7 +76,10 @@ export class KubernetesLogs implements KubernetesLogsBackend {
|
||||
|
||||
async getService(namespace: string, name: string) {
|
||||
try {
|
||||
const service = await this.core.readNamespacedService({ namespace, name });
|
||||
const service = await this.core.readNamespacedService({
|
||||
namespace,
|
||||
name,
|
||||
});
|
||||
return { name, selector: service.spec?.selector ?? {} };
|
||||
} catch (error) {
|
||||
if (statusCode(error) === 404) return;
|
||||
@@ -79,10 +87,7 @@ export class KubernetesLogs implements KubernetesLogsBackend {
|
||||
}
|
||||
}
|
||||
|
||||
async listPods(
|
||||
namespace: string,
|
||||
labels: Readonly<Record<string, string>>,
|
||||
) {
|
||||
async listPods(namespace: string, labels: Readonly<Record<string, string>>) {
|
||||
try {
|
||||
const pods = await this.core.listNamespacedPod({
|
||||
namespace,
|
||||
@@ -92,7 +97,9 @@ export class KubernetesLogs implements KubernetesLogsBackend {
|
||||
name: pod.metadata?.name ?? "",
|
||||
uid: pod.metadata?.uid ?? "",
|
||||
phase: pod.status?.phase,
|
||||
containers: (pod.spec?.containers ?? []).map((container) => container.name),
|
||||
containers: (pod.spec?.containers ?? []).map(
|
||||
(container) => container.name,
|
||||
),
|
||||
}));
|
||||
} catch (error) {
|
||||
throw logError(error);
|
||||
@@ -126,18 +133,27 @@ export class KubernetesLogs implements KubernetesLogsBackend {
|
||||
};
|
||||
signal.addEventListener("abort", abort, { once: true });
|
||||
try {
|
||||
upstream = await this.logger.log(
|
||||
request.namespace,
|
||||
request.pod,
|
||||
request.container,
|
||||
output,
|
||||
upstream = await logKubernetesRequest(
|
||||
{
|
||||
follow: true,
|
||||
tailLines: request.tailLines,
|
||||
sinceSeconds: request.sinceSeconds,
|
||||
sinceTime: request.sinceTime,
|
||||
timestamps: request.timestamps,
|
||||
method: "GET",
|
||||
pathname: `/api/v1/namespaces/${request.namespace}/pods/${request.pod}/log`,
|
||||
body: undefined,
|
||||
attempt: 1,
|
||||
},
|
||||
() =>
|
||||
this.logger.log(
|
||||
request.namespace,
|
||||
request.pod,
|
||||
request.container,
|
||||
output,
|
||||
{
|
||||
follow: true,
|
||||
tailLines: request.tailLines,
|
||||
sinceSeconds: request.sinceSeconds,
|
||||
sinceTime: request.sinceTime,
|
||||
timestamps: request.timestamps,
|
||||
},
|
||||
),
|
||||
);
|
||||
if (signal.aborted) abort();
|
||||
for await (const chunk of output) yield new Uint8Array(chunk);
|
||||
|
||||
Reference in New Issue
Block a user