@neat.is/core 0.10.6-dev.20261009 → 0.10.6-dev.20261010
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.
- package/dist/{chunk-ECBRGTB2.js → chunk-52SCEPEW.js} +218 -8
- package/dist/chunk-52SCEPEW.js.map +1 -0
- package/dist/cli.cjs +249 -8
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +32 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +218 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/neatd.cjs +218 -7
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-ECBRGTB2.js.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -25582,12 +25582,22 @@ init_cjs_shims();
|
|
|
25582
25582
|
// src/connectors/kubernetes/client.ts
|
|
25583
25583
|
init_cjs_shims();
|
|
25584
25584
|
var import_node_https = require("https");
|
|
25585
|
+
var K8S_RATE_LIMIT = { capacity: 120, refillMs: 1e3 };
|
|
25585
25586
|
function deploymentsPath(namespace) {
|
|
25586
25587
|
return `/apis/apps/v1/namespaces/${namespace}/deployments`;
|
|
25587
25588
|
}
|
|
25588
25589
|
function podsPath(namespace) {
|
|
25589
25590
|
return `/api/v1/namespaces/${namespace}/pods`;
|
|
25590
25591
|
}
|
|
25592
|
+
function podLogPath(namespace, podName, opts = {}) {
|
|
25593
|
+
const params = new URLSearchParams();
|
|
25594
|
+
if (opts.container) params.set("container", opts.container);
|
|
25595
|
+
if (typeof opts.tailLines === "number" && Number.isFinite(opts.tailLines)) params.set("tailLines", String(Math.trunc(opts.tailLines)));
|
|
25596
|
+
if (typeof opts.limitBytes === "number" && Number.isFinite(opts.limitBytes)) params.set("limitBytes", String(Math.trunc(opts.limitBytes)));
|
|
25597
|
+
if (opts.previous) params.set("previous", "true");
|
|
25598
|
+
const qs = params.toString();
|
|
25599
|
+
return `${podsPath(namespace)}/${podName}/log${qs ? `?${qs}` : ""}`;
|
|
25600
|
+
}
|
|
25591
25601
|
function makeK8sFetchImpl(transport) {
|
|
25592
25602
|
const agent = new import_node_https.Agent({
|
|
25593
25603
|
...transport.ca ? { ca: transport.ca } : {},
|
|
@@ -25638,7 +25648,7 @@ async function listResource(transport, namespace, path104, opts = {}) {
|
|
|
25638
25648
|
{ method: "GET", headers: { ...transport.token ? bearerAuthHeader(transport.token) : {}, Accept: "application/json" } },
|
|
25639
25649
|
// accountKey: the (cluster, namespace) pair — an identifier, safe to log, the
|
|
25640
25650
|
// rate-limit bucket for one namespace on one cluster (ADR-131).
|
|
25641
|
-
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, fetchImpl }
|
|
25651
|
+
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, rateLimit: K8S_RATE_LIMIT, fetchImpl }
|
|
25642
25652
|
);
|
|
25643
25653
|
if (!res.ok) {
|
|
25644
25654
|
throw new Error(`kubernetes ${path104} failed: ${res.status} ${res.statusText}`);
|
|
@@ -25659,6 +25669,28 @@ async function fetchDeployments(transport, namespace, opts = {}) {
|
|
|
25659
25669
|
async function fetchPods(transport, namespace, opts = {}) {
|
|
25660
25670
|
return listResource(transport, namespace, podsPath(namespace), opts);
|
|
25661
25671
|
}
|
|
25672
|
+
async function fetchPodLog(transport, namespace, podName, opts = {}) {
|
|
25673
|
+
const base = opts.apiUrl ?? transport.server;
|
|
25674
|
+
const path104 = podLogPath(namespace, podName, {
|
|
25675
|
+
...opts.container ? { container: opts.container } : {},
|
|
25676
|
+
...opts.tailLines !== void 0 ? { tailLines: opts.tailLines } : {},
|
|
25677
|
+
...opts.limitBytes !== void 0 ? { limitBytes: opts.limitBytes } : {},
|
|
25678
|
+
...opts.previous ? { previous: true } : {}
|
|
25679
|
+
});
|
|
25680
|
+
const url = `${base.replace(/\/$/, "")}${path104}`;
|
|
25681
|
+
const fetchImpl = opts.fetchImpl ?? makeK8sFetchImpl(transport);
|
|
25682
|
+
try {
|
|
25683
|
+
const res = await junctionFetch(
|
|
25684
|
+
url,
|
|
25685
|
+
{ method: "GET", headers: { ...transport.token ? bearerAuthHeader(transport.token) : {}, Accept: "text/plain" } },
|
|
25686
|
+
{ provider: "kubernetes", accountKey: `${safeHost(transport.server)}/${namespace}`, rateLimit: K8S_RATE_LIMIT, fetchImpl }
|
|
25687
|
+
);
|
|
25688
|
+
if (!res.ok) return void 0;
|
|
25689
|
+
return await res.text();
|
|
25690
|
+
} catch {
|
|
25691
|
+
return void 0;
|
|
25692
|
+
}
|
|
25693
|
+
}
|
|
25662
25694
|
|
|
25663
25695
|
// src/connectors/kubernetes/kubeconfig.ts
|
|
25664
25696
|
init_cjs_shims();
|
|
@@ -25766,6 +25798,123 @@ function parseK8sTargetName(targetName) {
|
|
|
25766
25798
|
return { serviceName, fault };
|
|
25767
25799
|
}
|
|
25768
25800
|
|
|
25801
|
+
// src/connectors/kubernetes/process-context.ts
|
|
25802
|
+
init_cjs_shims();
|
|
25803
|
+
var DEFAULT_MAX_LOG_LINES = 50;
|
|
25804
|
+
var DEFAULT_MAX_LOG_BYTES2 = 2 * 1024;
|
|
25805
|
+
var DEFAULT_MAX_ENTRIES = 64;
|
|
25806
|
+
var DEFAULT_MAX_VALUE_CHARS = 512;
|
|
25807
|
+
var REDACTED = "***REDACTED***";
|
|
25808
|
+
var SECRET_KEY_RE = /TOKEN|SECRET|KEY|PASSW(?:OR)?D|PWD|(?:^|[^A-Z])PASS(?:$|[^A-Z])|CREDENTIAL|(?:^|[^A-Z])AUTH|PRIVATE|DSN|COOKIE|SESSION|SALT|SIGNATURE|CERT|CONN(?:ECTION)?_?STR/i;
|
|
25809
|
+
function isSecretKey(name) {
|
|
25810
|
+
return SECRET_KEY_RE.test(name);
|
|
25811
|
+
}
|
|
25812
|
+
var PRIVATE_KEY_BLOCK_RE = /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z ]*PRIVATE KEY-----|$)/g;
|
|
25813
|
+
var PRIVATE_KEY_TAIL_RE = /(?:^[A-Za-z0-9+/=]{32,}\r?\n)+-----END [A-Z ]*PRIVATE KEY-----/gm;
|
|
25814
|
+
var URL_USERINFO_RE = /([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)([^\s/@]*)@/g;
|
|
25815
|
+
var SECRET_PAIR_RE = /((?:^|[\s?&;,{("'])[A-Za-z0-9_.-]*?(?:passw(?:or)?d|pwd|(?<![a-z])pass(?![a-z])|secret|token|api[_-]?key|access[_-]?key|private[_-]?key|client[_-]?key|credentials?|(?<![a-z])auth(?![a-z])|(?<![a-z])dsn(?![a-z]))[A-Za-z0-9_.-]*["']?\s*[=:]\s*["']?)([^\s&;,"'})]+)/gi;
|
|
25816
|
+
var AUTH_SCHEME_RE = /\b(Bearer|Basic|Token)\s+[A-Za-z0-9._~+/=-]{8,}/g;
|
|
25817
|
+
var KNOWN_TOKEN_RE = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}|\bAKIA[0-9A-Z]{16}\b|\bgh[pousr]_[A-Za-z0-9]{20,}|\bgithub_pat_[A-Za-z0-9_]{20,}|\bsk_(?:live|test)_[A-Za-z0-9]{10,}|\bxox[abprs]-[A-Za-z0-9-]{10,}|\bglpat-[A-Za-z0-9_-]{16,}|\bAIza[0-9A-Za-z_-]{30,}|\bneat_pat_[A-Za-z0-9_-]{16,}/g;
|
|
25818
|
+
function redactText(text) {
|
|
25819
|
+
return text.replace(PRIVATE_KEY_BLOCK_RE, REDACTED).replace(PRIVATE_KEY_TAIL_RE, REDACTED).replace(URL_USERINFO_RE, (_m, scheme, userinfo) => {
|
|
25820
|
+
const colon = userinfo.indexOf(":");
|
|
25821
|
+
return colon > 0 ? `${scheme}${userinfo.slice(0, colon)}:${REDACTED}@` : `${scheme}${REDACTED}@`;
|
|
25822
|
+
}).replace(SECRET_PAIR_RE, (_m, key) => `${key}${REDACTED}`).replace(AUTH_SCHEME_RE, (_m, scheme) => `${scheme} ${REDACTED}`).replace(KNOWN_TOKEN_RE, REDACTED);
|
|
25823
|
+
}
|
|
25824
|
+
function redactValue(name, value) {
|
|
25825
|
+
if (isSecretKey(name)) return REDACTED;
|
|
25826
|
+
return redactText(value);
|
|
25827
|
+
}
|
|
25828
|
+
function redactArg(arg) {
|
|
25829
|
+
const eq = /^(--?)?([A-Za-z0-9_.-]+)=([\s\S]*)$/.exec(arg);
|
|
25830
|
+
if (eq && isSecretKey(eq[2])) {
|
|
25831
|
+
return `${eq[1] ?? ""}${eq[2]}=${REDACTED}`;
|
|
25832
|
+
}
|
|
25833
|
+
return redactText(arg);
|
|
25834
|
+
}
|
|
25835
|
+
function isSecretFlag(arg) {
|
|
25836
|
+
const m = /^--?([A-Za-z0-9_.-]+)$/.exec(arg);
|
|
25837
|
+
return m !== null && isSecretKey(m[1]);
|
|
25838
|
+
}
|
|
25839
|
+
function capValue(s, max = DEFAULT_MAX_VALUE_CHARS) {
|
|
25840
|
+
return s.length > max ? `${s.slice(0, max)}\u2026` : s;
|
|
25841
|
+
}
|
|
25842
|
+
function describeEnvVar(ev) {
|
|
25843
|
+
const name = typeof ev.name === "string" ? ev.name : "";
|
|
25844
|
+
if (name.length === 0) return void 0;
|
|
25845
|
+
if (typeof ev.value === "string") {
|
|
25846
|
+
return `${name}=${capValue(redactValue(name, ev.value))}`;
|
|
25847
|
+
}
|
|
25848
|
+
const from = ev.valueFrom;
|
|
25849
|
+
if (from) {
|
|
25850
|
+
if (from.secretKeyRef) {
|
|
25851
|
+
const ref = typeof from.secretKeyRef.name === "string" && from.secretKeyRef.name.length > 0 ? from.secretKeyRef.name : "<unnamed>";
|
|
25852
|
+
return `${name}=<from secret ${ref}>`;
|
|
25853
|
+
}
|
|
25854
|
+
if (from.configMapKeyRef) {
|
|
25855
|
+
const ref = typeof from.configMapKeyRef.name === "string" && from.configMapKeyRef.name.length > 0 ? from.configMapKeyRef.name : "<unnamed>";
|
|
25856
|
+
const key = typeof from.configMapKeyRef.key === "string" && from.configMapKeyRef.key.length > 0 ? ` key ${from.configMapKeyRef.key}` : "";
|
|
25857
|
+
return `${name}=<from configMap ${ref}${key}>`;
|
|
25858
|
+
}
|
|
25859
|
+
if (from.fieldRef && typeof from.fieldRef.fieldPath === "string" && from.fieldRef.fieldPath.length > 0) {
|
|
25860
|
+
return `${name}=<from field ${from.fieldRef.fieldPath}>`;
|
|
25861
|
+
}
|
|
25862
|
+
if (from.resourceFieldRef && typeof from.resourceFieldRef.resource === "string" && from.resourceFieldRef.resource.length > 0) {
|
|
25863
|
+
return `${name}=<from resource ${from.resourceFieldRef.resource}>`;
|
|
25864
|
+
}
|
|
25865
|
+
return `${name}=<from reference>`;
|
|
25866
|
+
}
|
|
25867
|
+
return `${name}=`;
|
|
25868
|
+
}
|
|
25869
|
+
function buildContainerEnv(container) {
|
|
25870
|
+
const out = [];
|
|
25871
|
+
for (const ev of container.env ?? []) {
|
|
25872
|
+
const d = describeEnvVar(ev);
|
|
25873
|
+
if (d !== void 0) out.push(d);
|
|
25874
|
+
if (out.length >= DEFAULT_MAX_ENTRIES) break;
|
|
25875
|
+
}
|
|
25876
|
+
return out;
|
|
25877
|
+
}
|
|
25878
|
+
function buildContainerArgs(container) {
|
|
25879
|
+
const raw = [];
|
|
25880
|
+
for (const c of container.command ?? []) if (typeof c === "string") raw.push(c);
|
|
25881
|
+
for (const a of container.args ?? []) if (typeof a === "string") raw.push(a);
|
|
25882
|
+
const out = [];
|
|
25883
|
+
for (let i = 0; i < raw.length && out.length < DEFAULT_MAX_ENTRIES; i++) {
|
|
25884
|
+
const arg = raw[i];
|
|
25885
|
+
out.push(capValue(redactArg(arg)));
|
|
25886
|
+
const next = raw[i + 1];
|
|
25887
|
+
if (isSecretFlag(arg) && next !== void 0 && !next.startsWith("-") && out.length < DEFAULT_MAX_ENTRIES) {
|
|
25888
|
+
out.push(REDACTED);
|
|
25889
|
+
i++;
|
|
25890
|
+
}
|
|
25891
|
+
}
|
|
25892
|
+
return out;
|
|
25893
|
+
}
|
|
25894
|
+
function capProcessLog(text, maxLines = DEFAULT_MAX_LOG_LINES, maxBytes = DEFAULT_MAX_LOG_BYTES2) {
|
|
25895
|
+
const trimmed = text.replace(/\s+$/, "");
|
|
25896
|
+
if (trimmed.length === 0) return "";
|
|
25897
|
+
const lines = trimmed.split("\n");
|
|
25898
|
+
const tail = lines.length > maxLines ? lines.slice(lines.length - maxLines) : lines;
|
|
25899
|
+
let out = tail.join("\n");
|
|
25900
|
+
if (out.length > maxBytes) out = out.slice(out.length - maxBytes);
|
|
25901
|
+
return out;
|
|
25902
|
+
}
|
|
25903
|
+
function buildProcessContext(input) {
|
|
25904
|
+
const out = {};
|
|
25905
|
+
if (typeof input.log === "string") {
|
|
25906
|
+
const capped = capProcessLog(redactText(input.log));
|
|
25907
|
+
if (capped.length > 0) out.processLog = capped;
|
|
25908
|
+
}
|
|
25909
|
+
if (input.container) {
|
|
25910
|
+
const args = buildContainerArgs(input.container);
|
|
25911
|
+
if (args.length > 0) out.containerArgs = args;
|
|
25912
|
+
const env = buildContainerEnv(input.container);
|
|
25913
|
+
if (env.length > 0) out.containerEnv = env;
|
|
25914
|
+
}
|
|
25915
|
+
return out;
|
|
25916
|
+
}
|
|
25917
|
+
|
|
25769
25918
|
// src/connectors/kubernetes/map.ts
|
|
25770
25919
|
function serviceNameFor(deployment, config) {
|
|
25771
25920
|
const name = deployment.metadata?.name ?? "";
|
|
@@ -25783,6 +25932,9 @@ function podsForDeployment(deployment, pods) {
|
|
|
25783
25932
|
function nowIso2() {
|
|
25784
25933
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
25785
25934
|
}
|
|
25935
|
+
function podLogKey(podName, container) {
|
|
25936
|
+
return container ? `${podName}\0${container}` : podName;
|
|
25937
|
+
}
|
|
25786
25938
|
function podLevelFault(deployment, pods) {
|
|
25787
25939
|
const name = deployment.metadata?.name ?? "";
|
|
25788
25940
|
const owned = podsForDeployment(deployment, pods);
|
|
@@ -25800,7 +25952,9 @@ function podLevelFault(deployment, pods) {
|
|
|
25800
25952
|
fault: "image-pull",
|
|
25801
25953
|
message: `Deployment ${name} cannot pull image ${image} (${reason})`,
|
|
25802
25954
|
timestamp: pod.status?.startTime ?? nowIso2(),
|
|
25803
|
-
attributes: attrs
|
|
25955
|
+
attributes: attrs,
|
|
25956
|
+
pod,
|
|
25957
|
+
...typeof cs.name === "string" && cs.name.length > 0 ? { container: cs.name } : {}
|
|
25804
25958
|
};
|
|
25805
25959
|
}
|
|
25806
25960
|
if (reason === CRASH_LOOP_REASON && !crash) crash = { cs, pod };
|
|
@@ -25822,11 +25976,47 @@ function podLevelFault(deployment, pods) {
|
|
|
25822
25976
|
fault: "crash-loop",
|
|
25823
25977
|
message: `Deployment ${name} is crashlooping (restarts: ${restarts}); ${detail}`,
|
|
25824
25978
|
timestamp: term?.finishedAt ?? pod.status?.startTime ?? nowIso2(),
|
|
25825
|
-
attributes: attrs
|
|
25979
|
+
attributes: attrs,
|
|
25980
|
+
pod,
|
|
25981
|
+
...typeof cs.name === "string" && cs.name.length > 0 ? { container: cs.name } : {}
|
|
25826
25982
|
};
|
|
25827
25983
|
}
|
|
25828
25984
|
return null;
|
|
25829
25985
|
}
|
|
25986
|
+
function faultedContainer(finding) {
|
|
25987
|
+
const containers = finding.pod?.spec?.containers;
|
|
25988
|
+
if (!Array.isArray(containers) || containers.length === 0) return void 0;
|
|
25989
|
+
if (finding.container) {
|
|
25990
|
+
const named2 = containers.find((c) => c.name === finding.container);
|
|
25991
|
+
if (named2) return named2;
|
|
25992
|
+
}
|
|
25993
|
+
return containers.length === 1 ? containers[0] : void 0;
|
|
25994
|
+
}
|
|
25995
|
+
function mergeProcessContext(finding, logs) {
|
|
25996
|
+
const container = faultedContainer(finding);
|
|
25997
|
+
const podName = finding.pod?.metadata?.name;
|
|
25998
|
+
const log = logs && podName ? logs.get(podLogKey(podName, finding.container)) : void 0;
|
|
25999
|
+
if (!container && log === void 0) return;
|
|
26000
|
+
const ctx = buildProcessContext({
|
|
26001
|
+
...log !== void 0 ? { log } : {},
|
|
26002
|
+
...container ? { container } : {}
|
|
26003
|
+
});
|
|
26004
|
+
if (ctx.processLog !== void 0) finding.attributes["k8s.processLog"] = ctx.processLog;
|
|
26005
|
+
if (ctx.containerArgs !== void 0) finding.attributes["k8s.containerArgs"] = ctx.containerArgs;
|
|
26006
|
+
if (ctx.containerEnv !== void 0) finding.attributes["k8s.containerEnv"] = ctx.containerEnv;
|
|
26007
|
+
}
|
|
26008
|
+
function faultedPods(deployments, pods, config) {
|
|
26009
|
+
const out = [];
|
|
26010
|
+
const expectedZero = config.expectedZero ? new Set(config.expectedZero) : void 0;
|
|
26011
|
+
for (const deployment of deployments) {
|
|
26012
|
+
const finding = classifyDeployment(deployment, pods, expectedZero);
|
|
26013
|
+
if (!finding || finding.fault !== "crash-loop") continue;
|
|
26014
|
+
const podName = finding.pod?.metadata?.name;
|
|
26015
|
+
if (typeof podName !== "string" || podName.length === 0) continue;
|
|
26016
|
+
out.push({ podName, ...finding.container ? { container: finding.container } : {} });
|
|
26017
|
+
}
|
|
26018
|
+
return out;
|
|
26019
|
+
}
|
|
25830
26020
|
function classifyDeployment(deployment, pods, expectedZero) {
|
|
25831
26021
|
const name = deployment.metadata?.name ?? "";
|
|
25832
26022
|
const desired = typeof deployment.spec?.replicas === "number" ? deployment.spec.replicas : 1;
|
|
@@ -25854,12 +26044,13 @@ function classifyDeployment(deployment, pods, expectedZero) {
|
|
|
25854
26044
|
attributes: { "k8s.desiredReplicas": desired, "k8s.readyReplicas": ready }
|
|
25855
26045
|
};
|
|
25856
26046
|
}
|
|
25857
|
-
function mapDeploymentToSignal(deployment, pods, config) {
|
|
26047
|
+
function mapDeploymentToSignal(deployment, pods, config, logs) {
|
|
25858
26048
|
const name = deployment.metadata?.name;
|
|
25859
26049
|
if (typeof name !== "string" || name.length === 0) return null;
|
|
25860
26050
|
const expectedZero = config.expectedZero ? new Set(config.expectedZero) : void 0;
|
|
25861
26051
|
const finding = classifyDeployment(deployment, pods, expectedZero);
|
|
25862
26052
|
if (!finding) return null;
|
|
26053
|
+
mergeProcessContext(finding, logs);
|
|
25863
26054
|
const serviceName = serviceNameFor(deployment, config);
|
|
25864
26055
|
const namespace = deployment.metadata?.namespace ?? config.namespace;
|
|
25865
26056
|
const attributes = {
|
|
@@ -25912,12 +26103,12 @@ function deployStateSignal(deployment, pods, config) {
|
|
|
25912
26103
|
deployState: observedDeployState(deployment, pods)
|
|
25913
26104
|
};
|
|
25914
26105
|
}
|
|
25915
|
-
function mapWorkloadsToSignals(deployments, pods, config) {
|
|
26106
|
+
function mapWorkloadsToSignals(deployments, pods, config, logs) {
|
|
25916
26107
|
const out = [];
|
|
25917
26108
|
for (const deployment of deployments) {
|
|
25918
26109
|
const deployState = deployStateSignal(deployment, pods, config);
|
|
25919
26110
|
if (deployState) out.push(deployState);
|
|
25920
|
-
const incident = mapDeploymentToSignal(deployment, pods, config);
|
|
26111
|
+
const incident = mapDeploymentToSignal(deployment, pods, config, logs);
|
|
25921
26112
|
if (incident) out.push(incident);
|
|
25922
26113
|
}
|
|
25923
26114
|
return out;
|
|
@@ -26016,6 +26207,8 @@ async function startK8sSubstratePolling(input) {
|
|
|
26016
26207
|
}
|
|
26017
26208
|
|
|
26018
26209
|
// src/connectors/kubernetes/index.ts
|
|
26210
|
+
var PROCESS_LOG_TAIL_LINES = 200;
|
|
26211
|
+
var PROCESS_LOG_LIMIT_BYTES = 64 * 1024;
|
|
26019
26212
|
var KubernetesConnector = class {
|
|
26020
26213
|
constructor(config, fetchImpl) {
|
|
26021
26214
|
this.config = config;
|
|
@@ -26036,7 +26229,25 @@ var KubernetesConnector = class {
|
|
|
26036
26229
|
fetchDeployments(transport, namespace, opts),
|
|
26037
26230
|
fetchPods(transport, namespace, opts)
|
|
26038
26231
|
]);
|
|
26039
|
-
|
|
26232
|
+
const logs = await this.fetchFaultedPodLogs(transport, namespace, deployments, pods, opts);
|
|
26233
|
+
return mapWorkloadsToSignals(deployments, pods, this.config, logs);
|
|
26234
|
+
}
|
|
26235
|
+
async fetchFaultedPodLogs(transport, namespace, deployments, pods, opts) {
|
|
26236
|
+
const logs = /* @__PURE__ */ new Map();
|
|
26237
|
+
const targets = faultedPods(deployments, pods, this.config);
|
|
26238
|
+
await Promise.all(
|
|
26239
|
+
targets.map(async (t) => {
|
|
26240
|
+
const text = await fetchPodLog(transport, namespace, t.podName, {
|
|
26241
|
+
...t.container ? { container: t.container } : {},
|
|
26242
|
+
tailLines: PROCESS_LOG_TAIL_LINES,
|
|
26243
|
+
limitBytes: PROCESS_LOG_LIMIT_BYTES,
|
|
26244
|
+
previous: true,
|
|
26245
|
+
...opts
|
|
26246
|
+
});
|
|
26247
|
+
if (typeof text === "string" && text.length > 0) logs.set(podLogKey(t.podName, t.container), text);
|
|
26248
|
+
})
|
|
26249
|
+
);
|
|
26250
|
+
return logs;
|
|
26040
26251
|
}
|
|
26041
26252
|
};
|
|
26042
26253
|
function createKubernetesConnector(graph, config, fetchImpl) {
|
|
@@ -27117,7 +27328,7 @@ var import_semver2 = __toESM(require("semver"), 1);
|
|
|
27117
27328
|
// src/installers/templates.ts
|
|
27118
27329
|
init_cjs_shims();
|
|
27119
27330
|
var OTEL_INIT_HEADER = "// Generated by `neat init --apply` (ADR-069). OpenTelemetry auto-instrumentation hook.";
|
|
27120
|
-
var OTEL_INIT_STAMP = "// neat-template-version:
|
|
27331
|
+
var OTEL_INIT_STAMP = "// neat-template-version: 9 \u2014 CommonJS TypeScript uses a synchronous bootstrap (#910); OTel init degrades to no-OBSERVED when dependencies are absent (#820); daemon.json endpoint resolution (ADR-096) + layered file-first capture (ADR-090); spans flushed on exit (#1353).";
|
|
27121
27332
|
var OTEL_OTLP_HEADERS_JS = "if (process.env.NEAT_OTEL_TOKEN) process.env.OTEL_EXPORTER_OTLP_HEADERS ||= 'Authorization=Bearer%20' + encodeURIComponent(process.env.NEAT_OTEL_TOKEN)";
|
|
27122
27333
|
var OTEL_OTLP_PROTOCOL_JS = "process.env.OTEL_EXPORTER_OTLP_PROTOCOL ||= 'http/json'";
|
|
27123
27334
|
var OTEL_ENDPOINT_RESOLVER_CJS = `;(function () {
|
|
@@ -27421,6 +27632,31 @@ function __neatInstallFacades() {
|
|
|
27421
27632
|
}
|
|
27422
27633
|
var CALLSITE_PROCESSOR_JS = neatCaptureSource(false);
|
|
27423
27634
|
var CALLSITE_PROCESSOR_TS = neatCaptureSource(true);
|
|
27635
|
+
function neatFlushOnExitSource(ts) {
|
|
27636
|
+
const anyT = ts ? ": any" : "";
|
|
27637
|
+
return `;(function () {
|
|
27638
|
+
let __neatFlushing${anyT}
|
|
27639
|
+
const __neatFlush = () => {
|
|
27640
|
+
if (!__neatFlushing) {
|
|
27641
|
+
__neatFlushing = new Promise((resolve) => {
|
|
27642
|
+
const t${anyT} = setTimeout(() => resolve(true), 2000)
|
|
27643
|
+
if (t && typeof t.unref === 'function') t.unref()
|
|
27644
|
+
Promise.resolve().then(() => sdk.shutdown()).catch(() => {}).then(() => { clearTimeout(t); resolve(false) })
|
|
27645
|
+
})
|
|
27646
|
+
}
|
|
27647
|
+
return __neatFlushing
|
|
27648
|
+
}
|
|
27649
|
+
// Only a flush that timed out forces the exit; otherwise an app's own
|
|
27650
|
+
// beforeExit cleanup still runs.
|
|
27651
|
+
process.once('beforeExit', (code${anyT}) => { __neatFlush().then((timedOut${anyT}) => { if (timedOut) process.exit(process.exitCode ?? code) }) })
|
|
27652
|
+
for (const sig of ['SIGTERM', 'SIGINT']) {
|
|
27653
|
+
process.once(sig${ts ? " as any" : ""}, () => {
|
|
27654
|
+
const alone = process.listenerCount(sig${ts ? " as any" : ""}) === 0
|
|
27655
|
+
__neatFlush().then(() => { if (alone) process.kill(process.pid, sig) })
|
|
27656
|
+
})
|
|
27657
|
+
}
|
|
27658
|
+
})()`;
|
|
27659
|
+
}
|
|
27424
27660
|
function neatWireCaptureSource(ts) {
|
|
27425
27661
|
const providerT = ts ? ": any" : "";
|
|
27426
27662
|
return `try {
|
|
@@ -27473,6 +27709,7 @@ const instrumentations = [getNodeAutoInstrumentations()]
|
|
|
27473
27709
|
__INSTRUMENTATION_BLOCK__
|
|
27474
27710
|
const sdk = new NodeSDK({ instrumentations })
|
|
27475
27711
|
sdk.start()
|
|
27712
|
+
${neatFlushOnExitSource(false)}
|
|
27476
27713
|
${neatWireCaptureSource(false)}
|
|
27477
27714
|
} catch (__neatOtelErr) {
|
|
27478
27715
|
const __neatMsg = String((__neatOtelErr && __neatOtelErr.message) || __neatOtelErr)
|
|
@@ -27511,6 +27748,7 @@ const instrumentations = [getNodeAutoInstrumentations()]
|
|
|
27511
27748
|
__INSTRUMENTATION_BLOCK__
|
|
27512
27749
|
const sdk = new NodeSDK({ instrumentations })
|
|
27513
27750
|
sdk.start()
|
|
27751
|
+
${neatFlushOnExitSource(false)}
|
|
27514
27752
|
${neatWireCaptureSource(false)}
|
|
27515
27753
|
} catch (__neatOtelErr) {
|
|
27516
27754
|
const __neatMsg = String((__neatOtelErr && __neatOtelErr.message) || __neatOtelErr)
|
|
@@ -27547,6 +27785,7 @@ const instrumentations = [getNodeAutoInstrumentations()]
|
|
|
27547
27785
|
__INSTRUMENTATION_BLOCK__
|
|
27548
27786
|
const sdk = new NodeSDK({ instrumentations })
|
|
27549
27787
|
sdk.start()
|
|
27788
|
+
${neatFlushOnExitSource(true)}
|
|
27550
27789
|
${neatWireCaptureSource(true)}
|
|
27551
27790
|
} catch (__neatOtelErr) {
|
|
27552
27791
|
const __neatMsg = String((__neatOtelErr && __neatOtelErr.message) || __neatOtelErr)
|
|
@@ -27684,6 +27923,7 @@ const sdk = new NodeSDK({
|
|
|
27684
27923
|
instrumentations: [getNodeAutoInstrumentations()],
|
|
27685
27924
|
})
|
|
27686
27925
|
sdk.start()
|
|
27926
|
+
${neatFlushOnExitSource(true)}
|
|
27687
27927
|
`;
|
|
27688
27928
|
var FRAMEWORK_OTEL_INIT_JS_BODY = `${FRAMEWORK_OTEL_INIT_HEADER}
|
|
27689
27929
|
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
@@ -27699,6 +27939,7 @@ const sdk = new NodeSDK({
|
|
|
27699
27939
|
instrumentations: [getNodeAutoInstrumentations()],
|
|
27700
27940
|
})
|
|
27701
27941
|
sdk.start()
|
|
27942
|
+
${neatFlushOnExitSource(false)}
|
|
27702
27943
|
`;
|
|
27703
27944
|
function renderFrameworkOtelInit(template, serviceName, projectName) {
|
|
27704
27945
|
return template.replace(/__SERVICE_NAME__/g, serviceName).replace(/__PROJECT__/g, projectName);
|