@probelabs/visor 0.1.182-ee → 0.1.183-ee
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/defaults/assistant.yaml +2 -1
- package/defaults/code-talk.yaml +6 -0
- package/defaults/skills/task-progress.yaml +39 -0
- package/dist/agent-protocol/task-evaluator.d.ts +2 -1
- package/dist/agent-protocol/task-evaluator.d.ts.map +1 -1
- package/dist/agent-protocol/task-progress-tool.d.ts +29 -0
- package/dist/agent-protocol/task-progress-tool.d.ts.map +1 -0
- package/dist/agent-protocol/task-store.d.ts +8 -0
- package/dist/agent-protocol/task-store.d.ts.map +1 -1
- package/dist/agent-protocol/tasks-cli-handler.d.ts.map +1 -1
- package/dist/agent-protocol/trace-serializer.d.ts +5 -2
- package/dist/agent-protocol/trace-serializer.d.ts.map +1 -1
- package/dist/agent-protocol/track-execution.d.ts +1 -1
- package/dist/agent-protocol/track-execution.d.ts.map +1 -1
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/debug-visualizer/trace-reader.d.ts.map +1 -1
- package/dist/defaults/assistant.yaml +2 -1
- package/dist/defaults/code-talk.yaml +6 -0
- package/dist/defaults/skills/task-progress.yaml +39 -0
- package/dist/docs/telemetry-live-spans-plan.md +510 -0
- package/dist/generated/config-schema.json +43 -6
- package/dist/index.js +3545 -701
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/git-checkout-provider.d.ts.map +1 -1
- package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
- package/dist/reviewer.d.ts +2 -0
- package/dist/reviewer.d.ts.map +1 -1
- package/dist/runners/process-cli-handler.d.ts +2 -0
- package/dist/runners/process-cli-handler.d.ts.map +1 -0
- package/dist/runners/process-discovery.d.ts +29 -0
- package/dist/runners/process-discovery.d.ts.map +1 -0
- package/dist/sandbox/check-runner.d.ts.map +1 -1
- package/dist/sandbox/sandbox-telemetry.d.ts +7 -0
- package/dist/sandbox/sandbox-telemetry.d.ts.map +1 -1
- package/dist/sandbox/trace-ingester.d.ts +28 -15
- package/dist/sandbox/trace-ingester.d.ts.map +1 -1
- package/dist/scheduler/schedule-tool.d.ts +5 -0
- package/dist/scheduler/schedule-tool.d.ts.map +1 -1
- package/dist/sdk/{a2a-frontend-MU5EO2HZ.mjs → a2a-frontend-5YDHFQXD.mjs} +47 -8
- package/dist/sdk/{a2a-frontend-MU5EO2HZ.mjs.map → a2a-frontend-5YDHFQXD.mjs.map} +1 -1
- package/dist/sdk/{a2a-frontend-4LP3MLTS.mjs → a2a-frontend-6LWBIPMS.mjs} +19 -3
- package/dist/sdk/a2a-frontend-6LWBIPMS.mjs.map +1 -0
- package/dist/sdk/check-provider-registry-WSEVHJEV.mjs +31 -0
- package/dist/sdk/{check-provider-registry-I4BCWKRU.mjs → check-provider-registry-YRADEEQY.mjs} +6 -6
- package/dist/sdk/chunk-4BN2XI4X.mjs +459 -0
- package/dist/sdk/chunk-4BN2XI4X.mjs.map +1 -0
- package/dist/sdk/chunk-54KOAC4W.mjs +665 -0
- package/dist/sdk/chunk-54KOAC4W.mjs.map +1 -0
- package/dist/sdk/chunk-6C3R6E42.mjs +1700 -0
- package/dist/sdk/chunk-6C3R6E42.mjs.map +1 -0
- package/dist/sdk/{chunk-4I3TJ7UJ.mjs → chunk-7W5QCO4Y.mjs} +47 -10
- package/dist/sdk/chunk-7W5QCO4Y.mjs.map +1 -0
- package/dist/sdk/chunk-B2OUZAWY.mjs +237 -0
- package/dist/sdk/chunk-B2OUZAWY.mjs.map +1 -0
- package/dist/sdk/chunk-FWWLD555.mjs +244 -0
- package/dist/sdk/chunk-FWWLD555.mjs.map +1 -0
- package/dist/sdk/{chunk-QXT47ZHR.mjs → chunk-G7GSN3SK.mjs} +2 -2
- package/dist/sdk/{chunk-QXT47ZHR.mjs.map → chunk-G7GSN3SK.mjs.map} +1 -1
- package/dist/sdk/{chunk-DHETLQIX.mjs → chunk-GA2TYKSR.mjs} +5 -5
- package/dist/sdk/{chunk-6DPPP7LD.mjs → chunk-IDL3AA3G.mjs} +203 -42
- package/dist/sdk/chunk-IDL3AA3G.mjs.map +1 -0
- package/dist/sdk/chunk-MEB2TTIE.mjs +157 -0
- package/dist/sdk/chunk-MEB2TTIE.mjs.map +1 -0
- package/dist/sdk/{chunk-3JFK6KCD.mjs → chunk-MFXPJUUE.mjs} +150 -280
- package/dist/sdk/chunk-MFXPJUUE.mjs.map +1 -0
- package/dist/sdk/{chunk-KBGQJKIZ.mjs → chunk-NPSLGKXB.mjs} +3 -3
- package/dist/sdk/chunk-P2K4VOMU.mjs +825 -0
- package/dist/sdk/chunk-P2K4VOMU.mjs.map +1 -0
- package/dist/sdk/chunk-RI4ONH5X.mjs +482 -0
- package/dist/sdk/chunk-RI4ONH5X.mjs.map +1 -0
- package/dist/sdk/chunk-S5FSRHMY.mjs +139 -0
- package/dist/sdk/chunk-S5FSRHMY.mjs.map +1 -0
- package/dist/sdk/{chunk-7ERVRLDV.mjs → chunk-TFUQ2D5L.mjs} +13 -2
- package/dist/sdk/chunk-TFUQ2D5L.mjs.map +1 -0
- package/dist/sdk/{chunk-TQQNSHQV.mjs → chunk-UXB4XWEE.mjs} +1044 -179
- package/dist/sdk/chunk-UXB4XWEE.mjs.map +1 -0
- package/dist/sdk/{chunk-U6K5SK7X.mjs → chunk-V45TITKX.mjs} +2 -2
- package/dist/sdk/{chunk-ANUT54HW.mjs → chunk-WKLJ57WF.mjs} +6 -6
- package/dist/sdk/chunk-XOAEKFKB.mjs +1150 -0
- package/dist/sdk/chunk-XOAEKFKB.mjs.map +1 -0
- package/dist/sdk/chunk-ZPYODGYA.mjs +251 -0
- package/dist/sdk/chunk-ZPYODGYA.mjs.map +1 -0
- package/dist/sdk/command-executor-YNJOS77A.mjs +14 -0
- package/dist/sdk/{config-2STD74CJ.mjs → config-PCP6O6Y6.mjs} +4 -4
- package/dist/sdk/{failure-condition-evaluator-FFWJRAEQ.mjs → failure-condition-evaluator-H3PBFBYT.mjs} +4 -4
- package/dist/sdk/failure-condition-evaluator-IRFKTYZD.mjs +18 -0
- package/dist/sdk/github-auth-BJQBLK2V.mjs +196 -0
- package/dist/sdk/github-auth-BJQBLK2V.mjs.map +1 -0
- package/dist/sdk/{github-frontend-L3F5JXPJ.mjs → github-frontend-DECYOBRN.mjs} +8 -8
- package/dist/sdk/{github-frontend-KGV2R5Z6.mjs → github-frontend-TZRBOQCN.mjs} +4 -4
- package/dist/sdk/{host-QBJ7TOWG.mjs → host-CFM2ASDI.mjs} +4 -4
- package/dist/sdk/{host-X5ZZCEWN.mjs → host-T4LNVU2H.mjs} +3 -3
- package/dist/sdk/{knex-store-QCEW4I4R.mjs → knex-store-OEWSZEBY.mjs} +3 -3
- package/dist/sdk/lazy-otel-5RDTVS5L.mjs +24 -0
- package/dist/sdk/liquid-extensions-E3AKRX7P.mjs +25 -0
- package/dist/sdk/{loader-ZNKKJEZ3.mjs → loader-WRGI244P.mjs} +5 -5
- package/dist/sdk/memory-store-OHUIXCWJ.mjs +12 -0
- package/dist/sdk/metrics-MYUPQBBV.mjs +41 -0
- package/dist/sdk/{opa-policy-engine-QCSSIMUF.mjs → opa-policy-engine-IVMCGVNA.mjs} +3 -3
- package/dist/sdk/prompt-state-LN57DQF3.mjs +16 -0
- package/dist/sdk/renderer-schema-BT2IXMLW.mjs +51 -0
- package/dist/sdk/renderer-schema-BT2IXMLW.mjs.map +1 -0
- package/dist/sdk/routing-H2PQ57OA.mjs +26 -0
- package/dist/sdk/{routing-CVQT4KHX.mjs → routing-JMZ7HDCC.mjs} +5 -5
- package/dist/sdk/schedule-tool-2DPNSU63.mjs +37 -0
- package/dist/sdk/{schedule-tool-AECLFHSY.mjs → schedule-tool-4M45RK3E.mjs} +6 -6
- package/dist/sdk/{schedule-tool-handler-6QLZRTQA.mjs → schedule-tool-handler-KLHE2SOW.mjs} +6 -6
- package/dist/sdk/schedule-tool-handler-KLHE2SOW.mjs.map +1 -0
- package/dist/sdk/{schedule-tool-handler-J4NUETJ6.mjs → schedule-tool-handler-NBEO46RV.mjs} +16 -16
- package/dist/sdk/schedule-tool-handler-NBEO46RV.mjs.map +1 -0
- package/dist/sdk/sdk.d.mts +2 -0
- package/dist/sdk/sdk.d.ts +2 -0
- package/dist/sdk/sdk.js +3125 -666
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +15 -15
- package/dist/sdk/slack-frontend-DF5VL4OF.mjs +929 -0
- package/dist/sdk/slack-frontend-DF5VL4OF.mjs.map +1 -0
- package/dist/sdk/{task-evaluator-HLNXKKVV.mjs → task-evaluator-GQYDOSGT.mjs} +138 -24
- package/dist/sdk/task-evaluator-GQYDOSGT.mjs.map +1 -0
- package/dist/sdk/task-evaluator-OVMG7S56.mjs +263 -0
- package/dist/sdk/task-evaluator-OVMG7S56.mjs.map +1 -0
- package/dist/sdk/{trace-helpers-WJXYVV4S.mjs → trace-helpers-26ZCAE2V.mjs} +7 -5
- package/dist/sdk/trace-helpers-26ZCAE2V.mjs.map +1 -0
- package/dist/sdk/{trace-helpers-3FFAI7X3.mjs → trace-helpers-XV5GAX5L.mjs} +3 -3
- package/dist/sdk/trace-helpers-XV5GAX5L.mjs.map +1 -0
- package/dist/sdk/{trace-reader-ZY77OFNM.mjs → trace-reader-OVE4DL2D.mjs} +6 -2
- package/dist/sdk/trace-reader-OVE4DL2D.mjs.map +1 -0
- package/dist/sdk/trace-serializer-KKBJHM7J.mjs +24 -0
- package/dist/sdk/trace-serializer-KKBJHM7J.mjs.map +1 -0
- package/dist/sdk/{track-execution-AMQQNXKE.mjs → track-execution-3EC24C2X.mjs} +68 -7
- package/dist/sdk/track-execution-3EC24C2X.mjs.map +1 -0
- package/dist/sdk/{track-execution-MKIQXP2C.mjs → track-execution-66RLL6QT.mjs} +10 -3
- package/dist/sdk/track-execution-66RLL6QT.mjs.map +1 -0
- package/dist/sdk/utcp-check-provider-WI3QZ3W6.mjs +16 -0
- package/dist/sdk/utcp-check-provider-WI3QZ3W6.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-X2UREEH7.mjs +31 -0
- package/dist/sdk/workflow-check-provider-X2UREEH7.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-EXMC6JIS.mjs → workflow-check-provider-YXALZNAQ.mjs} +6 -6
- package/dist/sdk/workflow-check-provider-YXALZNAQ.mjs.map +1 -0
- package/dist/sdk/workflow-registry-YCZ3FCJC.mjs +12 -0
- package/dist/sdk/workflow-registry-YCZ3FCJC.mjs.map +1 -0
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/state-machine/dispatch/sandbox-routing.d.ts.map +1 -1
- package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
- package/dist/telemetry/fallback-ndjson.d.ts +21 -0
- package/dist/telemetry/fallback-ndjson.d.ts.map +1 -1
- package/dist/telemetry/lazy-otel.d.ts +2 -0
- package/dist/telemetry/lazy-otel.d.ts.map +1 -1
- package/dist/telemetry/opentelemetry.d.ts +5 -0
- package/dist/telemetry/opentelemetry.d.ts.map +1 -1
- package/dist/telemetry/trace-helpers.d.ts +10 -0
- package/dist/telemetry/trace-helpers.d.ts.map +1 -1
- package/dist/test-runner/conversation-sugar.d.ts +7 -0
- package/dist/test-runner/conversation-sugar.d.ts.map +1 -1
- package/dist/test-runner/core/flow-stage.d.ts.map +1 -1
- package/dist/test-runner/index.d.ts.map +1 -1
- package/dist/test-runner/validator.d.ts.map +1 -1
- package/dist/types/git-checkout.d.ts +2 -0
- package/dist/types/git-checkout.d.ts.map +1 -1
- package/dist/utils/script-tool-environment.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/sdk/a2a-frontend-4LP3MLTS.mjs.map +0 -1
- package/dist/sdk/check-provider-registry-RRWCXSTG.mjs +0 -31
- package/dist/sdk/chunk-3JFK6KCD.mjs.map +0 -1
- package/dist/sdk/chunk-4I3TJ7UJ.mjs.map +0 -1
- package/dist/sdk/chunk-6DPPP7LD.mjs.map +0 -1
- package/dist/sdk/chunk-6VVXKXTI.mjs +0 -164
- package/dist/sdk/chunk-6VVXKXTI.mjs.map +0 -1
- package/dist/sdk/chunk-7ERVRLDV.mjs.map +0 -1
- package/dist/sdk/chunk-TQQNSHQV.mjs.map +0 -1
- package/dist/sdk/failure-condition-evaluator-5DZYMCGW.mjs +0 -18
- package/dist/sdk/routing-XALEDC2G.mjs +0 -26
- package/dist/sdk/schedule-tool-Z6QYL2B3.mjs +0 -37
- package/dist/sdk/task-evaluator-HLNXKKVV.mjs.map +0 -1
- package/dist/sdk/trace-reader-ZY77OFNM.mjs.map +0 -1
- package/dist/sdk/track-execution-AMQQNXKE.mjs.map +0 -1
- package/dist/sdk/track-execution-MKIQXP2C.mjs.map +0 -1
- package/dist/sdk/workflow-check-provider-VKYGI5GK.mjs +0 -31
- /package/dist/sdk/{check-provider-registry-I4BCWKRU.mjs.map → check-provider-registry-WSEVHJEV.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-RRWCXSTG.mjs.map → check-provider-registry-YRADEEQY.mjs.map} +0 -0
- /package/dist/sdk/{chunk-DHETLQIX.mjs.map → chunk-GA2TYKSR.mjs.map} +0 -0
- /package/dist/sdk/{chunk-ANUT54HW.mjs.map → chunk-NPSLGKXB.mjs.map} +0 -0
- /package/dist/sdk/{chunk-U6K5SK7X.mjs.map → chunk-V45TITKX.mjs.map} +0 -0
- /package/dist/sdk/{chunk-KBGQJKIZ.mjs.map → chunk-WKLJ57WF.mjs.map} +0 -0
- /package/dist/sdk/{config-2STD74CJ.mjs.map → command-executor-YNJOS77A.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-5DZYMCGW.mjs.map → config-PCP6O6Y6.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-FFWJRAEQ.mjs.map → failure-condition-evaluator-H3PBFBYT.mjs.map} +0 -0
- /package/dist/sdk/{routing-CVQT4KHX.mjs.map → failure-condition-evaluator-IRFKTYZD.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-KGV2R5Z6.mjs.map → github-frontend-DECYOBRN.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-L3F5JXPJ.mjs.map → github-frontend-TZRBOQCN.mjs.map} +0 -0
- /package/dist/sdk/{host-QBJ7TOWG.mjs.map → host-CFM2ASDI.mjs.map} +0 -0
- /package/dist/sdk/{host-X5ZZCEWN.mjs.map → host-T4LNVU2H.mjs.map} +0 -0
- /package/dist/sdk/{knex-store-QCEW4I4R.mjs.map → knex-store-OEWSZEBY.mjs.map} +0 -0
- /package/dist/sdk/{routing-XALEDC2G.mjs.map → lazy-otel-5RDTVS5L.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-AECLFHSY.mjs.map → liquid-extensions-E3AKRX7P.mjs.map} +0 -0
- /package/dist/sdk/{loader-ZNKKJEZ3.mjs.map → loader-WRGI244P.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-Z6QYL2B3.mjs.map → memory-store-OHUIXCWJ.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-6QLZRTQA.mjs.map → metrics-MYUPQBBV.mjs.map} +0 -0
- /package/dist/sdk/{opa-policy-engine-QCSSIMUF.mjs.map → opa-policy-engine-IVMCGVNA.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-J4NUETJ6.mjs.map → prompt-state-LN57DQF3.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-3FFAI7X3.mjs.map → routing-H2PQ57OA.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-WJXYVV4S.mjs.map → routing-JMZ7HDCC.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-EXMC6JIS.mjs.map → schedule-tool-2DPNSU63.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-VKYGI5GK.mjs.map → schedule-tool-4M45RK3E.mjs.map} +0 -0
|
@@ -0,0 +1,1150 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getInstanceId,
|
|
3
|
+
init_instance_id,
|
|
4
|
+
require_package
|
|
5
|
+
} from "./chunk-G7GSN3SK.mjs";
|
|
6
|
+
import {
|
|
7
|
+
init_metrics,
|
|
8
|
+
metrics_exports
|
|
9
|
+
} from "./chunk-FWWLD555.mjs";
|
|
10
|
+
import {
|
|
11
|
+
SpanStatusCode,
|
|
12
|
+
context,
|
|
13
|
+
init_lazy_otel,
|
|
14
|
+
trace
|
|
15
|
+
} from "./chunk-B2OUZAWY.mjs";
|
|
16
|
+
import {
|
|
17
|
+
__esm,
|
|
18
|
+
__export,
|
|
19
|
+
__require,
|
|
20
|
+
__toCommonJS
|
|
21
|
+
} from "./chunk-J7LXIPZS.mjs";
|
|
22
|
+
|
|
23
|
+
// src/telemetry/fallback-ndjson.ts
|
|
24
|
+
var fallback_ndjson_exports = {};
|
|
25
|
+
__export(fallback_ndjson_exports, {
|
|
26
|
+
emitNdjsonFallback: () => emitNdjsonFallback,
|
|
27
|
+
emitNdjsonFullSpan: () => emitNdjsonFullSpan,
|
|
28
|
+
emitNdjsonSpanWithEvents: () => emitNdjsonSpanWithEvents,
|
|
29
|
+
flushNdjson: () => flushNdjson
|
|
30
|
+
});
|
|
31
|
+
import * as fs from "fs";
|
|
32
|
+
import * as path from "path";
|
|
33
|
+
function resolveTargetPath(outDir) {
|
|
34
|
+
if (process.env.VISOR_FALLBACK_TRACE_FILE) {
|
|
35
|
+
CURRENT_FILE = process.env.VISOR_FALLBACK_TRACE_FILE;
|
|
36
|
+
return CURRENT_FILE;
|
|
37
|
+
}
|
|
38
|
+
if (CURRENT_FILE) return CURRENT_FILE;
|
|
39
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
40
|
+
CURRENT_FILE = path.join(outDir, `${ts}.ndjson`);
|
|
41
|
+
return CURRENT_FILE;
|
|
42
|
+
}
|
|
43
|
+
function isEnabled() {
|
|
44
|
+
if (process.env.VISOR_FALLBACK_TRACE_FILE) return true;
|
|
45
|
+
return process.env.VISOR_TELEMETRY_ENABLED === "true" && (process.env.VISOR_TELEMETRY_SINK || "file") === "file";
|
|
46
|
+
}
|
|
47
|
+
function appendAsync(outDir, line) {
|
|
48
|
+
writeChain = writeChain.then(async () => {
|
|
49
|
+
if (!dirReady) {
|
|
50
|
+
try {
|
|
51
|
+
await fs.promises.mkdir(outDir, { recursive: true });
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
dirReady = true;
|
|
55
|
+
}
|
|
56
|
+
const target = resolveTargetPath(outDir);
|
|
57
|
+
await fs.promises.appendFile(target, line, "utf8");
|
|
58
|
+
}).catch(() => {
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
async function flushNdjson() {
|
|
62
|
+
try {
|
|
63
|
+
await writeChain;
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function emitNdjsonFallback(name, attrs) {
|
|
68
|
+
try {
|
|
69
|
+
if (!isEnabled()) return;
|
|
70
|
+
const outDir = process.env.VISOR_TRACE_DIR || path.join(process.cwd(), "output", "traces");
|
|
71
|
+
const line = JSON.stringify({ name, attributes: attrs }) + "\n";
|
|
72
|
+
appendAsync(outDir, line);
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function emitNdjsonSpanWithEvents(name, attrs, events) {
|
|
77
|
+
try {
|
|
78
|
+
if (!isEnabled()) return;
|
|
79
|
+
const outDir = process.env.VISOR_TRACE_DIR || path.join(process.cwd(), "output", "traces");
|
|
80
|
+
const line = JSON.stringify({ name, attributes: attrs, events }) + "\n";
|
|
81
|
+
appendAsync(outDir, line);
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function emitNdjsonFullSpan(record) {
|
|
86
|
+
try {
|
|
87
|
+
if (!isEnabled()) return;
|
|
88
|
+
const outDir = process.env.VISOR_TRACE_DIR || path.join(process.cwd(), "output", "traces");
|
|
89
|
+
const line = JSON.stringify(record) + "\n";
|
|
90
|
+
appendAsync(outDir, line);
|
|
91
|
+
} catch {
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
var CURRENT_FILE, dirReady, writeChain;
|
|
95
|
+
var init_fallback_ndjson = __esm({
|
|
96
|
+
"src/telemetry/fallback-ndjson.ts"() {
|
|
97
|
+
"use strict";
|
|
98
|
+
CURRENT_FILE = null;
|
|
99
|
+
dirReady = false;
|
|
100
|
+
writeChain = Promise.resolve();
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// src/telemetry/file-span-exporter.ts
|
|
105
|
+
var file_span_exporter_exports = {};
|
|
106
|
+
__export(file_span_exporter_exports, {
|
|
107
|
+
FileSpanExporter: () => FileSpanExporter
|
|
108
|
+
});
|
|
109
|
+
import * as fs2 from "fs";
|
|
110
|
+
import * as path2 from "path";
|
|
111
|
+
function serializeSpan(s) {
|
|
112
|
+
return {
|
|
113
|
+
traceId: s.spanContext().traceId,
|
|
114
|
+
spanId: s.spanContext().spanId,
|
|
115
|
+
parentSpanId: s.parentSpanContext?.spanId || s.parentSpanId,
|
|
116
|
+
name: s.name,
|
|
117
|
+
startTime: s.startTime,
|
|
118
|
+
endTime: s.endTime,
|
|
119
|
+
status: s.status,
|
|
120
|
+
attributes: s.attributes,
|
|
121
|
+
events: s.events?.map((e) => ({ name: e.name, time: e.time, attributes: e.attributes })),
|
|
122
|
+
resource: s.resource?.attributes,
|
|
123
|
+
kind: s.kind
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
var otelCore, FileSpanExporter;
|
|
127
|
+
var init_file_span_exporter = __esm({
|
|
128
|
+
"src/telemetry/file-span-exporter.ts"() {
|
|
129
|
+
"use strict";
|
|
130
|
+
try {
|
|
131
|
+
otelCore = (function(name) {
|
|
132
|
+
return __require(name);
|
|
133
|
+
})("@opentelemetry/core");
|
|
134
|
+
} catch {
|
|
135
|
+
otelCore = null;
|
|
136
|
+
}
|
|
137
|
+
FileSpanExporter = class {
|
|
138
|
+
filePath;
|
|
139
|
+
buffer = [];
|
|
140
|
+
ndjson;
|
|
141
|
+
constructor(opts = {}) {
|
|
142
|
+
const outDir = opts.dir || path2.join(process.cwd(), "output", "traces");
|
|
143
|
+
this.ndjson = opts.ndjson !== false;
|
|
144
|
+
if (!fs2.existsSync(outDir)) fs2.mkdirSync(outDir, { recursive: true });
|
|
145
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
146
|
+
const run = opts.runId ? `${opts.runId}-` : "";
|
|
147
|
+
const ext = this.ndjson ? "ndjson" : "json";
|
|
148
|
+
if (process.env.VISOR_FALLBACK_TRACE_FILE) {
|
|
149
|
+
this.filePath = process.env.VISOR_FALLBACK_TRACE_FILE;
|
|
150
|
+
const dir = path2.dirname(this.filePath);
|
|
151
|
+
if (!fs2.existsSync(dir)) fs2.mkdirSync(dir, { recursive: true });
|
|
152
|
+
} else {
|
|
153
|
+
this.filePath = path2.join(outDir, `run-${run}${ts}.${ext}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export(spans, resultCallback) {
|
|
157
|
+
const ExportResultCode = otelCore?.ExportResultCode || { SUCCESS: 0, FAILED: 1 };
|
|
158
|
+
try {
|
|
159
|
+
if (this.ndjson) {
|
|
160
|
+
for (const s of spans) {
|
|
161
|
+
const line = JSON.stringify(serializeSpan(s)) + "\n";
|
|
162
|
+
fs2.appendFileSync(this.filePath, line, "utf8");
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
for (const s of spans) this.buffer.push(serializeSpan(s));
|
|
166
|
+
}
|
|
167
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
168
|
+
} catch {
|
|
169
|
+
resultCallback({ code: ExportResultCode.FAILED });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
shutdown() {
|
|
173
|
+
return new Promise((resolve) => {
|
|
174
|
+
try {
|
|
175
|
+
if (this.ndjson) {
|
|
176
|
+
} else {
|
|
177
|
+
fs2.writeFileSync(this.filePath, JSON.stringify({ spans: this.buffer }, null, 2), "utf8");
|
|
178
|
+
}
|
|
179
|
+
} catch {
|
|
180
|
+
}
|
|
181
|
+
resolve();
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
forceFlush() {
|
|
185
|
+
return Promise.resolve();
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// src/telemetry/trace-report-exporter.ts
|
|
192
|
+
var trace_report_exporter_exports = {};
|
|
193
|
+
__export(trace_report_exporter_exports, {
|
|
194
|
+
TraceReportExporter: () => TraceReportExporter
|
|
195
|
+
});
|
|
196
|
+
import * as fs3 from "fs";
|
|
197
|
+
import * as path3 from "path";
|
|
198
|
+
function hrTimeToMillis(t) {
|
|
199
|
+
return t[0] * 1e3 + Math.floor(t[1] / 1e6);
|
|
200
|
+
}
|
|
201
|
+
function escapeHtml(s) {
|
|
202
|
+
return s.replace(
|
|
203
|
+
/[&<>"']/g,
|
|
204
|
+
(c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
var otelCore2, TraceReportExporter;
|
|
208
|
+
var init_trace_report_exporter = __esm({
|
|
209
|
+
"src/telemetry/trace-report-exporter.ts"() {
|
|
210
|
+
"use strict";
|
|
211
|
+
try {
|
|
212
|
+
otelCore2 = (function(name) {
|
|
213
|
+
return __require(name);
|
|
214
|
+
})("@opentelemetry/core");
|
|
215
|
+
} catch {
|
|
216
|
+
otelCore2 = null;
|
|
217
|
+
}
|
|
218
|
+
TraceReportExporter = class {
|
|
219
|
+
spans = [];
|
|
220
|
+
outDir;
|
|
221
|
+
runId;
|
|
222
|
+
constructor(opts = {}) {
|
|
223
|
+
this.outDir = opts.dir || path3.join(process.cwd(), "output", "traces");
|
|
224
|
+
this.runId = opts.runId;
|
|
225
|
+
if (!fs3.existsSync(this.outDir)) fs3.mkdirSync(this.outDir, { recursive: true });
|
|
226
|
+
}
|
|
227
|
+
export(spans, resultCallback) {
|
|
228
|
+
const ExportResultCode = otelCore2?.ExportResultCode || { SUCCESS: 0, FAILED: 1 };
|
|
229
|
+
try {
|
|
230
|
+
this.spans.push(...spans);
|
|
231
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
232
|
+
} catch {
|
|
233
|
+
resultCallback({ code: ExportResultCode.FAILED });
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async shutdown() {
|
|
237
|
+
try {
|
|
238
|
+
if (this.spans.length === 0) return;
|
|
239
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
240
|
+
const prefix = this.runId ? `run-${this.runId}-` : "";
|
|
241
|
+
const jsonPath = path3.join(this.outDir, `${prefix}${ts}.trace.json`);
|
|
242
|
+
const htmlPath = path3.join(this.outDir, `${prefix}${ts}.report.html`);
|
|
243
|
+
const otlpPath = path3.join(this.outDir, `${prefix}${ts}.otlp.json`);
|
|
244
|
+
const starts = this.spans.map((s) => hrTimeToMillis(s.startTime));
|
|
245
|
+
const ends = this.spans.map((s) => hrTimeToMillis(s.endTime));
|
|
246
|
+
const minStart = Math.min(...starts);
|
|
247
|
+
const maxEnd = Math.max(...ends);
|
|
248
|
+
const flat = this.spans.map((s) => ({
|
|
249
|
+
name: s.name,
|
|
250
|
+
start: hrTimeToMillis(s.startTime),
|
|
251
|
+
end: hrTimeToMillis(s.endTime),
|
|
252
|
+
duration: Math.max(0, hrTimeToMillis(s.endTime) - hrTimeToMillis(s.startTime)),
|
|
253
|
+
offset: hrTimeToMillis(s.startTime) - minStart,
|
|
254
|
+
attrs: s.attributes,
|
|
255
|
+
events: s.events?.map((e) => ({
|
|
256
|
+
name: e.name,
|
|
257
|
+
time: hrTimeToMillis(e.time),
|
|
258
|
+
attrs: e.attributes
|
|
259
|
+
})),
|
|
260
|
+
traceId: s.spanContext().traceId,
|
|
261
|
+
spanId: s.spanContext().spanId,
|
|
262
|
+
parentSpanId: s.parentSpanId
|
|
263
|
+
}));
|
|
264
|
+
fs3.writeFileSync(jsonPath, JSON.stringify({ spans: flat }, null, 2), "utf8");
|
|
265
|
+
try {
|
|
266
|
+
const req = this.toOtlpJson();
|
|
267
|
+
fs3.writeFileSync(otlpPath, JSON.stringify(req, null, 2), "utf8");
|
|
268
|
+
} catch {
|
|
269
|
+
}
|
|
270
|
+
const html = `<!doctype html>
|
|
271
|
+
<html>
|
|
272
|
+
<head>
|
|
273
|
+
<meta charset="utf-8"/>
|
|
274
|
+
<title>Visor Trace Report</title>
|
|
275
|
+
<style>
|
|
276
|
+
:root{--fg:#e6edf3;--bg:#0b0f14;--muted:#8b949e;--panel:#161b22;--border:#30363d;--accent:#1f6feb}
|
|
277
|
+
body{font-family:system-ui,Segoe UI,Roboto,Helvetica,Arial,sans-serif;margin:0;background:var(--bg);color:var(--fg)}
|
|
278
|
+
.container{max-width:1200px;margin:0 auto;padding:16px}
|
|
279
|
+
.summary{display:flex;gap:16px;color:var(--muted);font-size:12px;margin-bottom:8px;flex-wrap:wrap}
|
|
280
|
+
.panel{background:var(--panel);border:1px solid var(--border);border-radius:6px;padding:8px}
|
|
281
|
+
.tree .node{margin-left:12px;border-left:1px dashed var(--border);padding-left:8px}
|
|
282
|
+
.tree .root{border:0;margin-left:0;padding-left:0}
|
|
283
|
+
.node> .head{display:flex;align-items:center;gap:8px;cursor:pointer}
|
|
284
|
+
.toggle{width:10px;height:10px;border:1px solid var(--border);display:inline-flex;align-items:center;justify-content:center;font-size:10px;border-radius:2px;color:var(--muted)}
|
|
285
|
+
.name{font-weight:600}
|
|
286
|
+
.meta{color:var(--muted);font-size:12px}
|
|
287
|
+
.timeline{position:relative;height:8px;background:linear-gradient(90deg,transparent 0,var(--border) 0) left/100% 1px no-repeat;margin:6px 0 6px 18px}
|
|
288
|
+
.bar{position:absolute;height:6px;background:var(--accent);border-radius:3px}
|
|
289
|
+
.details{display:none;margin:4px 0 8px 18px}
|
|
290
|
+
.details pre{white-space:pre-wrap;background:#0f141a;border:1px solid var(--border);padding:8px;border-radius:4px;color:var(--fg)}
|
|
291
|
+
.legend{display:flex;justify-content:space-between;margin:8px 0;font-size:12px;color:var(--muted)}
|
|
292
|
+
.grid{display:grid;grid-template-columns:360px 1fr;gap:12px}
|
|
293
|
+
@media (max-width:900px){.grid{display:block}}
|
|
294
|
+
</style>
|
|
295
|
+
</head>
|
|
296
|
+
<body>
|
|
297
|
+
<div class="container">
|
|
298
|
+
<h2>Visor Trace Report</h2>
|
|
299
|
+
<div class="summary">
|
|
300
|
+
<div>Start: ${new Date(minStart).toISOString()}</div>
|
|
301
|
+
<div>Total Duration: ${maxEnd - minStart} ms</div>
|
|
302
|
+
<div>Spans: ${flat.length}</div>
|
|
303
|
+
<div>Saved JSON: ${escapeHtml(path3.basename(jsonPath))}</div>
|
|
304
|
+
</div>
|
|
305
|
+
<div class="grid">
|
|
306
|
+
<div class="panel">
|
|
307
|
+
<div class="legend"><div>Trace Tree</div><div>click a span for details</div></div>
|
|
308
|
+
<div id="tree" class="tree"></div>
|
|
309
|
+
</div>
|
|
310
|
+
<div class="panel">
|
|
311
|
+
<div class="legend"><div>Timeline</div><div>${maxEnd - minStart} ms</div></div>
|
|
312
|
+
<div id="timeline" style="position:relative;height:${Math.max(120, flat.length * 16)}px"></div>
|
|
313
|
+
<div class="legend"><div>0 ms</div><div>${maxEnd - minStart} ms</div></div>
|
|
314
|
+
</div>
|
|
315
|
+
</div>
|
|
316
|
+
</div>
|
|
317
|
+
<script id="trace-data" type="application/json">${escapeHtml(JSON.stringify({ spans: flat }))}</script>
|
|
318
|
+
<script>
|
|
319
|
+
const data = JSON.parse(document.getElementById('trace-data').textContent);
|
|
320
|
+
const spans = data.spans || [];
|
|
321
|
+
const byId = new Map(spans.map(s => [s.spanId, { span:s, children:[] }]));
|
|
322
|
+
const roots = [];
|
|
323
|
+
for (const n of byId.values()) { const p = n.span.parentSpanId && byId.get(n.span.parentSpanId); if (p) p.children.push(n); else roots.push(n); }
|
|
324
|
+
for (const n of byId.values()) n.children.sort((a,b)=>a.span.start-b.span.start);
|
|
325
|
+
roots.sort((a,b)=>a.span.start-b.span.start);
|
|
326
|
+
const treeEl = document.getElementById('tree');
|
|
327
|
+
const tlEl = document.getElementById('timeline');
|
|
328
|
+
const total = Math.max(1, Math.max(...spans.map(s=>s.end)) - Math.min(...spans.map(s=>s.start)));
|
|
329
|
+
function renderNode(n, parentEl, depth){
|
|
330
|
+
const s=n.span;
|
|
331
|
+
const node=document.createElement('div'); node.className='node'+(depth? '':' root');
|
|
332
|
+
const head=document.createElement('div'); head.className='head';
|
|
333
|
+
const t=document.createElement('span'); t.className='toggle'; t.textContent=n.children.length?'+':'';
|
|
334
|
+
const name=document.createElement('span'); name.className='name'; name.textContent=s.name;
|
|
335
|
+
const meta=document.createElement('span'); meta.className='meta'; meta.textContent=' '+s.duration+'ms';
|
|
336
|
+
head.append(t,name,meta); node.append(head);
|
|
337
|
+
const details=document.createElement('div'); details.className='details';
|
|
338
|
+
details.innerHTML = '' +
|
|
339
|
+
<div class="timeline"><div class="bar" style="left:' + ((s.offset/total)*100) + '%;width:' + Math.max(0.5,(s.duration/total)*100) + '%"></div></div>
|
|
340
|
+
<div class="meta">start: ' + new Date(s.start).toISOString() + ' \u2022 end: ' + new Date(s.end).toISOString() + '</div>
|
|
341
|
+
<div class="meta">trace: ' + s.traceId + ' \u2022 span: ' + s.spanId + '' + (s.parentSpanId? ' \u2022 parent: '+s.parentSpanId:'' ) + '</div>
|
|
342
|
+
<div class="meta">attributes</div>
|
|
343
|
+
<pre>' + JSON.stringify(s.attrs||{},null,2) + '</pre>
|
|
344
|
+
<div class="meta">events ' + ((s.events||[]).length) + '</div>
|
|
345
|
+
<pre>' + JSON.stringify(s.events||[],null,2) + '</pre>';
|
|
346
|
+
node.append(details);
|
|
347
|
+
head.onclick=()=>{ const open=details.style.display!=='none'; details.style.display=open?'none':'block'; if(n.children.length) t.textContent=open?'+':'\u2013'; };
|
|
348
|
+
details.style.display='none';
|
|
349
|
+
parentEl.append(node);
|
|
350
|
+
const tlRow=document.createElement('div'); tlRow.style.position='relative'; tlRow.style.height='16px'; tlRow.style.margin='2px 0';
|
|
351
|
+
const bar=document.createElement('div'); bar.className='bar'; bar.style.left=((s.offset/total)*100)+'%'; bar.style.width=(Math.max(0.5,(s.duration/total)*100))+'%'; bar.title=s.name+' ('+s.duration+'ms)'; tlRow.append(bar);
|
|
352
|
+
tlEl.append(tlRow);
|
|
353
|
+
for(const c of n.children) renderNode(c, node, depth+1);
|
|
354
|
+
}
|
|
355
|
+
roots.forEach(r=>renderNode(r, treeEl, 0));
|
|
356
|
+
</script>
|
|
357
|
+
</body>
|
|
358
|
+
</html>`;
|
|
359
|
+
fs3.writeFileSync(htmlPath, html, "utf8");
|
|
360
|
+
} catch {
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
toOtlpJson() {
|
|
364
|
+
const resourceGroups = /* @__PURE__ */ new Map();
|
|
365
|
+
for (const s of this.spans) {
|
|
366
|
+
const resAttrs = s.resource?.attributes || {};
|
|
367
|
+
const resKey = JSON.stringify(resAttrs);
|
|
368
|
+
let g = resourceGroups.get(resKey);
|
|
369
|
+
if (!g) {
|
|
370
|
+
g = { resource: resAttrs, spans: [] };
|
|
371
|
+
resourceGroups.set(resKey, g);
|
|
372
|
+
}
|
|
373
|
+
g.spans.push(s);
|
|
374
|
+
}
|
|
375
|
+
const resourceSpans = Array.from(resourceGroups.values()).map((g) => ({
|
|
376
|
+
resource: {
|
|
377
|
+
attributes: toOtelAttributes(g.resource)
|
|
378
|
+
},
|
|
379
|
+
scopeSpans: [
|
|
380
|
+
{
|
|
381
|
+
scope: { name: "visor", version: String(process.env.VISOR_VERSION || "dev") },
|
|
382
|
+
spans: g.spans.map((s) => toOtelSpan(s))
|
|
383
|
+
}
|
|
384
|
+
]
|
|
385
|
+
}));
|
|
386
|
+
return { resourceSpans };
|
|
387
|
+
function toOtelSpan(s) {
|
|
388
|
+
const startMs = hrTimeToMillis(s.startTime);
|
|
389
|
+
const endMs = hrTimeToMillis(s.endTime);
|
|
390
|
+
const toNs = (ms) => String(Math.max(0, Math.floor(ms * 1e6)));
|
|
391
|
+
return {
|
|
392
|
+
traceId: s.spanContext().traceId,
|
|
393
|
+
// hex; many tools accept hex in JSON
|
|
394
|
+
spanId: s.spanContext().spanId,
|
|
395
|
+
parentSpanId: s.parentSpanId || void 0,
|
|
396
|
+
name: s.name,
|
|
397
|
+
kind: s.kind ?? 0,
|
|
398
|
+
startTimeUnixNano: toNs(startMs),
|
|
399
|
+
endTimeUnixNano: toNs(endMs),
|
|
400
|
+
attributes: toOtelAttributes(s.attributes || {}),
|
|
401
|
+
events: (s.events || []).map((e) => ({
|
|
402
|
+
timeUnixNano: toNs(hrTimeToMillis(e.time)),
|
|
403
|
+
name: e.name,
|
|
404
|
+
attributes: toOtelAttributes(e.attributes || {})
|
|
405
|
+
})),
|
|
406
|
+
status: s.status ? {
|
|
407
|
+
code: s.status.code ?? 0,
|
|
408
|
+
message: s.status.message || void 0
|
|
409
|
+
} : void 0
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
function toOtelAttributes(obj) {
|
|
413
|
+
const out = [];
|
|
414
|
+
for (const [key, value] of Object.entries(obj || {})) {
|
|
415
|
+
out.push({ key, value: toAnyValue(value) });
|
|
416
|
+
}
|
|
417
|
+
return out;
|
|
418
|
+
}
|
|
419
|
+
function toAnyValue(v) {
|
|
420
|
+
const t = typeof v;
|
|
421
|
+
if (v == null) return { stringValue: "null" };
|
|
422
|
+
if (t === "string") return { stringValue: v };
|
|
423
|
+
if (t === "boolean") return { boolValue: v };
|
|
424
|
+
if (t === "number")
|
|
425
|
+
return Number.isInteger(v) ? { intValue: String(v) } : { doubleValue: v };
|
|
426
|
+
if (Array.isArray(v)) return { arrayValue: { values: v.map(toAnyValue) } };
|
|
427
|
+
if (t === "object")
|
|
428
|
+
return { kvlistValue: { values: toOtelAttributes(v) } };
|
|
429
|
+
return { stringValue: String(v) };
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
async forceFlush() {
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// src/debug-visualizer/debug-span-exporter.ts
|
|
439
|
+
var debug_span_exporter_exports = {};
|
|
440
|
+
__export(debug_span_exporter_exports, {
|
|
441
|
+
DebugSpanExporter: () => DebugSpanExporter,
|
|
442
|
+
createDebugSpanExporter: () => createDebugSpanExporter
|
|
443
|
+
});
|
|
444
|
+
function createDebugSpanExporter(server) {
|
|
445
|
+
return new DebugSpanExporter(server);
|
|
446
|
+
}
|
|
447
|
+
var otelCore3, DebugSpanExporter;
|
|
448
|
+
var init_debug_span_exporter = __esm({
|
|
449
|
+
"src/debug-visualizer/debug-span-exporter.ts"() {
|
|
450
|
+
"use strict";
|
|
451
|
+
try {
|
|
452
|
+
otelCore3 = (function(name) {
|
|
453
|
+
return __require(name);
|
|
454
|
+
})("@opentelemetry/core");
|
|
455
|
+
} catch {
|
|
456
|
+
otelCore3 = null;
|
|
457
|
+
}
|
|
458
|
+
DebugSpanExporter = class {
|
|
459
|
+
server;
|
|
460
|
+
constructor(server) {
|
|
461
|
+
this.server = server;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Export spans to WebSocket server
|
|
465
|
+
*/
|
|
466
|
+
export(spans, resultCallback) {
|
|
467
|
+
const ExportResultCode = otelCore3?.ExportResultCode || { SUCCESS: 0, FAILED: 1 };
|
|
468
|
+
console.log(`[debug-exporter] Export called with ${spans.length} spans`);
|
|
469
|
+
try {
|
|
470
|
+
for (const span of spans) {
|
|
471
|
+
console.log(`[debug-exporter] Converting and emitting span: ${span.name}`);
|
|
472
|
+
const processedSpan = this.convertSpan(span);
|
|
473
|
+
this.server.emitSpan(processedSpan);
|
|
474
|
+
}
|
|
475
|
+
console.log(`[debug-exporter] Successfully exported ${spans.length} spans`);
|
|
476
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
477
|
+
} catch (error) {
|
|
478
|
+
console.error("[debug-exporter] Failed to export spans:", error);
|
|
479
|
+
resultCallback({
|
|
480
|
+
code: ExportResultCode.FAILED,
|
|
481
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Shutdown the exporter
|
|
487
|
+
*/
|
|
488
|
+
async shutdown() {
|
|
489
|
+
console.log("[debug-exporter] Shutdown called");
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Force flush any buffered spans (no-op for this exporter)
|
|
493
|
+
*/
|
|
494
|
+
async forceFlush() {
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Convert OTEL ReadableSpan to ProcessedSpan format
|
|
498
|
+
*/
|
|
499
|
+
convertSpan(span) {
|
|
500
|
+
const attributes = {};
|
|
501
|
+
for (const [key, value] of Object.entries(span.attributes)) {
|
|
502
|
+
attributes[key] = value;
|
|
503
|
+
}
|
|
504
|
+
const rawParent = span.parentSpanId;
|
|
505
|
+
console.log(
|
|
506
|
+
`[debug-exporter] Span: ${span.name}, parent: ${span.parentSpanId || "NONE"} (type: ${typeof rawParent})`
|
|
507
|
+
);
|
|
508
|
+
const events = span.events.map((event) => ({
|
|
509
|
+
name: event.name,
|
|
510
|
+
time: this.hrTimeToTuple(event.time),
|
|
511
|
+
timestamp: new Date(this.hrTimeToMillis(event.time)).toISOString(),
|
|
512
|
+
attributes: event.attributes ? { ...event.attributes } : {}
|
|
513
|
+
}));
|
|
514
|
+
const status = span.status.code === 2 ? "error" : "ok";
|
|
515
|
+
const startMs = this.hrTimeToMillis(span.startTime);
|
|
516
|
+
const endMs = this.hrTimeToMillis(span.endTime);
|
|
517
|
+
const duration = endMs - startMs;
|
|
518
|
+
return {
|
|
519
|
+
traceId: span.spanContext().traceId,
|
|
520
|
+
spanId: span.spanContext().spanId,
|
|
521
|
+
parentSpanId: span.parentSpanId,
|
|
522
|
+
name: span.name,
|
|
523
|
+
startTime: this.hrTimeToTuple(span.startTime),
|
|
524
|
+
endTime: this.hrTimeToTuple(span.endTime),
|
|
525
|
+
duration,
|
|
526
|
+
attributes,
|
|
527
|
+
events,
|
|
528
|
+
status
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Convert OTEL HrTime to [seconds, nanoseconds] tuple
|
|
533
|
+
*/
|
|
534
|
+
hrTimeToTuple(hrTime) {
|
|
535
|
+
return hrTime;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Convert OTEL HrTime to milliseconds
|
|
539
|
+
*/
|
|
540
|
+
hrTimeToMillis(hrTime) {
|
|
541
|
+
return hrTime[0] * 1e3 + hrTime[1] / 1e6;
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
// src/telemetry/opentelemetry.ts
|
|
548
|
+
var opentelemetry_exports = {};
|
|
549
|
+
__export(opentelemetry_exports, {
|
|
550
|
+
forceFlushTelemetry: () => forceFlushTelemetry,
|
|
551
|
+
getOtelLoggerProvider: () => getOtelLoggerProvider,
|
|
552
|
+
initTelemetry: () => initTelemetry,
|
|
553
|
+
requestThrottledTelemetryFlush: () => requestThrottledTelemetryFlush,
|
|
554
|
+
resetTelemetryForTesting: () => resetTelemetryForTesting,
|
|
555
|
+
shutdownTelemetry: () => shutdownTelemetry
|
|
556
|
+
});
|
|
557
|
+
function resetTelemetryForTesting() {
|
|
558
|
+
sdk = null;
|
|
559
|
+
patched = false;
|
|
560
|
+
}
|
|
561
|
+
async function initTelemetry(opts = {}) {
|
|
562
|
+
const enabled = !!opts.enabled || !!opts.debugServer || process.env.VISOR_TELEMETRY_ENABLED === "true";
|
|
563
|
+
if (!enabled || sdk) return;
|
|
564
|
+
try {
|
|
565
|
+
(function(name) {
|
|
566
|
+
return __require(name);
|
|
567
|
+
})("@opentelemetry/api");
|
|
568
|
+
const { NodeSDK } = (function(name) {
|
|
569
|
+
return __require(name);
|
|
570
|
+
})("@opentelemetry/sdk-node");
|
|
571
|
+
const resourcesModule = (function(name) {
|
|
572
|
+
return __require(name);
|
|
573
|
+
})("@opentelemetry/resources");
|
|
574
|
+
const semanticConventions = (function(name) {
|
|
575
|
+
return __require(name);
|
|
576
|
+
})("@opentelemetry/semantic-conventions");
|
|
577
|
+
const { BatchSpanProcessor, ConsoleSpanExporter } = (function(name) {
|
|
578
|
+
return __require(name);
|
|
579
|
+
})("@opentelemetry/sdk-trace-base");
|
|
580
|
+
const sink = opts.sink || process.env.VISOR_TELEMETRY_SINK || "file";
|
|
581
|
+
const processors = [];
|
|
582
|
+
if (!process.env.VISOR_FALLBACK_TRACE_FILE && sink === "file") {
|
|
583
|
+
try {
|
|
584
|
+
const fs4 = __require("fs");
|
|
585
|
+
const path4 = __require("path");
|
|
586
|
+
const outDir = opts.file?.dir || process.env.VISOR_TRACE_DIR || path4.join(process.cwd(), "output", "traces");
|
|
587
|
+
fs4.mkdirSync(outDir, { recursive: true });
|
|
588
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
589
|
+
process.env.VISOR_FALLBACK_TRACE_FILE = path4.join(outDir, `run-${ts}.ndjson`);
|
|
590
|
+
} catch {
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
if (sink === "otlp") {
|
|
594
|
+
const protocol = opts.otlp?.protocol || "http";
|
|
595
|
+
if (protocol === "http") {
|
|
596
|
+
const { OTLPTraceExporter } = (function(name) {
|
|
597
|
+
return __require(name);
|
|
598
|
+
})("@opentelemetry/exporter-trace-otlp-http");
|
|
599
|
+
const traceUrl = opts.otlp?.endpoint || process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || void 0;
|
|
600
|
+
const exporter = new OTLPTraceExporter({
|
|
601
|
+
...traceUrl ? { url: traceUrl } : {},
|
|
602
|
+
headers: opts.otlp?.headers || process.env.OTEL_EXPORTER_OTLP_HEADERS
|
|
603
|
+
});
|
|
604
|
+
processors.push(new BatchSpanProcessor(exporter, batchParams()));
|
|
605
|
+
} else {
|
|
606
|
+
try {
|
|
607
|
+
const { OTLPTraceExporter: GrpcExporter } = (function(name) {
|
|
608
|
+
return __require(name);
|
|
609
|
+
})("@opentelemetry/exporter-trace-otlp-grpc");
|
|
610
|
+
processors.push(new BatchSpanProcessor(new GrpcExporter({}), batchParams()));
|
|
611
|
+
} catch {
|
|
612
|
+
processors.push(new BatchSpanProcessor(new ConsoleSpanExporter(), batchParams()));
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
} else if (sink === "console") {
|
|
616
|
+
processors.push(new BatchSpanProcessor(new ConsoleSpanExporter(), batchParams()));
|
|
617
|
+
} else {
|
|
618
|
+
const { FileSpanExporter: FileSpanExporter2 } = (init_file_span_exporter(), __toCommonJS(file_span_exporter_exports));
|
|
619
|
+
const exporter = new FileSpanExporter2({
|
|
620
|
+
dir: opts.file?.dir || process.env.VISOR_TRACE_DIR,
|
|
621
|
+
ndjson: opts.file?.ndjson,
|
|
622
|
+
runId: opts.file?.runId
|
|
623
|
+
});
|
|
624
|
+
processors.push(new BatchSpanProcessor(exporter, batchParams()));
|
|
625
|
+
}
|
|
626
|
+
let resource;
|
|
627
|
+
if (resourcesModule.Resource) {
|
|
628
|
+
resource = new resourcesModule.Resource({
|
|
629
|
+
[semanticConventions.SemanticResourceAttributes.SERVICE_NAME]: "visor",
|
|
630
|
+
[semanticConventions.SemanticResourceAttributes.SERVICE_VERSION]: process.env.VISOR_VERSION || "dev",
|
|
631
|
+
"deployment.environment": detectEnvironment()
|
|
632
|
+
});
|
|
633
|
+
} else {
|
|
634
|
+
resource = resourcesModule.resourceFromAttributes({
|
|
635
|
+
[semanticConventions.ATTR_SERVICE_NAME]: "visor",
|
|
636
|
+
[semanticConventions.ATTR_SERVICE_VERSION]: process.env.VISOR_VERSION || "dev",
|
|
637
|
+
"deployment.environment": detectEnvironment()
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
let metricReader;
|
|
641
|
+
if (sink === "otlp") {
|
|
642
|
+
try {
|
|
643
|
+
const { OTLPMetricExporter } = (function(name) {
|
|
644
|
+
return __require(name);
|
|
645
|
+
})("@opentelemetry/exporter-metrics-otlp-http");
|
|
646
|
+
const { PeriodicExportingMetricReader } = (function(name) {
|
|
647
|
+
return __require(name);
|
|
648
|
+
})("@opentelemetry/sdk-metrics");
|
|
649
|
+
const metricsUrl = process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT || void 0;
|
|
650
|
+
const mExporter = new OTLPMetricExporter({
|
|
651
|
+
...metricsUrl ? { url: metricsUrl } : {},
|
|
652
|
+
headers: process.env.OTEL_EXPORTER_OTLP_HEADERS
|
|
653
|
+
});
|
|
654
|
+
metricReader = new PeriodicExportingMetricReader({
|
|
655
|
+
exporter: mExporter,
|
|
656
|
+
exportIntervalMillis: 1e4,
|
|
657
|
+
exportTimeoutMillis: 1e4
|
|
658
|
+
});
|
|
659
|
+
} catch {
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
if (sink === "otlp") {
|
|
663
|
+
try {
|
|
664
|
+
const { LoggerProvider, BatchLogRecordProcessor } = (function(name) {
|
|
665
|
+
return __require(name);
|
|
666
|
+
})("@opentelemetry/sdk-logs");
|
|
667
|
+
const { OTLPLogExporter } = (function(name) {
|
|
668
|
+
return __require(name);
|
|
669
|
+
})("@opentelemetry/exporter-logs-otlp-http");
|
|
670
|
+
const { logs: logsApi } = (function(name) {
|
|
671
|
+
return __require(name);
|
|
672
|
+
})("@opentelemetry/api-logs");
|
|
673
|
+
const logsUrl = process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT || void 0;
|
|
674
|
+
const logExporter = new OTLPLogExporter({
|
|
675
|
+
...logsUrl ? { url: logsUrl } : {},
|
|
676
|
+
headers: process.env.OTEL_EXPORTER_OTLP_HEADERS
|
|
677
|
+
});
|
|
678
|
+
const logProcessor = new BatchLogRecordProcessor(logExporter);
|
|
679
|
+
const lp = new LoggerProvider({ resource });
|
|
680
|
+
lp._sharedState.registeredLogRecordProcessors.push(logProcessor);
|
|
681
|
+
lp._sharedState.activeProcessor = logProcessor;
|
|
682
|
+
logsApi.setGlobalLoggerProvider(lp);
|
|
683
|
+
loggerProvider = lp;
|
|
684
|
+
} catch {
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
let instrumentations;
|
|
688
|
+
const autoInstr = opts.autoInstrument === true || process.env.VISOR_TELEMETRY_AUTO_INSTRUMENTATIONS === "true";
|
|
689
|
+
if (autoInstr) {
|
|
690
|
+
try {
|
|
691
|
+
const { getNodeAutoInstrumentations } = (function(name) {
|
|
692
|
+
return __require(name);
|
|
693
|
+
})("@opentelemetry/auto-instrumentations-node");
|
|
694
|
+
instrumentations = [getNodeAutoInstrumentations()];
|
|
695
|
+
} catch {
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
if (opts.traceReport === true || process.env.VISOR_TRACE_REPORT === "true") {
|
|
699
|
+
try {
|
|
700
|
+
const { TraceReportExporter: TraceReportExporter2 } = (init_trace_report_exporter(), __toCommonJS(trace_report_exporter_exports));
|
|
701
|
+
const { BatchSpanProcessor: BatchSpanProcessor2 } = (function(name) {
|
|
702
|
+
return __require(name);
|
|
703
|
+
})("@opentelemetry/sdk-trace-base");
|
|
704
|
+
processors.push(
|
|
705
|
+
new BatchSpanProcessor2(
|
|
706
|
+
new TraceReportExporter2({
|
|
707
|
+
dir: opts.file?.dir || process.env.VISOR_TRACE_DIR,
|
|
708
|
+
runId: opts.file?.runId
|
|
709
|
+
})
|
|
710
|
+
)
|
|
711
|
+
);
|
|
712
|
+
} catch {
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
if (opts.debugServer) {
|
|
716
|
+
try {
|
|
717
|
+
const { DebugSpanExporter: DebugSpanExporter2 } = (init_debug_span_exporter(), __toCommonJS(debug_span_exporter_exports));
|
|
718
|
+
const { SimpleSpanProcessor } = (function(name) {
|
|
719
|
+
return __require(name);
|
|
720
|
+
})("@opentelemetry/sdk-trace-base");
|
|
721
|
+
const debugExporter = new DebugSpanExporter2(opts.debugServer);
|
|
722
|
+
processors.push(new SimpleSpanProcessor(debugExporter));
|
|
723
|
+
} catch (error) {
|
|
724
|
+
console.error("[telemetry] Failed to initialize debug span exporter:", error);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
let spanProcessor;
|
|
728
|
+
if (processors.length > 1) {
|
|
729
|
+
spanProcessor = {
|
|
730
|
+
onStart: (span, context2) => {
|
|
731
|
+
processors.forEach((p) => p.onStart?.(span, context2));
|
|
732
|
+
},
|
|
733
|
+
onEnd: (span) => {
|
|
734
|
+
processors.forEach((p) => p.onEnd?.(span));
|
|
735
|
+
},
|
|
736
|
+
shutdown: async () => {
|
|
737
|
+
await Promise.all(processors.map((p) => p.shutdown()));
|
|
738
|
+
},
|
|
739
|
+
forceFlush: async () => {
|
|
740
|
+
await Promise.all(processors.map((p) => p.forceFlush()));
|
|
741
|
+
}
|
|
742
|
+
};
|
|
743
|
+
} else {
|
|
744
|
+
spanProcessor = processors[0];
|
|
745
|
+
}
|
|
746
|
+
const nodeSdk = new NodeSDK({
|
|
747
|
+
resource,
|
|
748
|
+
spanProcessor,
|
|
749
|
+
metricReader,
|
|
750
|
+
instrumentations
|
|
751
|
+
// Context manager is already set globally above
|
|
752
|
+
// Auto-instrumentations can be added later when desired
|
|
753
|
+
});
|
|
754
|
+
const otelApiForDiag = (function(name) {
|
|
755
|
+
return __require(name);
|
|
756
|
+
})("@opentelemetry/api");
|
|
757
|
+
const DiagConsoleLoggerClass = otelApiForDiag.DiagConsoleLogger;
|
|
758
|
+
const diagLogLevel = otelApiForDiag.DiagLogLevel;
|
|
759
|
+
otelApiForDiag.diag.setLogger(new DiagConsoleLoggerClass(), diagLogLevel.ERROR);
|
|
760
|
+
await nodeSdk.start();
|
|
761
|
+
sdk = nodeSdk;
|
|
762
|
+
if (opts.patchConsole !== false) patchConsole();
|
|
763
|
+
} catch (error) {
|
|
764
|
+
if (process.env.VISOR_DEBUG === "true" || process.env.DEBUG) {
|
|
765
|
+
console.error("[telemetry] Failed to initialize OTel SDK:", error);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
function getOtelLoggerProvider() {
|
|
770
|
+
return loggerProvider;
|
|
771
|
+
}
|
|
772
|
+
async function forceFlushTelemetry() {
|
|
773
|
+
if (!sdk) return;
|
|
774
|
+
try {
|
|
775
|
+
if (typeof sdk.forceFlush === "function") {
|
|
776
|
+
await sdk.forceFlush();
|
|
777
|
+
}
|
|
778
|
+
} catch {
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
function requestThrottledTelemetryFlush() {
|
|
782
|
+
if (!sdk || flushInFlight || flushTimer) return;
|
|
783
|
+
const minIntervalMs = Math.max(
|
|
784
|
+
250,
|
|
785
|
+
parseInt(process.env.VISOR_TELEMETRY_FLUSH_INTERVAL_MS || "1500", 10) || 1500
|
|
786
|
+
);
|
|
787
|
+
const elapsed = Date.now() - lastFlushStartedAt;
|
|
788
|
+
const delayMs = Math.max(0, minIntervalMs - elapsed);
|
|
789
|
+
flushTimer = setTimeout(() => {
|
|
790
|
+
flushTimer = null;
|
|
791
|
+
if (!sdk || flushInFlight) return;
|
|
792
|
+
flushInFlight = true;
|
|
793
|
+
lastFlushStartedAt = Date.now();
|
|
794
|
+
void (typeof sdk.forceFlush === "function" ? sdk.forceFlush() : Promise.resolve()).catch(() => {
|
|
795
|
+
}).finally(() => {
|
|
796
|
+
flushInFlight = false;
|
|
797
|
+
});
|
|
798
|
+
}, delayMs);
|
|
799
|
+
if (typeof flushTimer.unref === "function") flushTimer.unref();
|
|
800
|
+
}
|
|
801
|
+
async function shutdownTelemetry() {
|
|
802
|
+
if (!sdk) return;
|
|
803
|
+
try {
|
|
804
|
+
try {
|
|
805
|
+
const { flushNdjson: flushNdjson2 } = (init_fallback_ndjson(), __toCommonJS(fallback_ndjson_exports));
|
|
806
|
+
await flushNdjson2();
|
|
807
|
+
} catch {
|
|
808
|
+
}
|
|
809
|
+
if (loggerProvider) {
|
|
810
|
+
try {
|
|
811
|
+
await loggerProvider.shutdown();
|
|
812
|
+
} catch {
|
|
813
|
+
}
|
|
814
|
+
loggerProvider = null;
|
|
815
|
+
}
|
|
816
|
+
await sdk.shutdown();
|
|
817
|
+
} catch {
|
|
818
|
+
} finally {
|
|
819
|
+
sdk = null;
|
|
820
|
+
try {
|
|
821
|
+
if (process.env.VISOR_TRACE_REPORT === "true") {
|
|
822
|
+
const fs4 = __require("fs");
|
|
823
|
+
const path4 = __require("path");
|
|
824
|
+
const outDir = process.env.VISOR_TRACE_DIR || path4.join(process.cwd(), "output", "traces");
|
|
825
|
+
if (!fs4.existsSync(outDir)) fs4.mkdirSync(outDir, { recursive: true });
|
|
826
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
827
|
+
const htmlPath = path4.join(outDir, `${ts}.report.html`);
|
|
828
|
+
if (!fs4.existsSync(htmlPath)) {
|
|
829
|
+
fs4.writeFileSync(
|
|
830
|
+
htmlPath,
|
|
831
|
+
'<!doctype html><html><head><meta charset="utf-8"/><title>Visor Trace Report</title></head><body><h2>Visor Trace Report</h2></body></html>',
|
|
832
|
+
"utf8"
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
} catch {
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
function detectEnvironment() {
|
|
841
|
+
if (process.env.GITHUB_ACTIONS) return "github-actions";
|
|
842
|
+
if (process.env.CI) return "ci";
|
|
843
|
+
return "local";
|
|
844
|
+
}
|
|
845
|
+
function batchParams() {
|
|
846
|
+
return {
|
|
847
|
+
maxQueueSize: 65536,
|
|
848
|
+
maxExportBatchSize: 8192,
|
|
849
|
+
scheduledDelayMillis: 1e3,
|
|
850
|
+
exportTimeoutMillis: 1e4
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
function patchConsole() {
|
|
854
|
+
if (patched) return;
|
|
855
|
+
try {
|
|
856
|
+
const { context: context2, trace: trace2 } = (function(name) {
|
|
857
|
+
return __require(name);
|
|
858
|
+
})("@opentelemetry/api");
|
|
859
|
+
const methods = ["log", "info", "warn", "error"];
|
|
860
|
+
const c = globalThis.console;
|
|
861
|
+
for (const m of methods) {
|
|
862
|
+
const orig = c[m].bind(c);
|
|
863
|
+
c[m] = (...args) => {
|
|
864
|
+
const span = trace2.getSpan(context2.active());
|
|
865
|
+
const ctx = span?.spanContext();
|
|
866
|
+
if (ctx) {
|
|
867
|
+
try {
|
|
868
|
+
const suffix = ` [trace_id=${ctx.traceId} span_id=${ctx.spanId}]`;
|
|
869
|
+
if (typeof args[0] === "string") args[0] = args[0] + suffix;
|
|
870
|
+
else args.push(suffix);
|
|
871
|
+
} catch {
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
return orig(...args);
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
patched = true;
|
|
878
|
+
} catch {
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
var sdk, patched, loggerProvider, flushTimer, flushInFlight, lastFlushStartedAt;
|
|
882
|
+
var init_opentelemetry = __esm({
|
|
883
|
+
"src/telemetry/opentelemetry.ts"() {
|
|
884
|
+
"use strict";
|
|
885
|
+
sdk = null;
|
|
886
|
+
patched = false;
|
|
887
|
+
loggerProvider = null;
|
|
888
|
+
flushTimer = null;
|
|
889
|
+
flushInFlight = false;
|
|
890
|
+
lastFlushStartedAt = 0;
|
|
891
|
+
}
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
// src/telemetry/trace-helpers.ts
|
|
895
|
+
var trace_helpers_exports = {};
|
|
896
|
+
__export(trace_helpers_exports, {
|
|
897
|
+
__getOrCreateNdjsonPath: () => __getOrCreateNdjsonPath,
|
|
898
|
+
_appendRunMarker: () => _appendRunMarker,
|
|
899
|
+
addEvent: () => addEvent,
|
|
900
|
+
emitImmediateSpan: () => emitImmediateSpan,
|
|
901
|
+
getTracer: () => getTracer,
|
|
902
|
+
getVisorRunAttributes: () => getVisorRunAttributes,
|
|
903
|
+
setSpanAttributes: () => setSpanAttributes,
|
|
904
|
+
setSpanError: () => setSpanError,
|
|
905
|
+
withActiveSpan: () => withActiveSpan,
|
|
906
|
+
withVisorRun: () => withVisorRun
|
|
907
|
+
});
|
|
908
|
+
function getTracer() {
|
|
909
|
+
return trace.getTracer("visor");
|
|
910
|
+
}
|
|
911
|
+
async function withActiveSpan(name, attrs, fn) {
|
|
912
|
+
const tracer = getTracer();
|
|
913
|
+
return await new Promise((resolve, reject) => {
|
|
914
|
+
const callback = async (span) => {
|
|
915
|
+
try {
|
|
916
|
+
const res = await fn(span);
|
|
917
|
+
resolve(res);
|
|
918
|
+
} catch (err) {
|
|
919
|
+
try {
|
|
920
|
+
if (err instanceof Error) span.recordException(err);
|
|
921
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
922
|
+
} catch {
|
|
923
|
+
}
|
|
924
|
+
reject(err);
|
|
925
|
+
} finally {
|
|
926
|
+
try {
|
|
927
|
+
span.end();
|
|
928
|
+
} catch {
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
const options = attrs ? { attributes: attrs } : {};
|
|
933
|
+
tracer.startActiveSpan(name, options, callback);
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
function emitImmediateSpan(name, attrs, options) {
|
|
937
|
+
try {
|
|
938
|
+
const startHr = process.hrtime();
|
|
939
|
+
const tracer = getTracer();
|
|
940
|
+
const span = tracer.startSpan(name, attrs ? { attributes: attrs } : void 0);
|
|
941
|
+
try {
|
|
942
|
+
for (const evt of options?.events || []) {
|
|
943
|
+
span.addEvent(evt.name, evt.attrs || {});
|
|
944
|
+
}
|
|
945
|
+
if (options?.status) {
|
|
946
|
+
span.setStatus(options.status);
|
|
947
|
+
}
|
|
948
|
+
} finally {
|
|
949
|
+
span.end();
|
|
950
|
+
}
|
|
951
|
+
try {
|
|
952
|
+
const { emitNdjsonFullSpan: emitNdjsonFullSpan2 } = (init_fallback_ndjson(), __toCommonJS(fallback_ndjson_exports));
|
|
953
|
+
const activeParent = trace.getSpan(context.active());
|
|
954
|
+
const parentCtx = activeParent?.spanContext?.();
|
|
955
|
+
const ctx = span.spanContext?.();
|
|
956
|
+
const endHr = process.hrtime();
|
|
957
|
+
emitNdjsonFullSpan2({
|
|
958
|
+
name,
|
|
959
|
+
traceId: ctx?.traceId || parentCtx?.traceId || randomTraceId(),
|
|
960
|
+
spanId: ctx?.spanId || randomSpanId(),
|
|
961
|
+
parentSpanId: parentCtx?.spanId,
|
|
962
|
+
startTime: [startHr[0], startHr[1]],
|
|
963
|
+
endTime: [endHr[0], endHr[1]],
|
|
964
|
+
attributes: attrs || {},
|
|
965
|
+
events: (options?.events || []).map((evt) => ({
|
|
966
|
+
name: evt.name,
|
|
967
|
+
attributes: evt.attrs || {}
|
|
968
|
+
})),
|
|
969
|
+
status: options?.status
|
|
970
|
+
});
|
|
971
|
+
} catch {
|
|
972
|
+
}
|
|
973
|
+
try {
|
|
974
|
+
const { requestThrottledTelemetryFlush: requestThrottledTelemetryFlush2 } = (init_opentelemetry(), __toCommonJS(opentelemetry_exports));
|
|
975
|
+
requestThrottledTelemetryFlush2();
|
|
976
|
+
} catch {
|
|
977
|
+
}
|
|
978
|
+
} catch {
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
function randomSpanId() {
|
|
982
|
+
return __require("crypto").randomBytes(8).toString("hex");
|
|
983
|
+
}
|
|
984
|
+
function randomTraceId() {
|
|
985
|
+
return __require("crypto").randomBytes(16).toString("hex");
|
|
986
|
+
}
|
|
987
|
+
function addEvent(name, attrs) {
|
|
988
|
+
const span = trace.getSpan(context.active());
|
|
989
|
+
if (span) {
|
|
990
|
+
try {
|
|
991
|
+
span.addEvent(name, attrs);
|
|
992
|
+
} catch {
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
try {
|
|
996
|
+
const { emitNdjsonSpanWithEvents: emitNdjsonSpanWithEvents2 } = (init_fallback_ndjson(), __toCommonJS(fallback_ndjson_exports));
|
|
997
|
+
emitNdjsonSpanWithEvents2("visor.event", {}, [{ name, attrs }]);
|
|
998
|
+
if (name === "fail_if.triggered") {
|
|
999
|
+
emitNdjsonSpanWithEvents2("visor.event", {}, [
|
|
1000
|
+
{ name: "fail_if.evaluated", attrs },
|
|
1001
|
+
{ name: "fail_if.triggered", attrs }
|
|
1002
|
+
]);
|
|
1003
|
+
}
|
|
1004
|
+
} catch {
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
function setSpanAttributes(attrs) {
|
|
1008
|
+
const span = trace.getSpan(context.active());
|
|
1009
|
+
if (!span) return;
|
|
1010
|
+
try {
|
|
1011
|
+
for (const [k, v] of Object.entries(attrs)) span.setAttribute(k, v);
|
|
1012
|
+
} catch {
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
function setSpanError(err) {
|
|
1016
|
+
const span = trace.getSpan(context.active());
|
|
1017
|
+
if (!span) return;
|
|
1018
|
+
try {
|
|
1019
|
+
if (err instanceof Error) span.recordException(err);
|
|
1020
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
1021
|
+
} catch {
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
function getVisorRunAttributes() {
|
|
1025
|
+
const attrs = {};
|
|
1026
|
+
try {
|
|
1027
|
+
attrs["visor.version"] = process.env.VISOR_VERSION || (require_package()?.version ?? "dev");
|
|
1028
|
+
} catch {
|
|
1029
|
+
attrs["visor.version"] = "dev";
|
|
1030
|
+
}
|
|
1031
|
+
const commitShort = process.env.VISOR_COMMIT_SHORT || "";
|
|
1032
|
+
const commitFull = process.env.VISOR_COMMIT_SHA || process.env.VISOR_COMMIT || "";
|
|
1033
|
+
if (commitShort) {
|
|
1034
|
+
attrs["visor.commit"] = commitShort;
|
|
1035
|
+
}
|
|
1036
|
+
if (commitFull) {
|
|
1037
|
+
attrs["visor.commit.sha"] = commitFull;
|
|
1038
|
+
}
|
|
1039
|
+
attrs["visor.instance_id"] = getInstanceId();
|
|
1040
|
+
return attrs;
|
|
1041
|
+
}
|
|
1042
|
+
async function withVisorRun(attrs, runMeta, fn) {
|
|
1043
|
+
const {
|
|
1044
|
+
recordRunStart,
|
|
1045
|
+
recordRunDuration,
|
|
1046
|
+
resetRunAiCalls,
|
|
1047
|
+
recordRunAiCalls,
|
|
1048
|
+
getRunAiCalls
|
|
1049
|
+
} = (init_metrics(), __toCommonJS(metrics_exports));
|
|
1050
|
+
const instanceId = getInstanceId();
|
|
1051
|
+
recordRunStart({
|
|
1052
|
+
source: runMeta.source,
|
|
1053
|
+
userId: runMeta.userId,
|
|
1054
|
+
userName: runMeta.userName,
|
|
1055
|
+
workflowId: runMeta.workflowId,
|
|
1056
|
+
instanceId
|
|
1057
|
+
});
|
|
1058
|
+
resetRunAiCalls();
|
|
1059
|
+
const startMs = Date.now();
|
|
1060
|
+
let success = true;
|
|
1061
|
+
try {
|
|
1062
|
+
return await withActiveSpan("visor.run", attrs, async (span) => {
|
|
1063
|
+
try {
|
|
1064
|
+
return await fn(span);
|
|
1065
|
+
} finally {
|
|
1066
|
+
try {
|
|
1067
|
+
span.setAttribute("visor.run.ai_calls", getRunAiCalls());
|
|
1068
|
+
span.setAttribute("visor.run.duration_ms", Date.now() - startMs);
|
|
1069
|
+
} catch {
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
});
|
|
1073
|
+
} catch (err) {
|
|
1074
|
+
success = false;
|
|
1075
|
+
throw err;
|
|
1076
|
+
} finally {
|
|
1077
|
+
recordRunAiCalls({
|
|
1078
|
+
source: runMeta.source,
|
|
1079
|
+
workflowId: runMeta.workflowId
|
|
1080
|
+
});
|
|
1081
|
+
recordRunDuration(Date.now() - startMs, {
|
|
1082
|
+
source: runMeta.source,
|
|
1083
|
+
userId: runMeta.userId,
|
|
1084
|
+
workflowId: runMeta.workflowId,
|
|
1085
|
+
success
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
function __getOrCreateNdjsonPath() {
|
|
1090
|
+
try {
|
|
1091
|
+
if (process.env.VISOR_TELEMETRY_SINK && process.env.VISOR_TELEMETRY_SINK !== "file")
|
|
1092
|
+
return null;
|
|
1093
|
+
const path4 = __require("path");
|
|
1094
|
+
const fs4 = __require("fs");
|
|
1095
|
+
if (process.env.VISOR_FALLBACK_TRACE_FILE) {
|
|
1096
|
+
__ndjsonPath = process.env.VISOR_FALLBACK_TRACE_FILE;
|
|
1097
|
+
const dir = path4.dirname(__ndjsonPath);
|
|
1098
|
+
if (!fs4.existsSync(dir)) fs4.mkdirSync(dir, { recursive: true });
|
|
1099
|
+
return __ndjsonPath;
|
|
1100
|
+
}
|
|
1101
|
+
const outDir = process.env.VISOR_TRACE_DIR || path4.join(process.cwd(), "output", "traces");
|
|
1102
|
+
if (!fs4.existsSync(outDir)) fs4.mkdirSync(outDir, { recursive: true });
|
|
1103
|
+
if (!__ndjsonPath) {
|
|
1104
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
1105
|
+
__ndjsonPath = path4.join(outDir, `${ts}.ndjson`);
|
|
1106
|
+
}
|
|
1107
|
+
return __ndjsonPath;
|
|
1108
|
+
} catch {
|
|
1109
|
+
return null;
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
function _appendRunMarker() {
|
|
1113
|
+
try {
|
|
1114
|
+
const fs4 = __require("fs");
|
|
1115
|
+
const p = __getOrCreateNdjsonPath();
|
|
1116
|
+
if (!p) return;
|
|
1117
|
+
const line = { name: "visor.run", attributes: { started: true } };
|
|
1118
|
+
fs4.appendFileSync(p, JSON.stringify(line) + "\n", "utf8");
|
|
1119
|
+
} catch {
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
var __ndjsonPath;
|
|
1123
|
+
var init_trace_helpers = __esm({
|
|
1124
|
+
"src/telemetry/trace-helpers.ts"() {
|
|
1125
|
+
init_lazy_otel();
|
|
1126
|
+
init_instance_id();
|
|
1127
|
+
__ndjsonPath = null;
|
|
1128
|
+
}
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
export {
|
|
1132
|
+
emitNdjsonFallback,
|
|
1133
|
+
emitNdjsonSpanWithEvents,
|
|
1134
|
+
emitNdjsonFullSpan,
|
|
1135
|
+
fallback_ndjson_exports,
|
|
1136
|
+
init_fallback_ndjson,
|
|
1137
|
+
getTracer,
|
|
1138
|
+
withActiveSpan,
|
|
1139
|
+
emitImmediateSpan,
|
|
1140
|
+
addEvent,
|
|
1141
|
+
setSpanAttributes,
|
|
1142
|
+
setSpanError,
|
|
1143
|
+
getVisorRunAttributes,
|
|
1144
|
+
withVisorRun,
|
|
1145
|
+
__getOrCreateNdjsonPath,
|
|
1146
|
+
_appendRunMarker,
|
|
1147
|
+
trace_helpers_exports,
|
|
1148
|
+
init_trace_helpers
|
|
1149
|
+
};
|
|
1150
|
+
//# sourceMappingURL=chunk-XOAEKFKB.mjs.map
|