@neat.is/core 0.9.3 → 0.9.4
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-EDE4XP2M.js → chunk-IVVF37OU.js} +130 -27
- package/dist/chunk-IVVF37OU.js.map +1 -0
- package/dist/{chunk-2D4Y5QHE.js → chunk-TGCWMMF6.js} +2 -2
- package/dist/cli.cjs +135 -31
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/index.cjs +130 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +130 -26
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +127 -24
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-EDE4XP2M.js.map +0 -1
- /package/dist/{chunk-2D4Y5QHE.js.map → chunk-TGCWMMF6.js.map} +0 -0
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
startStalenessLoop,
|
|
21
21
|
touchLastSeen,
|
|
22
22
|
writeAtomically
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-IVVF37OU.js";
|
|
24
24
|
import {
|
|
25
25
|
assertBindAuthority,
|
|
26
26
|
buildOtelReceiver,
|
|
@@ -891,4 +891,4 @@ export {
|
|
|
891
891
|
resolveHost,
|
|
892
892
|
startDaemon
|
|
893
893
|
};
|
|
894
|
-
//# sourceMappingURL=chunk-
|
|
894
|
+
//# sourceMappingURL=chunk-TGCWMMF6.js.map
|
package/dist/cli.cjs
CHANGED
|
@@ -5476,6 +5476,64 @@ function latencyPercentiles(hist) {
|
|
|
5476
5476
|
return { p50: round(quantile(hist, 0.5)), p95: round(quantile(hist, 0.95)) };
|
|
5477
5477
|
}
|
|
5478
5478
|
|
|
5479
|
+
// src/stacktrace.ts
|
|
5480
|
+
init_cjs_shims();
|
|
5481
|
+
var FRAME_SHAPES = [
|
|
5482
|
+
// `File "<path>", line <N>, in <func>` — the "most recent call last" shape.
|
|
5483
|
+
{ re: /File "([^"]+)", line (\d+)(?:, in (\S+))?/, file: 1, line: 2, fn: 3, deepest: "last" },
|
|
5484
|
+
// `at <func> (<path>:<line>:<col>)` — named call frame, most recent first.
|
|
5485
|
+
{ re: /\bat\s+(.+?)\s+\((.+?):(\d+):\d+\)/, file: 2, line: 3, fn: 1, deepest: "first" },
|
|
5486
|
+
// `at <path>:<line>:<col>` — anonymous call frame, most recent first.
|
|
5487
|
+
{ re: /\bat\s+(.+?):(\d+):\d+/, file: 1, line: 2, deepest: "first" },
|
|
5488
|
+
// `at <qualified.method>(<File.ext>:<line>)` — JVM-style, most recent first.
|
|
5489
|
+
{ re: /\bat\s+(.+?)\((\S+\.\w+):(\d+)\)/, file: 2, line: 3, fn: 1, deepest: "first" }
|
|
5490
|
+
];
|
|
5491
|
+
var VENDOR_MARKERS = [
|
|
5492
|
+
"node_modules",
|
|
5493
|
+
// dependency root
|
|
5494
|
+
"site-packages",
|
|
5495
|
+
// installed-package root
|
|
5496
|
+
"dist-packages",
|
|
5497
|
+
// distro-packaged root
|
|
5498
|
+
"node:"
|
|
5499
|
+
// runtime-internal module scheme (a stdlib/runtime-root frame)
|
|
5500
|
+
];
|
|
5501
|
+
function matchFrame(line) {
|
|
5502
|
+
for (const shape of FRAME_SHAPES) {
|
|
5503
|
+
const m = shape.re.exec(line);
|
|
5504
|
+
if (!m) continue;
|
|
5505
|
+
const file = m[shape.file];
|
|
5506
|
+
const lineNo = Number(m[shape.line]);
|
|
5507
|
+
if (!file || !Number.isFinite(lineNo)) continue;
|
|
5508
|
+
const fn = shape.fn !== void 0 ? m[shape.fn] : void 0;
|
|
5509
|
+
return { frame: { file, line: lineNo, ...fn ? { fn } : {} }, deepest: shape.deepest };
|
|
5510
|
+
}
|
|
5511
|
+
return null;
|
|
5512
|
+
}
|
|
5513
|
+
function isApplicationFrame(file) {
|
|
5514
|
+
if (file.startsWith("<")) return false;
|
|
5515
|
+
const norm = file.split("\\").join("/");
|
|
5516
|
+
for (const marker of VENDOR_MARKERS) {
|
|
5517
|
+
if (norm.includes(marker)) return false;
|
|
5518
|
+
}
|
|
5519
|
+
return true;
|
|
5520
|
+
}
|
|
5521
|
+
function deepestApplicationFrame(stacktrace) {
|
|
5522
|
+
if (!stacktrace) return null;
|
|
5523
|
+
const appFrames = [];
|
|
5524
|
+
for (const raw of stacktrace.split("\n")) {
|
|
5525
|
+
const matched = matchFrame(raw);
|
|
5526
|
+
if (!matched) continue;
|
|
5527
|
+
if (!isApplicationFrame(matched.frame.file)) continue;
|
|
5528
|
+
appFrames.push(matched);
|
|
5529
|
+
}
|
|
5530
|
+
if (appFrames.length === 0) return null;
|
|
5531
|
+
const orientation = appFrames.some((f) => f.deepest === "last") ? "last" : "first";
|
|
5532
|
+
const oriented = appFrames.filter((f) => f.deepest === orientation);
|
|
5533
|
+
const chosen = orientation === "last" ? oriented[oriented.length - 1] : oriented[0];
|
|
5534
|
+
return chosen ? chosen.frame : null;
|
|
5535
|
+
}
|
|
5536
|
+
|
|
5479
5537
|
// src/ingest.ts
|
|
5480
5538
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
5481
5539
|
var DAY_MS = 24 * HOUR_MS;
|
|
@@ -6327,29 +6385,71 @@ async function appendConnectorIncident(errorsPath, input) {
|
|
|
6327
6385
|
await import_node_fs8.promises.mkdir(import_node_path9.default.dirname(errorsPath), { recursive: true });
|
|
6328
6386
|
await import_node_fs8.promises.appendFile(errorsPath, JSON.stringify(ev) + "\n", "utf8");
|
|
6329
6387
|
}
|
|
6330
|
-
function
|
|
6388
|
+
function landIncidentCallSite(span, callSite, trusted, graph) {
|
|
6389
|
+
const relPath = graph ? reconcileObservedRelPath(graph, span.service, callSite.relPath) : callSite.relPath;
|
|
6390
|
+
const canonicalService = serviceNodeName(graph, span) ?? span.service;
|
|
6391
|
+
const recovered = !trusted;
|
|
6392
|
+
if (graph) {
|
|
6393
|
+
const fusedFileId = (0, import_types8.fileId)(canonicalService, relPath);
|
|
6394
|
+
if (graph.hasNode(fusedFileId)) {
|
|
6395
|
+
const node = landObservedSymbol(
|
|
6396
|
+
graph,
|
|
6397
|
+
fusedFileId,
|
|
6398
|
+
canonicalService,
|
|
6399
|
+
relPath,
|
|
6400
|
+
{ ...callSite, relPath },
|
|
6401
|
+
false
|
|
6402
|
+
);
|
|
6403
|
+
return {
|
|
6404
|
+
affectedNode: node,
|
|
6405
|
+
...recovered ? {
|
|
6406
|
+
codeFilepath: relPath,
|
|
6407
|
+
...callSite.line !== void 0 ? { codeLineno: callSite.line } : {}
|
|
6408
|
+
} : {}
|
|
6409
|
+
};
|
|
6410
|
+
}
|
|
6411
|
+
if (recovered) return null;
|
|
6412
|
+
}
|
|
6413
|
+
return { affectedNode: (0, import_types8.fileId)(span.service, relPath) };
|
|
6414
|
+
}
|
|
6415
|
+
function serviceNodeName(graph, span) {
|
|
6416
|
+
if (!graph) return void 0;
|
|
6417
|
+
const sid = resolveFusedServiceId(graph, span.service, span.env);
|
|
6418
|
+
if (!graph.hasNode(sid)) return void 0;
|
|
6419
|
+
const node = graph.getNodeAttributes(sid);
|
|
6420
|
+
return typeof node.name === "string" ? node.name : void 0;
|
|
6421
|
+
}
|
|
6422
|
+
function stacktraceCallSite(span, serviceNode, scanPath) {
|
|
6423
|
+
const frame = deepestApplicationFrame(span.exception?.stacktrace);
|
|
6424
|
+
if (!frame) return null;
|
|
6425
|
+
const relPath = relPathForRuntimeFile(frame.file, serviceNode, scanPath);
|
|
6426
|
+
if (!relPath) return null;
|
|
6427
|
+
return { relPath, line: frame.line, ...frame.fn ? { fn: frame.fn } : {} };
|
|
6428
|
+
}
|
|
6429
|
+
function incidentLocus(span, graph, scanPath) {
|
|
6331
6430
|
const sid = graph ? resolveFusedServiceId(graph, span.service, span.env) : (0, import_types8.serviceId)(span.service, span.env);
|
|
6332
6431
|
const serviceNode = graph && graph.hasNode(sid) ? graph.getNodeAttributes(sid) : void 0;
|
|
6333
6432
|
const callSite = callSiteFromSpan(span, serviceNode, scanPath);
|
|
6334
6433
|
if (callSite) {
|
|
6335
|
-
const
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
fusedFileId,
|
|
6343
|
-
canonicalService,
|
|
6344
|
-
relPath,
|
|
6345
|
-
{ ...callSite, relPath },
|
|
6346
|
-
false
|
|
6347
|
-
);
|
|
6348
|
-
}
|
|
6434
|
+
const landed = landIncidentCallSite(span, callSite, true, graph);
|
|
6435
|
+
if (landed) return landed;
|
|
6436
|
+
} else {
|
|
6437
|
+
const recovered = stacktraceCallSite(span, serviceNode, scanPath);
|
|
6438
|
+
if (recovered) {
|
|
6439
|
+
const landed = landIncidentCallSite(span, recovered, false, graph);
|
|
6440
|
+
if (landed) return landed;
|
|
6349
6441
|
}
|
|
6350
|
-
return (0, import_types8.fileId)(span.service, relPath);
|
|
6351
6442
|
}
|
|
6352
|
-
return sid;
|
|
6443
|
+
return { affectedNode: sid };
|
|
6444
|
+
}
|
|
6445
|
+
function incidentAffectedNode(span, graph, scanPath) {
|
|
6446
|
+
return incidentLocus(span, graph, scanPath).affectedNode;
|
|
6447
|
+
}
|
|
6448
|
+
function withRecoveredCodeAttrs(attrs, locus) {
|
|
6449
|
+
if (locus.codeFilepath === void 0) return attrs;
|
|
6450
|
+
attrs[CODE_FILEPATH_ATTR] = locus.codeFilepath;
|
|
6451
|
+
if (locus.codeLineno !== void 0) attrs[CODE_LINENO_ATTR] = locus.codeLineno;
|
|
6452
|
+
return attrs;
|
|
6353
6453
|
}
|
|
6354
6454
|
function sanitizeAttributes(attrs) {
|
|
6355
6455
|
const out = {};
|
|
@@ -6362,7 +6462,8 @@ function sanitizeAttributes(attrs) {
|
|
|
6362
6462
|
function buildErrorEventForReceiver(span, graph, scanPath) {
|
|
6363
6463
|
if (span.statusCode !== 2) return null;
|
|
6364
6464
|
const ts = span.startTimeIso ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
6365
|
-
const
|
|
6465
|
+
const locus = incidentLocus(span, graph, scanPath);
|
|
6466
|
+
const attrs = withRecoveredCodeAttrs(sanitizeAttributes(span.attributes), locus);
|
|
6366
6467
|
return {
|
|
6367
6468
|
id: `${span.traceId}:${span.spanId}`,
|
|
6368
6469
|
timestamp: ts,
|
|
@@ -6373,7 +6474,7 @@ function buildErrorEventForReceiver(span, graph, scanPath) {
|
|
|
6373
6474
|
...span.exception?.type ? { exceptionType: span.exception.type } : {},
|
|
6374
6475
|
...span.exception?.stacktrace ? { exceptionStacktrace: span.exception.stacktrace } : {},
|
|
6375
6476
|
...Object.keys(attrs).length > 0 ? { attributes: attrs } : {},
|
|
6376
|
-
affectedNode:
|
|
6477
|
+
affectedNode: locus.affectedNode
|
|
6377
6478
|
};
|
|
6378
6479
|
}
|
|
6379
6480
|
function makeErrorSpanWriter(errorsPath, graph, scanPath) {
|
|
@@ -6407,7 +6508,8 @@ async function recordFailingResponseIncident(ctx, span, affectedNode, timestamp,
|
|
|
6407
6508
|
await appendErrorEvent(ctx, ev);
|
|
6408
6509
|
}
|
|
6409
6510
|
async function recordExceptionIncident(ctx, span, ts) {
|
|
6410
|
-
const
|
|
6511
|
+
const locus = incidentLocus(span, ctx.graph, ctx.scanPath);
|
|
6512
|
+
const attrs = withRecoveredCodeAttrs(sanitizeAttributes(span.attributes), locus);
|
|
6411
6513
|
const ev = {
|
|
6412
6514
|
id: `${span.traceId}:${span.spanId}`,
|
|
6413
6515
|
timestamp: ts,
|
|
@@ -6418,7 +6520,7 @@ async function recordExceptionIncident(ctx, span, ts) {
|
|
|
6418
6520
|
...span.exception?.type ? { exceptionType: span.exception.type } : {},
|
|
6419
6521
|
...span.exception?.stacktrace ? { exceptionStacktrace: span.exception.stacktrace } : {},
|
|
6420
6522
|
...Object.keys(attrs).length > 0 ? { attributes: attrs } : {},
|
|
6421
|
-
affectedNode:
|
|
6523
|
+
affectedNode: locus.affectedNode
|
|
6422
6524
|
};
|
|
6423
6525
|
await appendErrorEvent(ctx, ev);
|
|
6424
6526
|
}
|
|
@@ -6721,7 +6823,8 @@ async function handleSpan(ctx, span) {
|
|
|
6721
6823
|
if (span.statusCode === 2) {
|
|
6722
6824
|
stitchTrace(ctx.graph, sourceId, ts);
|
|
6723
6825
|
if (ctx.writeErrorEventInline !== false) {
|
|
6724
|
-
const
|
|
6826
|
+
const locus = incidentLocus(span, ctx.graph, ctx.scanPath);
|
|
6827
|
+
const attrs = withRecoveredCodeAttrs(sanitizeAttributes(span.attributes), locus);
|
|
6725
6828
|
const ev = {
|
|
6726
6829
|
id: `${span.traceId}:${span.spanId}`,
|
|
6727
6830
|
timestamp: ts,
|
|
@@ -6733,10 +6836,11 @@ async function handleSpan(ctx, span) {
|
|
|
6733
6836
|
...span.exception?.stacktrace ? { exceptionStacktrace: span.exception.stacktrace } : {},
|
|
6734
6837
|
...Object.keys(attrs).length > 0 ? { attributes: attrs } : {},
|
|
6735
6838
|
// Attribute to where the failure originated — the symbol / file / service
|
|
6736
|
-
// the throwing span named (incidentAffectedNode
|
|
6737
|
-
//
|
|
6738
|
-
//
|
|
6739
|
-
|
|
6839
|
+
// the throwing span named (incidentAffectedNode / ADR-191, extended to
|
|
6840
|
+
// recover the locus from the stacktrace when the span stamped no code.*
|
|
6841
|
+
// attrs, ADR-216) — the same source-based attribution the durable
|
|
6842
|
+
// receiver write uses, not the outbound edge target this span minted.
|
|
6843
|
+
affectedNode: locus.affectedNode
|
|
6740
6844
|
};
|
|
6741
6845
|
await appendErrorEvent(ctx, ev);
|
|
6742
6846
|
}
|
|
@@ -24312,7 +24416,7 @@ var OTEL_ENV = {
|
|
|
24312
24416
|
key: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
|
|
24313
24417
|
value: "http://localhost:4318/projects/<project>/v1/traces"
|
|
24314
24418
|
};
|
|
24315
|
-
function
|
|
24419
|
+
function serviceNodeName2(pkg, serviceDir) {
|
|
24316
24420
|
return pkg.name ?? import_node_path81.default.basename(serviceDir);
|
|
24317
24421
|
}
|
|
24318
24422
|
function projectToken(pkg, serviceDir, project) {
|
|
@@ -24696,7 +24800,7 @@ async function planNext(serviceDir, pkg, manifestPath, nextConfigPath, project)
|
|
|
24696
24800
|
}
|
|
24697
24801
|
dependencyEdits.push({ file: manifestPath, kind: "add", name: inst.pkg, version: inst.version });
|
|
24698
24802
|
}
|
|
24699
|
-
const svcName =
|
|
24803
|
+
const svcName = serviceNodeName2(pkg, serviceDir);
|
|
24700
24804
|
const projectName = projectToken(pkg, serviceDir, project);
|
|
24701
24805
|
const registrations = nonBundled.map((i) => i.registration);
|
|
24702
24806
|
const generatedFiles = [];
|
|
@@ -24795,7 +24899,7 @@ async function queueEnvNeat(serviceDir, pkg, project, generatedFiles) {
|
|
|
24795
24899
|
generatedFiles.push({
|
|
24796
24900
|
file: envNeatFile,
|
|
24797
24901
|
contents: renderEnvNeat(
|
|
24798
|
-
|
|
24902
|
+
serviceNodeName2(pkg, serviceDir),
|
|
24799
24903
|
projectToken(pkg, serviceDir, project)
|
|
24800
24904
|
),
|
|
24801
24905
|
skipIfExists: true
|
|
@@ -24805,7 +24909,7 @@ async function queueEnvNeat(serviceDir, pkg, project, generatedFiles) {
|
|
|
24805
24909
|
function renderFrameworkOtelInitForPkg(template, pkg, serviceDir, project) {
|
|
24806
24910
|
return renderFrameworkOtelInit(
|
|
24807
24911
|
template,
|
|
24808
|
-
|
|
24912
|
+
serviceNodeName2(pkg, serviceDir),
|
|
24809
24913
|
projectToken(pkg, serviceDir, project)
|
|
24810
24914
|
);
|
|
24811
24915
|
}
|
|
@@ -25185,7 +25289,7 @@ async function plan(serviceDir, opts) {
|
|
|
25185
25289
|
} catch {
|
|
25186
25290
|
return { ...empty, libOnly: true };
|
|
25187
25291
|
}
|
|
25188
|
-
const svcName =
|
|
25292
|
+
const svcName = serviceNodeName2(pkg, serviceDir);
|
|
25189
25293
|
const projectName = projectToken(pkg, serviceDir, project);
|
|
25190
25294
|
const registrations = nonBundled.map((i) => i.registration);
|
|
25191
25295
|
const generatedFiles = [];
|