@powerhousedao/switchboard 6.0.0-dev.95 → 6.0.0-dev.96
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/CHANGELOG.md +11 -0
- package/dist/src/index.js +7 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/metrics.d.ts +5 -1
- package/dist/src/metrics.d.ts.map +1 -1
- package/dist/src/metrics.js +6 -7
- package/dist/src/metrics.js.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +8 -0
- package/dist/src/server.js.map +1 -1
- package/dist/src/types.d.ts +8 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/test/metrics.test.d.ts +2 -0
- package/dist/test/metrics.test.d.ts.map +1 -0
- package/dist/test/metrics.test.js +121 -0
- package/dist/test/metrics.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +15 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +11 -9
- package/test/metrics.test.ts +202 -0
- package/vitest.config.ts +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.config.d.ts","sourceRoot":"","sources":["../vitest.config.ts"],"names":[],"mappings":";AAEA,wBAYG"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config";
|
|
2
|
+
export default defineConfig({
|
|
3
|
+
test: {
|
|
4
|
+
pool: "forks",
|
|
5
|
+
environment: "node",
|
|
6
|
+
poolOptions: {
|
|
7
|
+
forks: {
|
|
8
|
+
singleFork: true,
|
|
9
|
+
isolate: true,
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
include: ["test/**/*.test.ts"],
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=vitest.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.config.js","sourceRoot":"","sources":["../vitest.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE;QACJ,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,MAAM;QACnB,WAAW,EAAE;YACX,KAAK,EAAE;gBACL,UAAU,EAAE,IAAI;gBAChB,OAAO,EAAE,IAAI;aACd;SACF;QACD,OAAO,EAAE,CAAC,mBAAmB,CAAC;KAC/B;CACF,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/switchboard",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "6.0.0-dev.
|
|
4
|
+
"version": "6.0.0-dev.96",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -47,23 +47,25 @@
|
|
|
47
47
|
"kysely-pglite-dialect": "1.2.0",
|
|
48
48
|
"pg": "8.18.0",
|
|
49
49
|
"redis": "^4.7.0",
|
|
50
|
-
"@powerhousedao/
|
|
51
|
-
"@powerhousedao/reactor
|
|
52
|
-
"@powerhousedao/
|
|
53
|
-
"@powerhousedao/reactor": "6.0.0-dev.
|
|
54
|
-
"@renown/sdk": "6.0.0-dev.
|
|
55
|
-
"document-drive": "6.0.0-dev.
|
|
56
|
-
"document-model": "6.0.0-dev.
|
|
50
|
+
"@powerhousedao/config": "6.0.0-dev.96",
|
|
51
|
+
"@powerhousedao/opentelemetry-instrumentation-reactor": "6.0.0-dev.96",
|
|
52
|
+
"@powerhousedao/reactor": "6.0.0-dev.96",
|
|
53
|
+
"@powerhousedao/reactor-api": "6.0.0-dev.96",
|
|
54
|
+
"@renown/sdk": "6.0.0-dev.96",
|
|
55
|
+
"document-drive": "6.0.0-dev.96",
|
|
56
|
+
"document-model": "6.0.0-dev.96"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@types/express": "^4.17.25",
|
|
60
60
|
"@types/node": "25.2.3",
|
|
61
61
|
"@types/pg": "8.16.0",
|
|
62
62
|
"concurrently": "9.2.1",
|
|
63
|
-
"nodemon": "3.1.11"
|
|
63
|
+
"nodemon": "3.1.11",
|
|
64
|
+
"vitest": "3.2.4"
|
|
64
65
|
},
|
|
65
66
|
"scripts": {
|
|
66
67
|
"tsc": "tsc",
|
|
68
|
+
"test": "vitest run",
|
|
67
69
|
"lint": "eslint",
|
|
68
70
|
"build:misc": "pnpm run install-packages",
|
|
69
71
|
"start": "node dist/src/index.js",
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { MeterProvider } from "@opentelemetry/sdk-metrics";
|
|
2
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
import { createMeterProviderFromEnv } from "../src/metrics.js";
|
|
4
|
+
|
|
5
|
+
// Stub childLogger so tests don't require the full document-drive runtime
|
|
6
|
+
vi.mock("document-drive", () => ({
|
|
7
|
+
childLogger: () => ({
|
|
8
|
+
info: vi.fn(),
|
|
9
|
+
warn: vi.fn(),
|
|
10
|
+
error: vi.fn(),
|
|
11
|
+
}),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
const providers: MeterProvider[] = [];
|
|
15
|
+
|
|
16
|
+
afterEach(async () => {
|
|
17
|
+
vi.restoreAllMocks();
|
|
18
|
+
// Await shutdown so PeriodicExportingMetricReader timers are cleared
|
|
19
|
+
await Promise.all(providers.map((p) => p.shutdown()));
|
|
20
|
+
providers.length = 0;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
function track(provider: MeterProvider | undefined): MeterProvider | undefined {
|
|
24
|
+
if (provider) providers.push(provider);
|
|
25
|
+
return provider;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function trackAsserted(provider: MeterProvider | undefined): MeterProvider {
|
|
29
|
+
expect(provider).toBeInstanceOf(MeterProvider);
|
|
30
|
+
return track(provider) as MeterProvider;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// These helpers access undocumented internal fields of MeterProvider and
|
|
34
|
+
// PeriodicExportingMetricReader. They may break if @opentelemetry/sdk-metrics
|
|
35
|
+
// renames its private state between major versions.
|
|
36
|
+
function getReader(provider: MeterProvider): {
|
|
37
|
+
_exportInterval: number;
|
|
38
|
+
_exportTimeout: number;
|
|
39
|
+
} {
|
|
40
|
+
return (
|
|
41
|
+
provider as unknown as {
|
|
42
|
+
_sharedState: {
|
|
43
|
+
metricCollectors: Array<{
|
|
44
|
+
_metricReader: { _exportInterval: number; _exportTimeout: number };
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
)._sharedState.metricCollectors[0]._metricReader;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getExporterUrl(provider: MeterProvider): string {
|
|
52
|
+
return (
|
|
53
|
+
provider as unknown as {
|
|
54
|
+
_sharedState: {
|
|
55
|
+
metricCollectors: Array<{
|
|
56
|
+
_metricReader: {
|
|
57
|
+
_exporter: {
|
|
58
|
+
_delegate: {
|
|
59
|
+
_transport: {
|
|
60
|
+
_transport: { _parameters: { url: string } };
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
}>;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
)._sharedState.metricCollectors[0]._metricReader._exporter._delegate
|
|
69
|
+
._transport._transport._parameters.url;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getResourceAttributes(
|
|
73
|
+
provider: MeterProvider,
|
|
74
|
+
): Record<string, unknown> {
|
|
75
|
+
return (
|
|
76
|
+
provider as unknown as {
|
|
77
|
+
_sharedState: { resource: { attributes: Record<string, unknown> } };
|
|
78
|
+
}
|
|
79
|
+
)._sharedState.resource.attributes;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
describe("createMeterProviderFromEnv", () => {
|
|
83
|
+
describe("when OTEL_EXPORTER_OTLP_ENDPOINT is not set", () => {
|
|
84
|
+
it("returns undefined", () => {
|
|
85
|
+
expect(createMeterProviderFromEnv({})).toBeUndefined();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe("when OTEL_EXPORTER_OTLP_ENDPOINT is set", () => {
|
|
90
|
+
it("returns a MeterProvider", () => {
|
|
91
|
+
expect(
|
|
92
|
+
track(
|
|
93
|
+
createMeterProviderFromEnv({
|
|
94
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",
|
|
95
|
+
}),
|
|
96
|
+
),
|
|
97
|
+
).toBeInstanceOf(MeterProvider);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("strips trailing slash from endpoint URL without throwing", () => {
|
|
101
|
+
expect(() =>
|
|
102
|
+
track(
|
|
103
|
+
createMeterProviderFromEnv({
|
|
104
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318/",
|
|
105
|
+
}),
|
|
106
|
+
),
|
|
107
|
+
).not.toThrow();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("does not double-append /v1/metrics when endpoint already includes it", () => {
|
|
111
|
+
const provider = trackAsserted(
|
|
112
|
+
createMeterProviderFromEnv({
|
|
113
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318/v1/metrics",
|
|
114
|
+
}),
|
|
115
|
+
);
|
|
116
|
+
expect(getExporterUrl(provider)).toBe("http://localhost:4318/v1/metrics");
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("uses 5000ms export interval by default", () => {
|
|
120
|
+
const provider = trackAsserted(
|
|
121
|
+
createMeterProviderFromEnv({
|
|
122
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",
|
|
123
|
+
}),
|
|
124
|
+
);
|
|
125
|
+
expect(getReader(provider)._exportInterval).toBe(5000);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("honours OTEL_METRIC_EXPORT_INTERVAL", () => {
|
|
129
|
+
const provider = trackAsserted(
|
|
130
|
+
createMeterProviderFromEnv({
|
|
131
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",
|
|
132
|
+
OTEL_METRIC_EXPORT_INTERVAL: "2000",
|
|
133
|
+
}),
|
|
134
|
+
);
|
|
135
|
+
expect(getReader(provider)._exportInterval).toBe(2000);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("falls back to 5000ms when OTEL_METRIC_EXPORT_INTERVAL is non-numeric", () => {
|
|
139
|
+
const provider = trackAsserted(
|
|
140
|
+
createMeterProviderFromEnv({
|
|
141
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",
|
|
142
|
+
OTEL_METRIC_EXPORT_INTERVAL: "abc",
|
|
143
|
+
}),
|
|
144
|
+
);
|
|
145
|
+
expect(getReader(provider)._exportInterval).toBe(5000);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("falls back to 5000ms when OTEL_METRIC_EXPORT_INTERVAL is zero", () => {
|
|
149
|
+
const provider = trackAsserted(
|
|
150
|
+
createMeterProviderFromEnv({
|
|
151
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",
|
|
152
|
+
OTEL_METRIC_EXPORT_INTERVAL: "0",
|
|
153
|
+
}),
|
|
154
|
+
);
|
|
155
|
+
expect(getReader(provider)._exportInterval).toBe(5000);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("falls back to 5000ms when OTEL_METRIC_EXPORT_INTERVAL is negative", () => {
|
|
159
|
+
const provider = trackAsserted(
|
|
160
|
+
createMeterProviderFromEnv({
|
|
161
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",
|
|
162
|
+
OTEL_METRIC_EXPORT_INTERVAL: "-1000",
|
|
163
|
+
}),
|
|
164
|
+
);
|
|
165
|
+
expect(getReader(provider)._exportInterval).toBe(5000);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("sets exportTimeoutMillis below exportIntervalMillis", () => {
|
|
169
|
+
const provider = trackAsserted(
|
|
170
|
+
createMeterProviderFromEnv({
|
|
171
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",
|
|
172
|
+
OTEL_METRIC_EXPORT_INTERVAL: "1000",
|
|
173
|
+
}),
|
|
174
|
+
);
|
|
175
|
+
const reader = getReader(provider);
|
|
176
|
+
expect(reader._exportTimeout).toBeLessThan(reader._exportInterval);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("uses 'switchboard' as service name by default", () => {
|
|
180
|
+
const provider = trackAsserted(
|
|
181
|
+
createMeterProviderFromEnv({
|
|
182
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",
|
|
183
|
+
}),
|
|
184
|
+
);
|
|
185
|
+
expect(getResourceAttributes(provider)["service.name"]).toBe(
|
|
186
|
+
"switchboard",
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it("honours OTEL_SERVICE_NAME", () => {
|
|
191
|
+
const provider = trackAsserted(
|
|
192
|
+
createMeterProviderFromEnv({
|
|
193
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",
|
|
194
|
+
OTEL_SERVICE_NAME: "my-switchboard",
|
|
195
|
+
}),
|
|
196
|
+
);
|
|
197
|
+
expect(getResourceAttributes(provider)["service.name"]).toBe(
|
|
198
|
+
"my-switchboard",
|
|
199
|
+
);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineConfig } from "vitest/config";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
pool: "forks",
|
|
6
|
+
environment: "node",
|
|
7
|
+
poolOptions: {
|
|
8
|
+
forks: {
|
|
9
|
+
singleFork: true,
|
|
10
|
+
isolate: true,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
include: ["test/**/*.test.ts"],
|
|
14
|
+
},
|
|
15
|
+
});
|