@neat.is/core 0.4.6 → 0.4.7
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-RBWL4HRB.js → chunk-7FTK47JQ.js} +277 -103
- package/dist/chunk-7FTK47JQ.js.map +1 -0
- package/dist/{chunk-NON5AXOR.js → chunk-LS6NS72S.js} +2 -2
- package/dist/cli.cjs +402 -145
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +107 -16
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +280 -115
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/neatd.cjs +280 -115
- package/dist/neatd.cjs.map +1 -1
- package/dist/neatd.js +2 -2
- package/dist/server.cjs +263 -98
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-RBWL4HRB.js.map +0 -1
- /package/dist/{chunk-NON5AXOR.js.map → chunk-LS6NS72S.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
setStatus,
|
|
42
42
|
startPersistLoop,
|
|
43
43
|
startStalenessLoop
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-7FTK47JQ.js";
|
|
45
45
|
import {
|
|
46
46
|
startOtelGrpcReceiver
|
|
47
47
|
} from "./chunk-3QCRUEQD.js";
|
|
@@ -693,38 +693,119 @@ import path4 from "path";
|
|
|
693
693
|
|
|
694
694
|
// src/installers/templates.ts
|
|
695
695
|
var OTEL_INIT_HEADER = "// Generated by `neat init --apply` (ADR-069). OpenTelemetry auto-instrumentation hook.";
|
|
696
|
+
var OTEL_INIT_STAMP = "// neat-template-version: 2 \u2014 file-first call-site capture (ADR-089).";
|
|
697
|
+
function neatCallsiteProcessorSource(ts) {
|
|
698
|
+
const stackT = ts ? ": string" : "";
|
|
699
|
+
const spanT = ts ? ": any" : "";
|
|
700
|
+
const strOpt = ts ? ": string | undefined" : "";
|
|
701
|
+
return `function __neatPickUserFrame(stack${stackT}) {
|
|
702
|
+
const lines = String(stack || '').split('\\n')
|
|
703
|
+
for (let i = 0; i < lines.length; i++) {
|
|
704
|
+
const raw = lines[i].trim()
|
|
705
|
+
if (raw.indexOf('at ') !== 0) continue
|
|
706
|
+
if (raw.indexOf('node_modules') !== -1) continue
|
|
707
|
+
if (raw.indexOf('@opentelemetry') !== -1) continue
|
|
708
|
+
if (raw.indexOf('node:') !== -1) continue
|
|
709
|
+
if (raw.indexOf('NeatCallSiteSpanProcessor') !== -1) continue
|
|
710
|
+
const bodyText = raw.slice(3)
|
|
711
|
+
const loc = bodyText.match(/:(\\d+):(\\d+)\\)?$/)
|
|
712
|
+
if (!loc) continue
|
|
713
|
+
const paren = bodyText.lastIndexOf('(')
|
|
714
|
+
let filepath${strOpt}
|
|
715
|
+
let fn${strOpt}
|
|
716
|
+
if (paren !== -1) {
|
|
717
|
+
fn = bodyText.slice(0, paren).trim()
|
|
718
|
+
if (fn.indexOf('async ') === 0) fn = fn.slice(6)
|
|
719
|
+
if (fn.indexOf('new ') === 0) fn = fn.slice(4)
|
|
720
|
+
filepath = bodyText.slice(paren + 1, bodyText.length - loc[0].length)
|
|
721
|
+
} else {
|
|
722
|
+
filepath = bodyText.slice(0, bodyText.length - loc[0].length)
|
|
723
|
+
}
|
|
724
|
+
if (filepath.indexOf('file://') === 0) filepath = filepath.slice(7)
|
|
725
|
+
if (!filepath) continue
|
|
726
|
+
return { filepath: filepath, lineno: Number(loc[1]), function: fn || undefined }
|
|
727
|
+
}
|
|
728
|
+
return null
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
class NeatCallSiteSpanProcessor {
|
|
732
|
+
onStart(span${spanT}) {
|
|
733
|
+
if (!span || (span.kind !== 2 && span.kind !== 3)) return
|
|
734
|
+
const frame = __neatPickUserFrame(new Error().stack)
|
|
735
|
+
if (!frame) return
|
|
736
|
+
span.setAttribute('code.filepath', frame.filepath)
|
|
737
|
+
if (typeof frame.lineno === 'number') span.setAttribute('code.lineno', frame.lineno)
|
|
738
|
+
if (frame.function) span.setAttribute('code.function', frame.function)
|
|
739
|
+
}
|
|
740
|
+
onEnd() {}
|
|
741
|
+
forceFlush() { return Promise.resolve() }
|
|
742
|
+
shutdown() { return Promise.resolve() }
|
|
743
|
+
}`;
|
|
744
|
+
}
|
|
745
|
+
var CALLSITE_PROCESSOR_JS = neatCallsiteProcessorSource(false);
|
|
746
|
+
var CALLSITE_PROCESSOR_TS = neatCallsiteProcessorSource(true);
|
|
747
|
+
function neatRegisterCallsiteSource(ts) {
|
|
748
|
+
const providerT = ts ? ": any" : "";
|
|
749
|
+
return `try {
|
|
750
|
+
const provider${providerT} = trace.getTracerProvider()
|
|
751
|
+
const delegate = provider && typeof provider.getDelegate === 'function' ? provider.getDelegate() : provider
|
|
752
|
+
if (delegate && typeof delegate.addSpanProcessor === 'function') {
|
|
753
|
+
delegate.addSpanProcessor(new NeatCallSiteSpanProcessor())
|
|
754
|
+
}
|
|
755
|
+
} catch {
|
|
756
|
+
// capture is best-effort; span export is unaffected
|
|
757
|
+
}`;
|
|
758
|
+
}
|
|
696
759
|
var OTEL_INIT_CJS = `${OTEL_INIT_HEADER}
|
|
760
|
+
${OTEL_INIT_STAMP}
|
|
697
761
|
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
698
762
|
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
|
|
699
763
|
|
|
700
764
|
const { NodeSDK } = require('@opentelemetry/sdk-node')
|
|
701
765
|
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')
|
|
766
|
+
const { trace } = require('@opentelemetry/api')
|
|
767
|
+
|
|
768
|
+
${CALLSITE_PROCESSOR_JS}
|
|
702
769
|
|
|
703
770
|
const instrumentations = [getNodeAutoInstrumentations()]
|
|
704
771
|
__INSTRUMENTATION_BLOCK__
|
|
705
|
-
new NodeSDK({ instrumentations })
|
|
772
|
+
const sdk = new NodeSDK({ instrumentations })
|
|
773
|
+
sdk.start()
|
|
774
|
+
${neatRegisterCallsiteSource(false)}
|
|
706
775
|
`;
|
|
707
776
|
var OTEL_INIT_ESM = `${OTEL_INIT_HEADER}
|
|
777
|
+
${OTEL_INIT_STAMP}
|
|
708
778
|
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
709
779
|
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
|
|
710
780
|
|
|
711
781
|
import { NodeSDK } from '@opentelemetry/sdk-node'
|
|
712
782
|
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
|
|
783
|
+
import { trace } from '@opentelemetry/api'
|
|
784
|
+
|
|
785
|
+
${CALLSITE_PROCESSOR_JS}
|
|
713
786
|
|
|
714
787
|
const instrumentations = [getNodeAutoInstrumentations()]
|
|
715
788
|
__INSTRUMENTATION_BLOCK__
|
|
716
|
-
new NodeSDK({ instrumentations })
|
|
789
|
+
const sdk = new NodeSDK({ instrumentations })
|
|
790
|
+
sdk.start()
|
|
791
|
+
${neatRegisterCallsiteSource(false)}
|
|
717
792
|
`;
|
|
718
793
|
var OTEL_INIT_TS = `${OTEL_INIT_HEADER}
|
|
794
|
+
${OTEL_INIT_STAMP}
|
|
719
795
|
process.env.OTEL_SERVICE_NAME ||= '__SERVICE_NAME__'
|
|
720
796
|
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||= 'http://localhost:4318/projects/__PROJECT__/v1/traces'
|
|
721
797
|
|
|
722
798
|
import { NodeSDK } from '@opentelemetry/sdk-node'
|
|
723
799
|
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
|
|
800
|
+
import { trace } from '@opentelemetry/api'
|
|
801
|
+
|
|
802
|
+
${CALLSITE_PROCESSOR_TS}
|
|
724
803
|
|
|
725
804
|
const instrumentations = [getNodeAutoInstrumentations()]
|
|
726
805
|
__INSTRUMENTATION_BLOCK__
|
|
727
|
-
new NodeSDK({ instrumentations })
|
|
806
|
+
const sdk = new NodeSDK({ instrumentations })
|
|
807
|
+
sdk.start()
|
|
808
|
+
${neatRegisterCallsiteSource(true)}
|
|
728
809
|
`;
|
|
729
810
|
function renderNodeOtelInit(template, serviceName, projectName, registrations = []) {
|
|
730
811
|
const block = registrations.length === 0 ? "" : `
|
|
@@ -948,6 +1029,23 @@ async function exists(p) {
|
|
|
948
1029
|
return false;
|
|
949
1030
|
}
|
|
950
1031
|
}
|
|
1032
|
+
async function readFileMaybe(p) {
|
|
1033
|
+
try {
|
|
1034
|
+
return await fs4.readFile(p, "utf8");
|
|
1035
|
+
} catch {
|
|
1036
|
+
return null;
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
async function planOtelInitGeneration(file, contents) {
|
|
1040
|
+
const existing = await readFileMaybe(file);
|
|
1041
|
+
if (existing === null) {
|
|
1042
|
+
return { file, contents, skipIfExists: true };
|
|
1043
|
+
}
|
|
1044
|
+
if (existing.includes(OTEL_INIT_HEADER) && !existing.includes(OTEL_INIT_STAMP)) {
|
|
1045
|
+
return { file, contents, skipIfExists: false };
|
|
1046
|
+
}
|
|
1047
|
+
return null;
|
|
1048
|
+
}
|
|
951
1049
|
async function detect(serviceDir) {
|
|
952
1050
|
const pkg = await readPackageJson(serviceDir);
|
|
953
1051
|
return pkg !== null && typeof pkg.name === "string";
|
|
@@ -1678,18 +1776,11 @@ async function plan(serviceDir, opts) {
|
|
|
1678
1776
|
const projectName = projectToken(pkg, serviceDir, project);
|
|
1679
1777
|
const registrations = nonBundled.map((i) => i.registration);
|
|
1680
1778
|
const generatedFiles = [];
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
svcName,
|
|
1687
|
-
projectName,
|
|
1688
|
-
registrations
|
|
1689
|
-
),
|
|
1690
|
-
skipIfExists: true
|
|
1691
|
-
});
|
|
1692
|
-
}
|
|
1779
|
+
const otelInitGen = await planOtelInitGeneration(
|
|
1780
|
+
otelInitFile,
|
|
1781
|
+
renderNodeOtelInit(otelInitContents(flavor), svcName, projectName, registrations)
|
|
1782
|
+
);
|
|
1783
|
+
if (otelInitGen) generatedFiles.push(otelInitGen);
|
|
1693
1784
|
if (!await exists(envNeatFile)) {
|
|
1694
1785
|
generatedFiles.push({
|
|
1695
1786
|
file: envNeatFile,
|