autotel 2.24.1 → 2.25.1
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/auto.cjs +2 -2
- package/dist/auto.js +1 -1
- package/dist/{chunk-CSG2D3BZ.cjs → chunk-73SCHI7V.cjs} +7 -7
- package/dist/{chunk-CSG2D3BZ.cjs.map → chunk-73SCHI7V.cjs.map} +1 -1
- package/dist/{chunk-47KW5CV7.js → chunk-7RV6L24E.js} +4 -3
- package/dist/chunk-7RV6L24E.js.map +1 -0
- package/dist/{chunk-AXNPD6XW.cjs → chunk-7ZYUFMWU.cjs} +26 -26
- package/dist/{chunk-AXNPD6XW.cjs.map → chunk-7ZYUFMWU.cjs.map} +1 -1
- package/dist/{chunk-GSZJOYFF.js → chunk-BKIAH2YS.js} +3 -3
- package/dist/{chunk-GSZJOYFF.js.map → chunk-BKIAH2YS.js.map} +1 -1
- package/dist/{chunk-CLR5RQW4.cjs → chunk-DBUNRUDB.cjs} +5 -5
- package/dist/{chunk-CLR5RQW4.cjs.map → chunk-DBUNRUDB.cjs.map} +1 -1
- package/dist/{chunk-PDRIJURL.cjs → chunk-GIND746I.cjs} +4 -3
- package/dist/chunk-GIND746I.cjs.map +1 -0
- package/dist/{chunk-CZR7PJUZ.cjs → chunk-HCFBEOBM.cjs} +13 -13
- package/dist/{chunk-CZR7PJUZ.cjs.map → chunk-HCFBEOBM.cjs.map} +1 -1
- package/dist/{chunk-2D74YR4Z.js → chunk-JDV3LYOI.js} +3 -3
- package/dist/{chunk-2D74YR4Z.js.map → chunk-JDV3LYOI.js.map} +1 -1
- package/dist/{chunk-ZJTBAUXG.js → chunk-JZKMXKJX.js} +3 -3
- package/dist/{chunk-ZJTBAUXG.js.map → chunk-JZKMXKJX.js.map} +1 -1
- package/dist/{chunk-W6U2BUHU.cjs → chunk-LRFG6HRL.cjs} +5 -5
- package/dist/{chunk-W6U2BUHU.cjs.map → chunk-LRFG6HRL.cjs.map} +1 -1
- package/dist/{chunk-Z3BQYTZE.js → chunk-NYTCPK4J.js} +3 -3
- package/dist/{chunk-Z3BQYTZE.js.map → chunk-NYTCPK4J.js.map} +1 -1
- package/dist/{chunk-IJMW6CTV.js → chunk-P5YCN2Z3.js} +3 -3
- package/dist/{chunk-IJMW6CTV.js.map → chunk-P5YCN2Z3.js.map} +1 -1
- package/dist/decorators.cjs +2 -2
- package/dist/decorators.js +2 -2
- package/dist/event.cjs +5 -5
- package/dist/event.js +2 -2
- package/dist/functional.cjs +9 -9
- package/dist/functional.js +2 -2
- package/dist/index.cjs +41 -41
- package/dist/index.js +9 -9
- package/dist/instrumentation.cjs +8 -8
- package/dist/instrumentation.js +1 -1
- package/dist/messaging.cjs +6 -6
- package/dist/messaging.js +3 -3
- package/dist/semantic-helpers.cjs +7 -7
- package/dist/semantic-helpers.js +3 -3
- package/dist/test-span-collector.cjs +1 -0
- package/dist/test-span-collector.cjs.map +1 -1
- package/dist/test-span-collector.d.cts +2 -1
- package/dist/test-span-collector.d.ts +2 -1
- package/dist/test-span-collector.js +1 -1
- package/dist/test-span-collector.js.map +1 -1
- package/dist/webhook.cjs +3 -3
- package/dist/webhook.js +2 -2
- package/dist/workflow-distributed.cjs +4 -4
- package/dist/workflow-distributed.js +2 -2
- package/dist/workflow.cjs +7 -7
- package/dist/workflow.js +3 -3
- package/package.json +12 -10
- package/src/init.integrations.test.ts +14 -8
- package/src/init.openllmetry.test.ts +98 -193
- package/src/init.ts +18 -1
- package/src/test-span-collector.ts +1 -1
- package/dist/chunk-47KW5CV7.js.map +0 -1
- package/dist/chunk-PDRIJURL.cjs.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkINJD3G4K_cjs = require('./chunk-INJD3G4K.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunk7ZYUFMWU_cjs = require('./chunk-7ZYUFMWU.cjs');
|
|
5
5
|
require('./chunk-W4EUTSB2.cjs');
|
|
6
6
|
require('./chunk-GML3FBOT.cjs');
|
|
7
7
|
require('./chunk-D5LMF53P.cjs');
|
|
8
8
|
require('./chunk-XRKAL7WJ.cjs');
|
|
9
|
-
require('./chunk-
|
|
9
|
+
require('./chunk-GIND746I.cjs');
|
|
10
10
|
require('./chunk-6YIDHH2S.cjs');
|
|
11
11
|
require('./chunk-GVLK7YUU.cjs');
|
|
12
12
|
require('./chunk-ZNMBW67B.cjs');
|
|
@@ -59,7 +59,7 @@ var WorkflowBaggage = chunkINJD3G4K_cjs.createSafeBaggageSchema(workflowBaggageF
|
|
|
59
59
|
function traceDistributedWorkflow(config) {
|
|
60
60
|
const spanName = `workflow.${config.name}`;
|
|
61
61
|
return (fnFactory) => {
|
|
62
|
-
return
|
|
62
|
+
return chunk7ZYUFMWU_cjs.trace(
|
|
63
63
|
{ name: spanName, spanKind: api.SpanKind.INTERNAL },
|
|
64
64
|
(baseCtx) => {
|
|
65
65
|
return async (...args) => {
|
|
@@ -158,7 +158,7 @@ function traceDistributedWorkflow(config) {
|
|
|
158
158
|
function traceDistributedStep(config) {
|
|
159
159
|
const spanName = `workflow.step.${config.name}`;
|
|
160
160
|
return (fnFactory) => {
|
|
161
|
-
return
|
|
161
|
+
return chunk7ZYUFMWU_cjs.trace(
|
|
162
162
|
{ name: spanName, spanKind: api.SpanKind.INTERNAL },
|
|
163
163
|
(baseCtx) => {
|
|
164
164
|
return async (...args) => {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createSafeBaggageSchema } from './chunk-4IFSYQVX.js';
|
|
2
|
-
import { trace } from './chunk-
|
|
2
|
+
import { trace } from './chunk-JDV3LYOI.js';
|
|
3
3
|
import './chunk-SR35DG5A.js';
|
|
4
4
|
import './chunk-B3ZHLLMP.js';
|
|
5
5
|
import './chunk-WD4RP6IV.js';
|
|
6
6
|
import './chunk-USSL3D6L.js';
|
|
7
|
-
import './chunk-
|
|
7
|
+
import './chunk-7RV6L24E.js';
|
|
8
8
|
import './chunk-YTGF4L2C.js';
|
|
9
9
|
import './chunk-X4RMFFMR.js';
|
|
10
10
|
import './chunk-WGWSHJ2N.js';
|
package/dist/workflow.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
3
|
+
var chunkDBUNRUDB_cjs = require('./chunk-DBUNRUDB.cjs');
|
|
4
|
+
require('./chunk-7ZYUFMWU.cjs');
|
|
5
5
|
require('./chunk-W4EUTSB2.cjs');
|
|
6
6
|
require('./chunk-GML3FBOT.cjs');
|
|
7
7
|
require('./chunk-D5LMF53P.cjs');
|
|
8
8
|
require('./chunk-XRKAL7WJ.cjs');
|
|
9
|
-
require('./chunk-
|
|
9
|
+
require('./chunk-GIND746I.cjs');
|
|
10
10
|
require('./chunk-6YIDHH2S.cjs');
|
|
11
11
|
require('./chunk-GVLK7YUU.cjs');
|
|
12
12
|
require('./chunk-ZNMBW67B.cjs');
|
|
@@ -25,19 +25,19 @@ require('./chunk-JEQ2X3Z6.cjs');
|
|
|
25
25
|
|
|
26
26
|
Object.defineProperty(exports, "getCurrentWorkflowContext", {
|
|
27
27
|
enumerable: true,
|
|
28
|
-
get: function () { return
|
|
28
|
+
get: function () { return chunkDBUNRUDB_cjs.getCurrentWorkflowContext; }
|
|
29
29
|
});
|
|
30
30
|
Object.defineProperty(exports, "isInWorkflow", {
|
|
31
31
|
enumerable: true,
|
|
32
|
-
get: function () { return
|
|
32
|
+
get: function () { return chunkDBUNRUDB_cjs.isInWorkflow; }
|
|
33
33
|
});
|
|
34
34
|
Object.defineProperty(exports, "traceStep", {
|
|
35
35
|
enumerable: true,
|
|
36
|
-
get: function () { return
|
|
36
|
+
get: function () { return chunkDBUNRUDB_cjs.traceStep; }
|
|
37
37
|
});
|
|
38
38
|
Object.defineProperty(exports, "traceWorkflow", {
|
|
39
39
|
enumerable: true,
|
|
40
|
-
get: function () { return
|
|
40
|
+
get: function () { return chunkDBUNRUDB_cjs.traceWorkflow; }
|
|
41
41
|
});
|
|
42
42
|
//# sourceMappingURL=workflow.cjs.map
|
|
43
43
|
//# sourceMappingURL=workflow.cjs.map
|
package/dist/workflow.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow } from './chunk-P5YCN2Z3.js';
|
|
2
|
+
import './chunk-JDV3LYOI.js';
|
|
3
3
|
import './chunk-SR35DG5A.js';
|
|
4
4
|
import './chunk-B3ZHLLMP.js';
|
|
5
5
|
import './chunk-WD4RP6IV.js';
|
|
6
6
|
import './chunk-USSL3D6L.js';
|
|
7
|
-
import './chunk-
|
|
7
|
+
import './chunk-7RV6L24E.js';
|
|
8
8
|
import './chunk-YTGF4L2C.js';
|
|
9
9
|
import './chunk-X4RMFFMR.js';
|
|
10
10
|
import './chunk-WGWSHJ2N.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.25.1",
|
|
4
4
|
"description": "Write Once, Observe Anywhere",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -139,11 +139,13 @@
|
|
|
139
139
|
},
|
|
140
140
|
"./register": {
|
|
141
141
|
"types": "./dist/register.d.ts",
|
|
142
|
-
"import": "./dist/register.js"
|
|
142
|
+
"import": "./dist/register.js",
|
|
143
|
+
"require": "./dist/register.cjs"
|
|
143
144
|
},
|
|
144
145
|
"./auto": {
|
|
145
146
|
"types": "./dist/auto.d.ts",
|
|
146
|
-
"import": "./dist/auto.js"
|
|
147
|
+
"import": "./dist/auto.js",
|
|
148
|
+
"require": "./dist/auto.cjs"
|
|
147
149
|
},
|
|
148
150
|
"./hook.mjs": {
|
|
149
151
|
"import": "./src/hook.mjs"
|
|
@@ -257,7 +259,7 @@
|
|
|
257
259
|
"@opentelemetry/sdk-node": "^0.213.0",
|
|
258
260
|
"@opentelemetry/sdk-trace-base": "^2.6.0",
|
|
259
261
|
"@opentelemetry/semantic-conventions": "^1.40.0",
|
|
260
|
-
"@tanstack/intent": "^0.0.
|
|
262
|
+
"@tanstack/intent": "^0.0.23",
|
|
261
263
|
"import-in-the-middle": "^3.0.0"
|
|
262
264
|
},
|
|
263
265
|
"peerDependencies": {
|
|
@@ -274,7 +276,7 @@
|
|
|
274
276
|
"@traceloop/node-server-sdk": "^0.22.8",
|
|
275
277
|
"pino": "^10.3.1",
|
|
276
278
|
"pino-pretty": "^13.1.3",
|
|
277
|
-
"yaml": "^2.8.
|
|
279
|
+
"yaml": "^2.8.3"
|
|
278
280
|
},
|
|
279
281
|
"peerDependenciesMeta": {
|
|
280
282
|
"@opentelemetry/auto-instrumentations-node": {
|
|
@@ -334,13 +336,13 @@
|
|
|
334
336
|
"@opentelemetry/resource-detector-gcp": "^0.48.0",
|
|
335
337
|
"@opentelemetry/sdk-logs": "^0.213.0",
|
|
336
338
|
"@opentelemetry/sdk-trace-node": "^2.6.0",
|
|
337
|
-
"@swc/core": "^1.15.
|
|
339
|
+
"@swc/core": "^1.15.21",
|
|
338
340
|
"@total-typescript/ts-reset": "^0.6.1",
|
|
339
341
|
"@total-typescript/tsconfig": "^1.0.4",
|
|
340
342
|
"@types/eslint-config-prettier": "^6.11.3",
|
|
341
343
|
"@types/node": "^25.5.0",
|
|
342
|
-
"@typescript-eslint/eslint-plugin": "^8.57.
|
|
343
|
-
"@typescript-eslint/parser": "^8.57.
|
|
344
|
+
"@typescript-eslint/eslint-plugin": "^8.57.1",
|
|
345
|
+
"@typescript-eslint/parser": "^8.57.1",
|
|
344
346
|
"eslint-config-prettier": "^10.1.8",
|
|
345
347
|
"eslint-plugin-unicorn": "^63.0.0",
|
|
346
348
|
"pino": "^10.3.1",
|
|
@@ -349,13 +351,13 @@
|
|
|
349
351
|
"tsup": "^8.5.1",
|
|
350
352
|
"tsx": "^4.21.0",
|
|
351
353
|
"typescript": "^5.9.3",
|
|
352
|
-
"typescript-eslint": "^8.57.
|
|
354
|
+
"typescript-eslint": "^8.57.1",
|
|
353
355
|
"unplugin-swc": "^1.5.9",
|
|
354
356
|
"vite-tsconfig-paths": "^6.1.1",
|
|
355
357
|
"vitest": "^4.1.0",
|
|
356
358
|
"vitest-mock-extended": "^3.1.0",
|
|
357
359
|
"winston": "^3.19.0",
|
|
358
|
-
"yaml": "^2.8.
|
|
360
|
+
"yaml": "^2.8.3"
|
|
359
361
|
},
|
|
360
362
|
"repository": {
|
|
361
363
|
"type": "git",
|
|
@@ -20,18 +20,24 @@ const mockedModules = [
|
|
|
20
20
|
'@opentelemetry/sdk-metrics',
|
|
21
21
|
];
|
|
22
22
|
|
|
23
|
-
// Mock instrumentation classes with exact names from OpenTelemetry
|
|
24
|
-
|
|
23
|
+
// Mock instrumentation classes with exact names from OpenTelemetry.
|
|
24
|
+
// NodeSDK.start() calls lifecycle hooks on each instrumentation instance.
|
|
25
|
+
class MockInstrumentationBase {
|
|
25
26
|
constructor(public config?: Record<string, unknown>) {}
|
|
26
|
-
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
setConfig(_config: Record<string, unknown>) {}
|
|
29
|
+
setTracerProvider(_provider: unknown) {}
|
|
30
|
+
setMeterProvider(_provider: unknown) {}
|
|
31
|
+
setLoggerProvider(_provider: unknown) {}
|
|
32
|
+
enable() {}
|
|
33
|
+
disable() {}
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
class
|
|
33
|
-
|
|
34
|
-
}
|
|
36
|
+
class MongoDBInstrumentation extends MockInstrumentationBase {}
|
|
37
|
+
|
|
38
|
+
class MongooseInstrumentation extends MockInstrumentationBase {}
|
|
39
|
+
|
|
40
|
+
class HttpInstrumentation extends MockInstrumentationBase {}
|
|
35
41
|
|
|
36
42
|
async function loadInitWithMocks() {
|
|
37
43
|
const sdkInstances: SdkRecord[] = [];
|
|
@@ -1,138 +1,36 @@
|
|
|
1
|
-
import { afterEach,
|
|
2
|
-
import type { NodeSDK } from '@opentelemetry/sdk-node';
|
|
3
|
-
import { mock, mockDeep, type DeepMockProxy } from 'vitest-mock-extended';
|
|
4
|
-
|
|
5
|
-
type SdkRecord = {
|
|
6
|
-
options: Record<string, unknown>;
|
|
7
|
-
instance: DeepMockProxy<NodeSDK>;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const mockedModules = [
|
|
11
|
-
'@opentelemetry/sdk-node',
|
|
12
|
-
'@opentelemetry/exporter-trace-otlp-http',
|
|
13
|
-
'@opentelemetry/exporter-metrics-otlp-http',
|
|
14
|
-
'@opentelemetry/sdk-metrics',
|
|
15
|
-
'./node-require',
|
|
16
|
-
'./node-require.ts',
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
// Track traceloop initialize calls globally
|
|
20
|
-
const traceloopInitializeCalls: Array<Record<string, unknown>> = [];
|
|
21
|
-
|
|
22
|
-
// Store mock initialize function globally
|
|
23
|
-
let globalMockInitialize: ReturnType<typeof vi.fn> | null = null;
|
|
24
|
-
|
|
25
|
-
async function loadInitWithMocks() {
|
|
26
|
-
const sdkInstances: SdkRecord[] = [];
|
|
27
|
-
|
|
28
|
-
class MockNodeSDK {
|
|
29
|
-
constructor(options: Record<string, unknown>) {
|
|
30
|
-
const instance = mockDeep<NodeSDK>();
|
|
31
|
-
instance.start.mockImplementation(() => {});
|
|
32
|
-
instance.shutdown.mockResolvedValue();
|
|
33
|
-
|
|
34
|
-
(instance as any).getTracerProvider = vi.fn().mockReturnValue(mock());
|
|
35
|
-
sdkInstances.push({ options, instance });
|
|
36
|
-
return instance;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
class MockOTLPTraceExporter {
|
|
41
|
-
options: Record<string, unknown>;
|
|
42
|
-
|
|
43
|
-
constructor(options: Record<string, unknown>) {
|
|
44
|
-
this.options = options;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
class MockOTLPMetricExporter {
|
|
49
|
-
options: Record<string, unknown>;
|
|
50
|
-
|
|
51
|
-
constructor(options: Record<string, unknown>) {
|
|
52
|
-
this.options = options;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
class MockPeriodicExportingMetricReader {
|
|
57
|
-
options: Record<string, unknown>;
|
|
58
|
-
|
|
59
|
-
constructor(options: Record<string, unknown>) {
|
|
60
|
-
this.options = options;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Clear module cache first
|
|
65
|
-
vi.resetModules();
|
|
66
|
-
|
|
67
|
-
// Create mock function that captures calls and store it globally
|
|
68
|
-
globalMockInitialize = vi.fn((options?: Record<string, unknown>) => {
|
|
69
|
-
traceloopInitializeCalls.push(options || {});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const mockTraceloop = {
|
|
73
|
-
initialize: globalMockInitialize,
|
|
74
|
-
instrumentations: [{ name: 'openai' }, { name: 'langchain' }],
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// Mock node-require to intercept safeRequire('@traceloop/node-server-sdk').
|
|
78
|
-
// vi.doMock on the traceloop module itself doesn't work because safeRequire
|
|
79
|
-
// uses native require() which bypasses vitest's module interception.
|
|
80
|
-
const nodeRequireMock = () => ({
|
|
81
|
-
safeRequire: vi.fn((id: string) => {
|
|
82
|
-
if (id === '@traceloop/node-server-sdk') {
|
|
83
|
-
return mockTraceloop;
|
|
84
|
-
}
|
|
85
|
-
return undefined;
|
|
86
|
-
}),
|
|
87
|
-
requireModule: vi.fn((id: string) => {
|
|
88
|
-
const err = new Error(`Cannot find module '${id}'`);
|
|
89
|
-
(err as NodeJS.ErrnoException).code = 'MODULE_NOT_FOUND';
|
|
90
|
-
throw err;
|
|
91
|
-
}),
|
|
92
|
-
nodeRequire: vi.fn(),
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
vi.doMock('./node-require', nodeRequireMock);
|
|
96
|
-
vi.doMock('./node-require.ts', nodeRequireMock);
|
|
97
|
-
|
|
98
|
-
vi.doMock('@opentelemetry/sdk-node', () => ({
|
|
99
|
-
NodeSDK: MockNodeSDK,
|
|
100
|
-
}));
|
|
101
|
-
|
|
102
|
-
vi.doMock('@opentelemetry/exporter-trace-otlp-http', () => ({
|
|
103
|
-
OTLPTraceExporter: MockOTLPTraceExporter,
|
|
104
|
-
}));
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
105
2
|
|
|
106
|
-
|
|
107
|
-
OTLPMetricExporter: MockOTLPMetricExporter,
|
|
108
|
-
}));
|
|
3
|
+
type InitModule = typeof import('./init');
|
|
109
4
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
5
|
+
async function loadInitModule(): Promise<InitModule> {
|
|
6
|
+
vi.resetModules();
|
|
7
|
+
return import('./init');
|
|
8
|
+
}
|
|
113
9
|
|
|
114
|
-
|
|
10
|
+
function createSdkFactory() {
|
|
11
|
+
const calls: Array<Record<string, unknown>> = [];
|
|
12
|
+
const getTracerProvider = vi.fn(() => ({ id: 'mock-tracer-provider' }));
|
|
13
|
+
const start = vi.fn();
|
|
14
|
+
const shutdown = vi.fn(async () => {});
|
|
115
15
|
|
|
116
16
|
return {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
17
|
+
calls,
|
|
18
|
+
getTracerProvider,
|
|
19
|
+
start,
|
|
20
|
+
shutdown,
|
|
21
|
+
sdkFactory: (options: Record<string, unknown>) => {
|
|
22
|
+
calls.push(options);
|
|
23
|
+
return {
|
|
24
|
+
start,
|
|
25
|
+
shutdown,
|
|
26
|
+
getTracerProvider,
|
|
27
|
+
} as never;
|
|
28
|
+
},
|
|
122
29
|
};
|
|
123
30
|
}
|
|
124
31
|
|
|
125
32
|
describe('init() OpenLLMetry integration', () => {
|
|
126
|
-
beforeEach(() => {
|
|
127
|
-
vi.resetModules();
|
|
128
|
-
traceloopInitializeCalls.length = 0;
|
|
129
|
-
globalMockInitialize = null;
|
|
130
|
-
});
|
|
131
|
-
|
|
132
33
|
afterEach(() => {
|
|
133
|
-
for (const mod of mockedModules) {
|
|
134
|
-
vi.doUnmock(mod);
|
|
135
|
-
}
|
|
136
34
|
vi.clearAllMocks();
|
|
137
35
|
delete process.env.AUTOTEL_METRICS;
|
|
138
36
|
delete process.env.NODE_ENV;
|
|
@@ -140,29 +38,53 @@ describe('init() OpenLLMetry integration', () => {
|
|
|
140
38
|
});
|
|
141
39
|
|
|
142
40
|
it('should not initialize OpenLLMetry when disabled', async () => {
|
|
143
|
-
const
|
|
41
|
+
const mod = await loadInitModule();
|
|
42
|
+
const sdk = createSdkFactory();
|
|
43
|
+
const traceloopInitializeCalls: Array<Record<string, unknown>> = [];
|
|
44
|
+
|
|
45
|
+
mod._setOptionalRequireForTesting(() => ({
|
|
46
|
+
initialize: (options?: Record<string, unknown>) =>
|
|
47
|
+
traceloopInitializeCalls.push(options ?? {}),
|
|
48
|
+
}));
|
|
144
49
|
|
|
145
|
-
init({ service: 'test-app' });
|
|
50
|
+
mod.init({ service: 'test-app', sdkFactory: sdk.sdkFactory });
|
|
146
51
|
|
|
147
52
|
expect(traceloopInitializeCalls).toHaveLength(0);
|
|
53
|
+
mod._resetOptionalRequireForTesting();
|
|
148
54
|
});
|
|
149
55
|
|
|
150
56
|
it('should initialize OpenLLMetry when enabled', async () => {
|
|
151
|
-
const
|
|
57
|
+
const mod = await loadInitModule();
|
|
58
|
+
const sdk = createSdkFactory();
|
|
59
|
+
const traceloopInitializeCalls: Array<Record<string, unknown>> = [];
|
|
60
|
+
|
|
61
|
+
mod._setOptionalRequireForTesting(() => ({
|
|
62
|
+
initialize: (options?: Record<string, unknown>) =>
|
|
63
|
+
traceloopInitializeCalls.push(options ?? {}),
|
|
64
|
+
}));
|
|
152
65
|
|
|
153
|
-
init({
|
|
66
|
+
mod.init({
|
|
154
67
|
service: 'test-app',
|
|
155
68
|
openllmetry: { enabled: true },
|
|
69
|
+
sdkFactory: sdk.sdkFactory,
|
|
156
70
|
});
|
|
157
71
|
|
|
158
72
|
expect(traceloopInitializeCalls).toHaveLength(1);
|
|
159
73
|
expect(traceloopInitializeCalls[0]).toBeDefined();
|
|
74
|
+
mod._resetOptionalRequireForTesting();
|
|
160
75
|
});
|
|
161
76
|
|
|
162
77
|
it('should pass OpenLLMetry options to initialize', async () => {
|
|
163
|
-
const
|
|
78
|
+
const mod = await loadInitModule();
|
|
79
|
+
const sdk = createSdkFactory();
|
|
80
|
+
const traceloopInitializeCalls: Array<Record<string, unknown>> = [];
|
|
81
|
+
|
|
82
|
+
mod._setOptionalRequireForTesting(() => ({
|
|
83
|
+
initialize: (options?: Record<string, unknown>) =>
|
|
84
|
+
traceloopInitializeCalls.push(options ?? {}),
|
|
85
|
+
}));
|
|
164
86
|
|
|
165
|
-
init({
|
|
87
|
+
mod.init({
|
|
166
88
|
service: 'test-app',
|
|
167
89
|
openllmetry: {
|
|
168
90
|
enabled: true,
|
|
@@ -171,6 +93,7 @@ describe('init() OpenLLMetry integration', () => {
|
|
|
171
93
|
apiKey: 'test-key',
|
|
172
94
|
},
|
|
173
95
|
},
|
|
96
|
+
sdkFactory: sdk.sdkFactory,
|
|
174
97
|
});
|
|
175
98
|
|
|
176
99
|
expect(traceloopInitializeCalls).toHaveLength(1);
|
|
@@ -178,112 +101,94 @@ describe('init() OpenLLMetry integration', () => {
|
|
|
178
101
|
disableBatch: true,
|
|
179
102
|
apiKey: 'test-key',
|
|
180
103
|
});
|
|
104
|
+
mod._resetOptionalRequireForTesting();
|
|
181
105
|
});
|
|
182
106
|
|
|
183
107
|
it('should reuse autotel tracer provider when OpenLLMetry is enabled', async () => {
|
|
184
|
-
const
|
|
185
|
-
|
|
108
|
+
const mod = await loadInitModule();
|
|
109
|
+
const sdk = createSdkFactory();
|
|
110
|
+
const traceloopInitializeCalls: Array<Record<string, unknown>> = [];
|
|
186
111
|
|
|
187
|
-
|
|
112
|
+
mod._setOptionalRequireForTesting(() => ({
|
|
113
|
+
initialize: (options?: Record<string, unknown>) =>
|
|
114
|
+
traceloopInitializeCalls.push(options ?? {}),
|
|
115
|
+
}));
|
|
116
|
+
|
|
117
|
+
mod.init({
|
|
188
118
|
service: 'test-app',
|
|
189
119
|
openllmetry: { enabled: true },
|
|
120
|
+
sdkFactory: sdk.sdkFactory,
|
|
190
121
|
});
|
|
191
122
|
|
|
192
|
-
expect(sdkInstances).toHaveLength(1);
|
|
193
|
-
const sdkInstance = sdkInstances[0].instance;
|
|
194
|
-
|
|
195
123
|
expect(traceloopInitializeCalls).toHaveLength(1);
|
|
196
124
|
const callOptions = traceloopInitializeCalls[0];
|
|
197
125
|
expect(callOptions).toBeDefined();
|
|
198
|
-
expect(
|
|
126
|
+
expect(sdk.getTracerProvider).toHaveBeenCalled();
|
|
127
|
+
mod._resetOptionalRequireForTesting();
|
|
199
128
|
});
|
|
200
129
|
|
|
201
130
|
it('should add OpenLLMetry instrumentations when selectiveInstrumentation is false', async () => {
|
|
202
|
-
const
|
|
131
|
+
const mod = await loadInitModule();
|
|
132
|
+
const sdk = createSdkFactory();
|
|
133
|
+
const mockTraceloop = {
|
|
134
|
+
initialize: vi.fn(),
|
|
135
|
+
instrumentations: [{ name: 'openai' }, { name: 'langchain' }],
|
|
136
|
+
};
|
|
203
137
|
|
|
204
|
-
|
|
138
|
+
mod._setOptionalRequireForTesting(() => mockTraceloop);
|
|
139
|
+
|
|
140
|
+
mod.init({
|
|
205
141
|
service: 'test-app',
|
|
206
142
|
openllmetry: { enabled: true },
|
|
207
143
|
autoInstrumentations: false,
|
|
144
|
+
sdkFactory: sdk.sdkFactory,
|
|
208
145
|
});
|
|
209
146
|
|
|
210
|
-
const options =
|
|
147
|
+
const options = sdk.calls.at(-1) as Record<string, unknown>;
|
|
211
148
|
const instrumentations = options.instrumentations as unknown[];
|
|
212
149
|
|
|
213
150
|
expect(instrumentations).toBeDefined();
|
|
214
151
|
expect(mockTraceloop.instrumentations).toBeDefined();
|
|
152
|
+
mod._resetOptionalRequireForTesting();
|
|
215
153
|
});
|
|
216
154
|
|
|
217
155
|
it('should handle missing @traceloop/node-server-sdk gracefully', async () => {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const nodeRequireMock = () => ({
|
|
222
|
-
safeRequire: vi.fn(() => undefined),
|
|
223
|
-
requireModule: vi.fn((id: string) => {
|
|
224
|
-
const err = new Error(`Cannot find module '${id}'`);
|
|
225
|
-
(err as NodeJS.ErrnoException).code = 'MODULE_NOT_FOUND';
|
|
226
|
-
throw err;
|
|
227
|
-
}),
|
|
228
|
-
nodeRequire: vi.fn(),
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
vi.doMock('./node-require', nodeRequireMock);
|
|
232
|
-
vi.doMock('./node-require.ts', nodeRequireMock);
|
|
233
|
-
|
|
234
|
-
vi.doMock('@opentelemetry/sdk-node', () => ({
|
|
235
|
-
NodeSDK: class {
|
|
236
|
-
constructor() {
|
|
237
|
-
const instance = mockDeep<NodeSDK>();
|
|
238
|
-
instance.start.mockImplementation(() => {});
|
|
239
|
-
instance.shutdown.mockResolvedValue();
|
|
240
|
-
return instance;
|
|
241
|
-
}
|
|
242
|
-
},
|
|
243
|
-
}));
|
|
244
|
-
|
|
245
|
-
vi.doMock('@opentelemetry/exporter-trace-otlp-http', () => ({
|
|
246
|
-
OTLPTraceExporter: class {
|
|
247
|
-
constructor() {}
|
|
248
|
-
},
|
|
249
|
-
}));
|
|
250
|
-
|
|
251
|
-
vi.doMock('@opentelemetry/exporter-metrics-otlp-http', () => ({
|
|
252
|
-
OTLPMetricExporter: class {
|
|
253
|
-
constructor() {}
|
|
254
|
-
},
|
|
255
|
-
}));
|
|
256
|
-
|
|
257
|
-
vi.doMock('@opentelemetry/sdk-metrics', () => ({
|
|
258
|
-
PeriodicExportingMetricReader: class {
|
|
259
|
-
constructor() {}
|
|
260
|
-
},
|
|
261
|
-
}));
|
|
262
|
-
|
|
263
|
-
const { init } = await import('./init');
|
|
156
|
+
const mod = await loadInitModule();
|
|
157
|
+
const sdk = createSdkFactory();
|
|
158
|
+
mod._setOptionalRequireForTesting(() => undefined);
|
|
264
159
|
|
|
265
160
|
expect(() => {
|
|
266
|
-
init({
|
|
161
|
+
mod.init({
|
|
267
162
|
service: 'test-app',
|
|
268
163
|
openllmetry: { enabled: true },
|
|
164
|
+
sdkFactory: sdk.sdkFactory,
|
|
269
165
|
});
|
|
270
166
|
}).not.toThrow();
|
|
167
|
+
mod._resetOptionalRequireForTesting();
|
|
271
168
|
});
|
|
272
169
|
|
|
273
170
|
it('should initialize OpenLLMetry after SDK start', async () => {
|
|
274
|
-
const
|
|
275
|
-
|
|
171
|
+
const mod = await loadInitModule();
|
|
172
|
+
const sdk = createSdkFactory();
|
|
173
|
+
const traceloopInitializeCalls: Array<Record<string, unknown>> = [];
|
|
174
|
+
|
|
175
|
+
mod._setOptionalRequireForTesting(() => ({
|
|
176
|
+
initialize: (options?: Record<string, unknown>) =>
|
|
177
|
+
traceloopInitializeCalls.push(options ?? {}),
|
|
178
|
+
}));
|
|
276
179
|
|
|
277
|
-
init({
|
|
180
|
+
mod.init({
|
|
278
181
|
service: 'test-app',
|
|
279
182
|
openllmetry: { enabled: true },
|
|
183
|
+
sdkFactory: sdk.sdkFactory,
|
|
280
184
|
});
|
|
281
185
|
|
|
282
186
|
// Verify SDK started (synchronously in init)
|
|
283
|
-
expect(
|
|
284
|
-
expect(
|
|
187
|
+
expect(sdk.calls).toHaveLength(1);
|
|
188
|
+
expect(sdk.start).toHaveBeenCalled();
|
|
285
189
|
|
|
286
190
|
// Verify OpenLLMetry was initialized (synchronously via safeRequire)
|
|
287
191
|
expect(traceloopInitializeCalls).toHaveLength(1);
|
|
192
|
+
mod._resetOptionalRequireForTesting();
|
|
288
193
|
});
|
|
289
194
|
});
|
package/src/init.ts
CHANGED
|
@@ -1022,6 +1022,7 @@ let logger: Logger = silentLogger; // Silent by default - no spam
|
|
|
1022
1022
|
let validationConfig: Partial<ValidationConfig> | null = null;
|
|
1023
1023
|
let eventsConfig: EventsConfig | null = null;
|
|
1024
1024
|
let _stringRedactor: StringRedactor | null = null;
|
|
1025
|
+
let _optionalRequire: typeof safeRequire = safeRequire;
|
|
1025
1026
|
|
|
1026
1027
|
/**
|
|
1027
1028
|
* Resolve metrics flag with env var override support
|
|
@@ -1471,7 +1472,7 @@ export function init(cfg: AutotelConfig): void {
|
|
|
1471
1472
|
|
|
1472
1473
|
// Initialize OpenLLMetry if enabled (after SDK starts to reuse tracer provider)
|
|
1473
1474
|
if (mergedConfig.openllmetry?.enabled) {
|
|
1474
|
-
const traceloop =
|
|
1475
|
+
const traceloop = _optionalRequire<{
|
|
1475
1476
|
initialize?: (options?: Record<string, unknown>) => void;
|
|
1476
1477
|
}>('@traceloop/node-server-sdk');
|
|
1477
1478
|
|
|
@@ -1833,6 +1834,22 @@ export function getStringRedactor(): StringRedactor | null {
|
|
|
1833
1834
|
return _stringRedactor;
|
|
1834
1835
|
}
|
|
1835
1836
|
|
|
1837
|
+
/**
|
|
1838
|
+
* @internal Override optional require for deterministic tests.
|
|
1839
|
+
*/
|
|
1840
|
+
export function _setOptionalRequireForTesting(
|
|
1841
|
+
loader: typeof safeRequire,
|
|
1842
|
+
): void {
|
|
1843
|
+
_optionalRequire = loader;
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
/**
|
|
1847
|
+
* @internal Reset optional require override.
|
|
1848
|
+
*/
|
|
1849
|
+
export function _resetOptionalRequireForTesting(): void {
|
|
1850
|
+
_optionalRequire = safeRequire;
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1836
1853
|
/**
|
|
1837
1854
|
* Get SDK instance (for shutdown)
|
|
1838
1855
|
*/
|
|
@@ -124,7 +124,7 @@ function isSerializable(v: unknown): v is SerializableValue {
|
|
|
124
124
|
return false;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
function serializeSpan(span: ReadableSpan): SerializedSpan {
|
|
127
|
+
export function serializeSpan(span: ReadableSpan): SerializedSpan {
|
|
128
128
|
const attrs: Record<string, SerializableValue> = {};
|
|
129
129
|
for (const [k, v] of Object.entries(span.attributes)) {
|
|
130
130
|
if (isSerializable(v)) attrs[k] = v;
|