@powerhousedao/opentelemetry-instrumentation-reactor 6.2.3-dev.9 → 6.2.3-staging.0
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/index.d.ts +38 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -1
- package/package.json +8 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { InProcessReactorModule } from "@powerhousedao/reactor";
|
|
2
|
-
import * as _opentelemetry_api0 from "@opentelemetry/api";
|
|
3
|
-
|
|
4
2
|
//#region src/instrumentation.d.ts
|
|
5
|
-
declare class ReactorInstrumentation {
|
|
3
|
+
export declare class ReactorInstrumentation {
|
|
6
4
|
private readonly module;
|
|
7
5
|
private metrics;
|
|
8
6
|
private unsubscribes;
|
|
@@ -22,7 +20,10 @@ declare class ReactorInstrumentation {
|
|
|
22
20
|
private subscribeExecutorJobFailed;
|
|
23
21
|
private subscribeReadModelBatchCompleted;
|
|
24
22
|
private subscribeReadModelIndexed;
|
|
23
|
+
private subscribeCatchUpSwept;
|
|
24
|
+
private registerCatchUpGauges;
|
|
25
25
|
private subscribeDeadLetterAdded;
|
|
26
|
+
private subscribeSignatureRefused;
|
|
26
27
|
private registerObservableGauges;
|
|
27
28
|
private registerPoolInstrumentation;
|
|
28
29
|
private cleanup;
|
|
@@ -30,29 +31,37 @@ declare class ReactorInstrumentation {
|
|
|
30
31
|
//#endregion
|
|
31
32
|
//#region src/metrics.d.ts
|
|
32
33
|
declare function createMetrics(): {
|
|
33
|
-
queueJobsEnqueued:
|
|
34
|
-
queueJobsDequeued:
|
|
35
|
-
queueJobsCompleted:
|
|
36
|
-
queueJobsFailed:
|
|
37
|
-
queueDepth:
|
|
38
|
-
executorJobDuration:
|
|
39
|
-
executorActiveJobs:
|
|
40
|
-
executorTotalProcessed:
|
|
41
|
-
executorOperationsGenerated:
|
|
42
|
-
jobTotalDuration:
|
|
43
|
-
readmodelIndexDuration:
|
|
44
|
-
readmodelCoordinatorChainDepth:
|
|
45
|
-
readmodelCoordinatorStageDuration:
|
|
46
|
-
readmodelIndexingDuration:
|
|
47
|
-
readmodelCoordinatorBatchSize:
|
|
48
|
-
readmodelCoordinatorChainWaitDuration:
|
|
49
|
-
dbPoolAcquireWaitDuration:
|
|
50
|
-
dbPoolSize:
|
|
51
|
-
dbPoolIdle:
|
|
52
|
-
dbPoolWaiting:
|
|
53
|
-
eventbusEventsEmitted:
|
|
54
|
-
syncRemotes:
|
|
55
|
-
syncDeadLettersAdded:
|
|
34
|
+
queueJobsEnqueued: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
35
|
+
queueJobsDequeued: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
36
|
+
queueJobsCompleted: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
37
|
+
queueJobsFailed: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
38
|
+
queueDepth: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
39
|
+
executorJobDuration: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
|
|
40
|
+
executorActiveJobs: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
41
|
+
executorTotalProcessed: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
42
|
+
executorOperationsGenerated: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
43
|
+
jobTotalDuration: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
|
|
44
|
+
readmodelIndexDuration: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
|
|
45
|
+
readmodelCoordinatorChainDepth: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
46
|
+
readmodelCoordinatorStageDuration: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
|
|
47
|
+
readmodelIndexingDuration: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
|
|
48
|
+
readmodelCoordinatorBatchSize: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
|
|
49
|
+
readmodelCoordinatorChainWaitDuration: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
|
|
50
|
+
dbPoolAcquireWaitDuration: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
|
|
51
|
+
dbPoolSize: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
52
|
+
dbPoolIdle: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
53
|
+
dbPoolWaiting: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
54
|
+
eventbusEventsEmitted: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
55
|
+
syncRemotes: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
56
|
+
syncDeadLettersAdded: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
57
|
+
catchupSequenceHead: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
58
|
+
catchupSettledThrough: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
59
|
+
catchupSettleLag: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
60
|
+
catchupConsumerLag: import("@opentelemetry/api").ObservableGauge<import("@opentelemetry/api").Attributes>;
|
|
61
|
+
catchupSweepDuration: import("@opentelemetry/api").Histogram<import("@opentelemetry/api").Attributes>;
|
|
62
|
+
catchupSweepReplayed: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
63
|
+
catchupSweepFailures: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
64
|
+
signatureRefusals: import("@opentelemetry/api").Counter<import("@opentelemetry/api").Attributes>;
|
|
56
65
|
};
|
|
57
66
|
type ReactorMetrics = ReturnType<typeof createMetrics>;
|
|
58
67
|
//#endregion
|
|
@@ -77,7 +86,8 @@ type EventLoopInstrumentation = {
|
|
|
77
86
|
* process-lifetime cumulative. ELU and CPU deltas are computed against a
|
|
78
87
|
* cached previous snapshot, also windowed to the prior scrape interval.
|
|
79
88
|
*/
|
|
80
|
-
declare function registerEventLoopInstrumentation(): EventLoopInstrumentation;
|
|
89
|
+
export declare function registerEventLoopInstrumentation(): EventLoopInstrumentation;
|
|
81
90
|
//#endregion
|
|
82
|
-
export {
|
|
91
|
+
export type { EventLoopInstrumentation, ReactorMetrics };
|
|
92
|
+
export {};
|
|
83
93
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/instrumentation.ts","../src/metrics.ts","../src/event-loop-instrumentation.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/instrumentation.ts","../src/metrics.ts","../src/event-loop-instrumentation.ts"],"mappings":";;qBA8Ba;mBACM;UACT;UACA;UACA;UAGA;UACA;UACA;EAER,YAAY,QAAQ;EAIpB;EA0BA;UAeQ;UAgBA;UAgBA;UAgBA;UA6BA;UAuBA;UA4BA;UA4BA;UA8BA;UAmBA;UAsBA;UAyCA;UAiBA;UAmBA;UAoEA;UA2CA;;;;iBCjfM;EAKZ,gDAAiB,qCAAA;EAIjB,gDAAiB,qCAAA;EAIjB,iDAAkB,qCAAA;EAIlB,8CAAe,qCAAA;EAIf,yCAAU,6CAAA;EAMV,kDAAmB,uCAAA;EAOnB,iDAAkB,6CAAA;EAOlB,qDAAsB,qCAAA;EAItB,0DAA2B,qCAAA;EAS3B,+CAAgB,uCAAA;EAMhB,qDAAsB,uCAAA;EAOtB,6DAA8B,6CAAA;EAQ9B,gEAAiC,uCAAA;EAQjC,wDAAyB,uCAAA;EAQzB,4DAA6B,uCAAA;EAO7B,oEAAqC,uCAAA;EAUrC,wDAAyB,uCAAA;EAQzB,yCAAU,6CAAA;EAIV,yCAAU,6CAAA;EAIV,4CAAa,6CAAA;EAOb,oDAAqB,qCAAA;EASrB,0CAAW,6CAAA;EAIX,mDAAoB,qCAAA;EASpB,kDAAmB,6CAAA;EAOnB,oDAAqB,6CAAA;EAQrB,+CAAgB,6CAAA;EAOhB,iDAAkB,6CAAA;EAOlB,mDAAoB,uCAAA;EAOpB,mDAAoB,qCAAA;EAOpB,mDAAoB,qCAAA;EASpB,gDAAiB,qCAAA;;KAQT,iBAAiB,kBAAkB;;;;;;;;KC9LnC;EACV;;;;;;;;;;;;;;wBAec,oCAAoC"}
|
package/dist/index.js
CHANGED
|
@@ -97,6 +97,38 @@ function createMetrics() {
|
|
|
97
97
|
syncDeadLettersAdded: meter.createCounter("reactor.sync.dead_letters.added", {
|
|
98
98
|
description: "Sync operations moved to dead letter storage",
|
|
99
99
|
unit: "{operation}"
|
|
100
|
+
}),
|
|
101
|
+
catchupSequenceHead: meter.createObservableGauge("reactor.catchup.sequence_head", {
|
|
102
|
+
description: "Highest ordinal the index sequence has handed out",
|
|
103
|
+
unit: "{ordinal}"
|
|
104
|
+
}),
|
|
105
|
+
catchupSettledThrough: meter.createObservableGauge("reactor.catchup.settled_through", {
|
|
106
|
+
description: "Every ordinal at or below this is visible or will never exist",
|
|
107
|
+
unit: "{ordinal}"
|
|
108
|
+
}),
|
|
109
|
+
catchupSettleLag: meter.createObservableGauge("reactor.catchup.settle_lag", {
|
|
110
|
+
description: "Sequence head minus the settled watermark",
|
|
111
|
+
unit: "{ordinal}"
|
|
112
|
+
}),
|
|
113
|
+
catchupConsumerLag: meter.createObservableGauge("reactor.catchup.consumer_lag", {
|
|
114
|
+
description: "Settled watermark minus a consumer's applied cursor",
|
|
115
|
+
unit: "{ordinal}"
|
|
116
|
+
}),
|
|
117
|
+
catchupSweepDuration: meter.createHistogram("reactor.catchup.sweep.duration", {
|
|
118
|
+
description: "Wall time of a catch-up sweep that moved or replayed",
|
|
119
|
+
unit: "ms"
|
|
120
|
+
}),
|
|
121
|
+
catchupSweepReplayed: meter.createCounter("reactor.catchup.sweep.replayed", {
|
|
122
|
+
description: "Operations a sweep applied that the live path never did",
|
|
123
|
+
unit: "{operation}"
|
|
124
|
+
}),
|
|
125
|
+
catchupSweepFailures: meter.createCounter("reactor.catchup.sweep.failures", {
|
|
126
|
+
description: "Sweeps that could not apply an operation",
|
|
127
|
+
unit: "{sweep}"
|
|
128
|
+
}),
|
|
129
|
+
signatureRefusals: meter.createCounter("reactor.signature.refusals", {
|
|
130
|
+
description: "Writes that failed signature admission, refused or (in log mode) admitted",
|
|
131
|
+
unit: "{operation}"
|
|
100
132
|
})
|
|
101
133
|
};
|
|
102
134
|
}
|
|
@@ -124,10 +156,13 @@ var ReactorInstrumentation = class {
|
|
|
124
156
|
this.subscribeExecutorJobCompleted(eventBus);
|
|
125
157
|
this.subscribeExecutorJobFailed(eventBus);
|
|
126
158
|
this.subscribeDeadLetterAdded(eventBus);
|
|
159
|
+
this.subscribeSignatureRefused(eventBus);
|
|
127
160
|
this.subscribeReadModelBatchCompleted(eventBus);
|
|
128
161
|
this.subscribeReadModelIndexed(eventBus);
|
|
162
|
+
this.subscribeCatchUpSwept(eventBus);
|
|
129
163
|
this.registerObservableGauges(queue, executorManager, this.module.readModelCoordinator, syncModule);
|
|
130
164
|
this.registerPoolInstrumentation(pools);
|
|
165
|
+
this.registerCatchUpGauges();
|
|
131
166
|
}
|
|
132
167
|
stop() {
|
|
133
168
|
for (const unsub of this.unsubscribes) unsub();
|
|
@@ -247,6 +282,42 @@ var ReactorInstrumentation = class {
|
|
|
247
282
|
this.metrics.eventbusEventsEmitted.add(1, { "event.type": "READMODEL_INDEXED" });
|
|
248
283
|
}));
|
|
249
284
|
}
|
|
285
|
+
subscribeCatchUpSwept(eventBus) {
|
|
286
|
+
this.unsubscribes.push(eventBus.subscribe(ReactorEventTypes.CATCHUP_SWEPT, (_type, event) => {
|
|
287
|
+
if (!this.metrics) return;
|
|
288
|
+
const attrs = {
|
|
289
|
+
consumer: event.consumerId,
|
|
290
|
+
thread: event.thread
|
|
291
|
+
};
|
|
292
|
+
this.metrics.catchupSweepDuration.record(event.durationMs, attrs);
|
|
293
|
+
if (event.replayed > 0) this.metrics.catchupSweepReplayed.add(event.replayed, attrs);
|
|
294
|
+
if (event.blockedAt !== void 0) this.metrics.catchupSweepFailures.add(1, attrs);
|
|
295
|
+
this.metrics.eventbusEventsEmitted.add(1, { "event.type": "CATCHUP_SWEPT" });
|
|
296
|
+
}));
|
|
297
|
+
}
|
|
298
|
+
registerCatchUpGauges() {
|
|
299
|
+
if (!this.metrics) return;
|
|
300
|
+
const { catchUp } = this.module;
|
|
301
|
+
const gauges = [
|
|
302
|
+
[this.metrics.catchupSequenceHead, (result) => result.observe(catchUp.status().watermark.head)],
|
|
303
|
+
[this.metrics.catchupSettledThrough, (result) => result.observe(catchUp.status().watermark.settledThrough)],
|
|
304
|
+
[this.metrics.catchupSettleLag, (result) => {
|
|
305
|
+
const { head, settledThrough } = catchUp.status().watermark;
|
|
306
|
+
result.observe(Math.max(0, head - settledThrough));
|
|
307
|
+
}],
|
|
308
|
+
[this.metrics.catchupConsumerLag, (result) => {
|
|
309
|
+
const status = catchUp.status();
|
|
310
|
+
for (const consumer of status.consumers) result.observe(Math.max(0, status.watermark.settledThrough - consumer.appliedThrough), {
|
|
311
|
+
consumer: consumer.consumerId,
|
|
312
|
+
thread: consumer.thread
|
|
313
|
+
});
|
|
314
|
+
}]
|
|
315
|
+
];
|
|
316
|
+
for (const [gauge, callback] of gauges) {
|
|
317
|
+
gauge.addCallback(callback);
|
|
318
|
+
this.observableCallbacks.push([gauge, callback]);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
250
321
|
subscribeDeadLetterAdded(eventBus) {
|
|
251
322
|
this.unsubscribes.push(eventBus.subscribe(SyncEventTypes.DEAD_LETTER_ADDED, (_type, event) => {
|
|
252
323
|
if (!this.metrics) return;
|
|
@@ -254,6 +325,17 @@ var ReactorInstrumentation = class {
|
|
|
254
325
|
this.metrics.eventbusEventsEmitted.add(1, { "event.type": "DEAD_LETTER_ADDED" });
|
|
255
326
|
}));
|
|
256
327
|
}
|
|
328
|
+
subscribeSignatureRefused(eventBus) {
|
|
329
|
+
this.unsubscribes.push(eventBus.subscribe(ReactorEventTypes.SIGNATURE_REFUSED, (_type, event) => {
|
|
330
|
+
if (!this.metrics) return;
|
|
331
|
+
this.metrics.signatureRefusals.add(1, {
|
|
332
|
+
scheme: event.scheme,
|
|
333
|
+
path: event.path,
|
|
334
|
+
code: event.code
|
|
335
|
+
});
|
|
336
|
+
this.metrics.eventbusEventsEmitted.add(1, { "event.type": "SIGNATURE_REFUSED" });
|
|
337
|
+
}));
|
|
338
|
+
}
|
|
257
339
|
registerObservableGauges(queue, executorManager, readModelCoordinator, syncModule) {
|
|
258
340
|
if (!this.metrics) return;
|
|
259
341
|
const depthCb = async (result) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["METER_NAME","performance"],"sources":["../src/metrics.ts","../src/instrumentation.ts","../src/event-loop-instrumentation.ts"],"sourcesContent":["import { metrics } from \"@opentelemetry/api\";\n\nconst METER_NAME = \"@powerhousedao/reactor\";\n\nexport function createMetrics() {\n const meter = metrics.getMeter(METER_NAME);\n\n return {\n // Queue metrics\n queueJobsEnqueued: meter.createCounter(\"reactor.queue.jobs.enqueued\", {\n description: \"Jobs enqueued\",\n unit: \"{job}\",\n }),\n queueJobsDequeued: meter.createCounter(\"reactor.queue.jobs.dequeued\", {\n description: \"Jobs dequeued for execution\",\n unit: \"{job}\",\n }),\n queueJobsCompleted: meter.createCounter(\"reactor.queue.jobs.completed\", {\n description: \"Jobs completed (READ_READY)\",\n unit: \"{job}\",\n }),\n queueJobsFailed: meter.createCounter(\"reactor.queue.jobs.failed\", {\n description: \"Jobs permanently failed\",\n unit: \"{job}\",\n }),\n queueDepth: meter.createObservableGauge(\"reactor.queue.depth\", {\n description: \"Pending jobs across all queues\",\n unit: \"{job}\",\n }),\n\n // Executor metrics\n executorJobDuration: meter.createHistogram(\n \"reactor.executor.job.duration\",\n {\n description: \"Job execution time (RUNNING to WRITE_READY)\",\n unit: \"ms\",\n },\n ),\n executorActiveJobs: meter.createObservableGauge(\n \"reactor.executor.active_jobs\",\n {\n description: \"Currently executing jobs\",\n unit: \"{job}\",\n },\n ),\n executorTotalProcessed: meter.createCounter(\"reactor.executor.processed\", {\n description: \"Total jobs processed\",\n unit: \"{job}\",\n }),\n executorOperationsGenerated: meter.createCounter(\n \"reactor.executor.operations_generated\",\n {\n description: \"Operations produced by executors\",\n unit: \"{operation}\",\n },\n ),\n\n // Job lifecycle metrics\n jobTotalDuration: meter.createHistogram(\"reactor.job.total.duration\", {\n description: \"Full job lifecycle (PENDING to READ_READY/FAILED)\",\n unit: \"ms\",\n }),\n\n // Read model metrics\n readmodelIndexDuration: meter.createHistogram(\n \"reactor.readmodel.index.duration\",\n {\n description: \"Read model indexing time (WRITE_READY to READ_READY)\",\n unit: \"ms\",\n },\n ),\n readmodelCoordinatorChainDepth: meter.createObservableGauge(\n \"reactor.readmodel.coordinator.chain_depth\",\n {\n description:\n \"In-flight per-queueKey projection chains in the coordinator\",\n unit: \"{chain}\",\n },\n ),\n readmodelCoordinatorStageDuration: meter.createHistogram(\n \"reactor.readmodel.coordinator.stage.duration\",\n {\n description:\n \"Wall time per stage in ReadModelCoordinator.runChain (pre_ready, emit, post_ready)\",\n unit: \"ms\",\n },\n ),\n readmodelIndexingDuration: meter.createHistogram(\n \"reactor.readmodel.indexing.duration\",\n {\n description:\n \"Per-read-model indexing duration within a coordinator chain\",\n unit: \"ms\",\n },\n ),\n readmodelCoordinatorBatchSize: meter.createHistogram(\n \"reactor.readmodel.coordinator.batch.size\",\n {\n description: \"Operations per batch processed by the coordinator chain\",\n unit: \"{operation}\",\n },\n ),\n readmodelCoordinatorChainWaitDuration: meter.createHistogram(\n \"reactor.readmodel.coordinator.chain.wait_duration\",\n {\n description:\n \"Time a batch sat in the per-queueKey chain before runChain started\",\n unit: \"ms\",\n },\n ),\n\n // Postgres pool metrics\n dbPoolAcquireWaitDuration: meter.createHistogram(\n \"reactor.db.pool.acquire.wait_duration\",\n {\n description:\n \"Time spent waiting for a pg.Pool to hand out a client (pool.connect resolve latency)\",\n unit: \"ms\",\n },\n ),\n dbPoolSize: meter.createObservableGauge(\"reactor.db.pool.size\", {\n description: \"pg.Pool totalCount — connections currently open\",\n unit: \"{connection}\",\n }),\n dbPoolIdle: meter.createObservableGauge(\"reactor.db.pool.idle\", {\n description: \"pg.Pool idleCount — open connections not currently in use\",\n unit: \"{connection}\",\n }),\n dbPoolWaiting: meter.createObservableGauge(\"reactor.db.pool.waiting\", {\n description:\n \"pg.Pool waitingCount — callers queued waiting to acquire a connection\",\n unit: \"{request}\",\n }),\n\n // Event bus metrics\n eventbusEventsEmitted: meter.createCounter(\n \"reactor.eventbus.events.emitted\",\n {\n description: \"Events emitted\",\n unit: \"{event}\",\n },\n ),\n\n // Sync metrics\n syncRemotes: meter.createObservableGauge(\"reactor.sync.remotes\", {\n description: \"Active remote count\",\n unit: \"{remote}\",\n }),\n syncDeadLettersAdded: meter.createCounter(\n \"reactor.sync.dead_letters.added\",\n {\n description: \"Sync operations moved to dead letter storage\",\n unit: \"{operation}\",\n },\n ),\n };\n}\n\nexport type ReactorMetrics = ReturnType<typeof createMetrics>;\n","import {\n JobExecutorEventTypes,\n ReactorEventTypes,\n SyncEventTypes,\n} from \"@powerhousedao/reactor\";\nimport type {\n DeadLetterAddedEvent,\n IEventBus,\n IJobExecutorManager,\n IQueue,\n JobCompletedEvent,\n JobFailedEvent as ExecutorJobFailedEvent,\n JobPendingEvent,\n JobReadReadyEvent,\n JobRunningEvent,\n JobWriteReadyEvent,\n PoolInstrumentation,\n ReactorJobFailedEvent,\n ReadModelBatchCompletedEvent,\n ReadModelIndexedEvent,\n IReadModelCoordinator,\n InProcessReactorModule,\n SyncModule,\n Unsubscribe,\n} from \"@powerhousedao/reactor\";\nimport type { ObservableCallback, ObservableGauge } from \"@opentelemetry/api\";\nimport { createMetrics, type ReactorMetrics } from \"./metrics.js\";\n\nexport class ReactorInstrumentation {\n private readonly module: InProcessReactorModule;\n private metrics: ReactorMetrics | undefined;\n private unsubscribes: Unsubscribe[] = [];\n private observableCallbacks: Array<[ObservableGauge, ObservableCallback]> =\n [];\n\n private pendingTimestamps = new Map<string, number>();\n private runningTimestamps = new Map<string, number>();\n private writeReadyTimestamps = new Map<string, number>();\n\n constructor(module: InProcessReactorModule) {\n this.module = module;\n }\n\n start(): void {\n this.metrics = createMetrics();\n const { eventBus, queue, executorManager, syncModule, pools } = this.module;\n\n this.subscribeJobPending(eventBus);\n this.subscribeJobRunning(eventBus);\n this.subscribeJobWriteReady(eventBus);\n this.subscribeJobReadReady(eventBus);\n this.subscribeJobFailed(eventBus);\n this.subscribeExecutorJobCompleted(eventBus);\n this.subscribeExecutorJobFailed(eventBus);\n this.subscribeDeadLetterAdded(eventBus);\n this.subscribeReadModelBatchCompleted(eventBus);\n this.subscribeReadModelIndexed(eventBus);\n this.registerObservableGauges(\n queue,\n executorManager,\n this.module.readModelCoordinator,\n syncModule,\n );\n this.registerPoolInstrumentation(pools);\n }\n\n stop(): void {\n for (const unsub of this.unsubscribes) {\n unsub();\n }\n this.unsubscribes = [];\n for (const [gauge, cb] of this.observableCallbacks) {\n gauge.removeCallback(cb);\n }\n this.observableCallbacks = [];\n this.pendingTimestamps.clear();\n this.runningTimestamps.clear();\n this.writeReadyTimestamps.clear();\n this.metrics = undefined;\n }\n\n private subscribeJobPending(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<JobPendingEvent>(\n ReactorEventTypes.JOB_PENDING,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.queueJobsEnqueued.add(1);\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"JOB_PENDING\",\n });\n this.pendingTimestamps.set(event.jobId, performance.now());\n },\n ),\n );\n }\n\n private subscribeJobRunning(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<JobRunningEvent>(\n ReactorEventTypes.JOB_RUNNING,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.queueJobsDequeued.add(1);\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"JOB_RUNNING\",\n });\n this.runningTimestamps.set(event.jobId, performance.now());\n },\n ),\n );\n }\n\n private subscribeJobWriteReady(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<JobWriteReadyEvent>(\n ReactorEventTypes.JOB_WRITE_READY,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.executorOperationsGenerated.add(event.operations.length);\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"JOB_WRITE_READY\",\n });\n this.writeReadyTimestamps.set(event.jobId, performance.now());\n },\n ),\n );\n }\n\n private subscribeJobReadReady(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<JobReadReadyEvent>(\n ReactorEventTypes.JOB_READ_READY,\n (_type, event) => {\n if (!this.metrics) return;\n const writeReadyTs = this.writeReadyTimestamps.get(event.jobId);\n if (writeReadyTs !== undefined) {\n this.metrics.readmodelIndexDuration.record(\n performance.now() - writeReadyTs,\n );\n }\n const pendingTs = this.pendingTimestamps.get(event.jobId);\n if (pendingTs !== undefined) {\n this.metrics.jobTotalDuration.record(\n performance.now() - pendingTs,\n { \"job.success\": \"true\" },\n );\n }\n this.metrics.queueJobsCompleted.add(1);\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"JOB_READ_READY\",\n });\n this.cleanup(event.jobId);\n },\n ),\n );\n }\n\n private subscribeJobFailed(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<ReactorJobFailedEvent>(\n ReactorEventTypes.JOB_FAILED,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.queueJobsFailed.add(1);\n const pendingTs = this.pendingTimestamps.get(event.jobId);\n if (pendingTs !== undefined) {\n this.metrics.jobTotalDuration.record(\n performance.now() - pendingTs,\n { \"job.success\": \"false\" },\n );\n }\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"JOB_FAILED\",\n });\n this.cleanup(event.jobId);\n },\n ),\n );\n }\n\n private subscribeExecutorJobCompleted(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<JobCompletedEvent>(\n JobExecutorEventTypes.JOB_COMPLETED,\n (_type, event) => {\n if (!this.metrics) return;\n const workerId = event.workerId ?? \"unknown\";\n const jobId = event.job.id;\n const runningTs = this.runningTimestamps.get(jobId);\n if (runningTs !== undefined) {\n this.metrics.executorJobDuration.record(\n performance.now() - runningTs,\n { \"job.success\": \"true\", \"worker.id\": workerId },\n );\n this.runningTimestamps.delete(jobId);\n }\n this.metrics.executorTotalProcessed.add(1, {\n \"job.success\": \"true\",\n \"worker.id\": workerId,\n });\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"EXECUTOR_JOB_COMPLETED\",\n });\n },\n ),\n );\n }\n\n private subscribeExecutorJobFailed(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<ExecutorJobFailedEvent>(\n JobExecutorEventTypes.JOB_FAILED,\n (_type, event) => {\n if (!this.metrics) return;\n const workerId = event.workerId ?? \"unknown\";\n const jobId = event.job.id;\n const runningTs = this.runningTimestamps.get(jobId);\n if (runningTs !== undefined) {\n this.metrics.executorJobDuration.record(\n performance.now() - runningTs,\n { \"job.success\": \"false\", \"worker.id\": workerId },\n );\n this.runningTimestamps.delete(jobId);\n }\n this.metrics.executorTotalProcessed.add(1, {\n \"job.success\": \"false\",\n \"worker.id\": workerId,\n });\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"EXECUTOR_JOB_FAILED\",\n });\n },\n ),\n );\n }\n\n private subscribeReadModelBatchCompleted(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<ReadModelBatchCompletedEvent>(\n ReactorEventTypes.READMODEL_BATCH_COMPLETED,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.readmodelCoordinatorChainWaitDuration.record(\n event.chainWaitDurationMs,\n );\n this.metrics.readmodelCoordinatorBatchSize.record(event.batchSize);\n this.metrics.readmodelCoordinatorStageDuration.record(\n event.preReadyDurationMs,\n { stage: \"pre_ready\" },\n );\n this.metrics.readmodelCoordinatorStageDuration.record(\n event.emitDurationMs,\n { stage: \"emit\" },\n );\n this.metrics.readmodelCoordinatorStageDuration.record(\n event.postReadyDurationMs,\n { stage: \"post_ready\" },\n );\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"READMODEL_BATCH_COMPLETED\",\n });\n },\n ),\n );\n }\n\n private subscribeReadModelIndexed(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<ReadModelIndexedEvent>(\n ReactorEventTypes.READMODEL_INDEXED,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.readmodelIndexingDuration.record(event.durationMs, {\n \"read_model.name\": event.readModelName,\n stage: event.stage,\n \"indexing.success\": event.success ? \"true\" : \"false\",\n });\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"READMODEL_INDEXED\",\n });\n },\n ),\n );\n }\n\n private subscribeDeadLetterAdded(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<DeadLetterAddedEvent>(\n SyncEventTypes.DEAD_LETTER_ADDED,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.syncDeadLettersAdded.add(1, {\n \"remote.name\": event.remoteName,\n });\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"DEAD_LETTER_ADDED\",\n });\n },\n ),\n );\n }\n\n private registerObservableGauges(\n queue: IQueue,\n executorManager: IJobExecutorManager,\n readModelCoordinator: IReadModelCoordinator,\n syncModule: SyncModule | undefined,\n ): void {\n if (!this.metrics) return;\n\n const depthCb: ObservableCallback = async (result) => {\n if (!this.metrics) return;\n // queue.totalSize() is a DB query. If it exceeds the OTel collection\n // window the observation is silently dropped, making the gauge appear\n // to drop to zero under load. The timeout makes the failure explicit.\n const TIMEOUT_MS = 2_000;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n const depth = await Promise.race([\n queue.totalSize(),\n new Promise<never>((_, reject) => {\n timeoutId = setTimeout(\n () => reject(new Error(\"queue.totalSize() timed out\")),\n TIMEOUT_MS,\n );\n }),\n ]);\n result.observe(depth);\n } catch (err) {\n console.warn(\n \"[ReactorInstrumentation] queueDepth observation failed:\",\n err,\n );\n } finally {\n clearTimeout(timeoutId);\n }\n };\n this.metrics.queueDepth.addCallback(depthCb);\n this.observableCallbacks.push([this.metrics.queueDepth, depthCb]);\n\n const activeJobsCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n const status = executorManager.getStatus();\n result.observe(status.activeJobs);\n };\n this.metrics.executorActiveJobs.addCallback(activeJobsCb);\n this.observableCallbacks.push([\n this.metrics.executorActiveJobs,\n activeJobsCb,\n ]);\n\n const chainDepthCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n result.observe(readModelCoordinator.getChainDepth());\n };\n this.metrics.readmodelCoordinatorChainDepth.addCallback(chainDepthCb);\n this.observableCallbacks.push([\n this.metrics.readmodelCoordinatorChainDepth,\n chainDepthCb,\n ]);\n\n const remotesCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n const count = syncModule?.syncManager.list().length ?? 0;\n result.observe(count);\n };\n this.metrics.syncRemotes.addCallback(remotesCb);\n this.observableCallbacks.push([this.metrics.syncRemotes, remotesCb]);\n }\n\n private registerPoolInstrumentation(pools: PoolInstrumentation[]): void {\n if (!this.metrics || pools.length === 0) return;\n\n for (const pool of pools) {\n const attrs = { pool: pool.name };\n const unsub = pool.onAcquire((durationMs) => {\n if (!this.metrics) return;\n this.metrics.dbPoolAcquireWaitDuration.record(durationMs, attrs);\n });\n this.unsubscribes.push(unsub);\n }\n\n const sizeCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n for (const pool of pools) {\n const stats = pool.getStats();\n result.observe(stats.size, { pool: pool.name });\n }\n };\n this.metrics.dbPoolSize.addCallback(sizeCb);\n this.observableCallbacks.push([this.metrics.dbPoolSize, sizeCb]);\n\n const idleCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n for (const pool of pools) {\n const stats = pool.getStats();\n result.observe(stats.idle, { pool: pool.name });\n }\n };\n this.metrics.dbPoolIdle.addCallback(idleCb);\n this.observableCallbacks.push([this.metrics.dbPoolIdle, idleCb]);\n\n const waitingCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n for (const pool of pools) {\n const stats = pool.getStats();\n result.observe(stats.waiting, { pool: pool.name });\n }\n };\n this.metrics.dbPoolWaiting.addCallback(waitingCb);\n this.observableCallbacks.push([this.metrics.dbPoolWaiting, waitingCb]);\n }\n\n private cleanup(jobId: string): void {\n this.pendingTimestamps.delete(jobId);\n this.runningTimestamps.delete(jobId);\n this.writeReadyTimestamps.delete(jobId);\n }\n}\n","// Host event-loop and CPU instrumentation. Registers OTel observable\n// gauges on the global meter provider for monitorEventLoopDelay percentiles,\n// performance.eventLoopUtilization, and process.cpuUsage. Pure observation;\n// does not touch the reactor package. Started by the host process once its\n// meter provider is registered (switchboard: observability.mts; bench: main.ts).\nimport {\n metrics,\n type BatchObservableCallback,\n type BatchObservableResult,\n type Observable,\n} from \"@opentelemetry/api\";\nimport {\n monitorEventLoopDelay,\n performance,\n type EventLoopUtilization,\n} from \"node:perf_hooks\";\n\nconst METER_NAME = \"@powerhousedao/reactor-host\";\nconst DELAY_RESOLUTION_MS = 10;\nconst NS_PER_MS = 1_000_000;\nconst NS_PER_US = 1_000;\n\n/**\n * Handle returned by registerEventLoopInstrumentation. Calling stop()\n * disables the underlying monitorEventLoopDelay histogram and removes\n * the batch observable callback from the meter.\n */\nexport type EventLoopInstrumentation = {\n stop(): void;\n};\n\n/**\n * Registers six observable gauges on the host meter:\n *\n * reactor.host.eventloop.delay.{p50,p95,p99,max} (ms)\n * reactor.host.eventloop.utilization (ratio 0..1)\n * reactor.host.cpu.utilization (ratio, >1 if multi-core)\n *\n * The monitorEventLoopDelay histogram is reset on each scrape so each sample\n * represents the delay distribution over the prior scrape window rather than\n * process-lifetime cumulative. ELU and CPU deltas are computed against a\n * cached previous snapshot, also windowed to the prior scrape interval.\n */\nexport function registerEventLoopInstrumentation(): EventLoopInstrumentation {\n const meter = metrics.getMeter(METER_NAME);\n\n const histogram = monitorEventLoopDelay({ resolution: DELAY_RESOLUTION_MS });\n histogram.enable();\n\n const delayP50 = meter.createObservableGauge(\n \"reactor.host.eventloop.delay.p50\",\n {\n description: \"Event-loop callback delay p50 over the prior scrape window\",\n unit: \"ms\",\n },\n );\n const delayP95 = meter.createObservableGauge(\n \"reactor.host.eventloop.delay.p95\",\n {\n description: \"Event-loop callback delay p95 over the prior scrape window\",\n unit: \"ms\",\n },\n );\n const delayP99 = meter.createObservableGauge(\n \"reactor.host.eventloop.delay.p99\",\n {\n description: \"Event-loop callback delay p99 over the prior scrape window\",\n unit: \"ms\",\n },\n );\n const delayMax = meter.createObservableGauge(\n \"reactor.host.eventloop.delay.max\",\n {\n description: \"Event-loop callback delay max over the prior scrape window\",\n unit: \"ms\",\n },\n );\n const utilization = meter.createObservableGauge(\n \"reactor.host.eventloop.utilization\",\n {\n description:\n \"Event-loop utilization ratio (active / (active + idle)) over the prior scrape window\",\n unit: \"1\",\n },\n );\n const cpuUtilization = meter.createObservableGauge(\n \"reactor.host.cpu.utilization\",\n {\n description:\n \"Process CPU utilization over the prior scrape window. 1.0 = one core saturated.\",\n unit: \"1\",\n },\n );\n\n let prevElu: EventLoopUtilization = performance.eventLoopUtilization();\n let prevCpu: NodeJS.CpuUsage = process.cpuUsage();\n let prevHrtime: bigint = process.hrtime.bigint();\n\n const callback: BatchObservableCallback = (result: BatchObservableResult) => {\n const p50ms = histogram.percentile(50) / NS_PER_MS;\n const p95ms = histogram.percentile(95) / NS_PER_MS;\n const p99ms = histogram.percentile(99) / NS_PER_MS;\n const maxMs = histogram.max / NS_PER_MS;\n histogram.reset();\n\n const eluNow = performance.eventLoopUtilization();\n const eluDelta = performance.eventLoopUtilization(eluNow, prevElu);\n prevElu = eluNow;\n\n const cpuNow = process.cpuUsage();\n const hrtimeNow = process.hrtime.bigint();\n const cpuDeltaUs =\n cpuNow.user - prevCpu.user + (cpuNow.system - prevCpu.system);\n const elapsedUs = Number(hrtimeNow - prevHrtime) / NS_PER_US;\n const cpuRatio = elapsedUs > 0 ? cpuDeltaUs / elapsedUs : 0;\n prevCpu = cpuNow;\n prevHrtime = hrtimeNow;\n\n result.observe(delayP50, p50ms);\n result.observe(delayP95, p95ms);\n result.observe(delayP99, p99ms);\n result.observe(delayMax, maxMs);\n result.observe(utilization, eluDelta.utilization);\n result.observe(cpuUtilization, cpuRatio);\n };\n\n const observables: Observable[] = [\n delayP50,\n delayP95,\n delayP99,\n delayMax,\n utilization,\n cpuUtilization,\n ];\n\n meter.addBatchObservableCallback(callback, observables);\n\n return {\n stop(): void {\n meter.removeBatchObservableCallback(callback, observables);\n histogram.disable();\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["METER_NAME","performance"],"sources":["../src/metrics.ts","../src/instrumentation.ts","../src/event-loop-instrumentation.ts"],"sourcesContent":["import { metrics } from \"@opentelemetry/api\";\n\nconst METER_NAME = \"@powerhousedao/reactor\";\n\nexport function createMetrics() {\n const meter = metrics.getMeter(METER_NAME);\n\n return {\n // Queue metrics\n queueJobsEnqueued: meter.createCounter(\"reactor.queue.jobs.enqueued\", {\n description: \"Jobs enqueued\",\n unit: \"{job}\",\n }),\n queueJobsDequeued: meter.createCounter(\"reactor.queue.jobs.dequeued\", {\n description: \"Jobs dequeued for execution\",\n unit: \"{job}\",\n }),\n queueJobsCompleted: meter.createCounter(\"reactor.queue.jobs.completed\", {\n description: \"Jobs completed (READ_READY)\",\n unit: \"{job}\",\n }),\n queueJobsFailed: meter.createCounter(\"reactor.queue.jobs.failed\", {\n description: \"Jobs permanently failed\",\n unit: \"{job}\",\n }),\n queueDepth: meter.createObservableGauge(\"reactor.queue.depth\", {\n description: \"Pending jobs across all queues\",\n unit: \"{job}\",\n }),\n\n // Executor metrics\n executorJobDuration: meter.createHistogram(\n \"reactor.executor.job.duration\",\n {\n description: \"Job execution time (RUNNING to WRITE_READY)\",\n unit: \"ms\",\n },\n ),\n executorActiveJobs: meter.createObservableGauge(\n \"reactor.executor.active_jobs\",\n {\n description: \"Currently executing jobs\",\n unit: \"{job}\",\n },\n ),\n executorTotalProcessed: meter.createCounter(\"reactor.executor.processed\", {\n description: \"Total jobs processed\",\n unit: \"{job}\",\n }),\n executorOperationsGenerated: meter.createCounter(\n \"reactor.executor.operations_generated\",\n {\n description: \"Operations produced by executors\",\n unit: \"{operation}\",\n },\n ),\n\n // Job lifecycle metrics\n jobTotalDuration: meter.createHistogram(\"reactor.job.total.duration\", {\n description: \"Full job lifecycle (PENDING to READ_READY/FAILED)\",\n unit: \"ms\",\n }),\n\n // Read model metrics\n readmodelIndexDuration: meter.createHistogram(\n \"reactor.readmodel.index.duration\",\n {\n description: \"Read model indexing time (WRITE_READY to READ_READY)\",\n unit: \"ms\",\n },\n ),\n readmodelCoordinatorChainDepth: meter.createObservableGauge(\n \"reactor.readmodel.coordinator.chain_depth\",\n {\n description:\n \"In-flight per-queueKey projection chains in the coordinator\",\n unit: \"{chain}\",\n },\n ),\n readmodelCoordinatorStageDuration: meter.createHistogram(\n \"reactor.readmodel.coordinator.stage.duration\",\n {\n description:\n \"Wall time per stage in ReadModelCoordinator.runChain (pre_ready, emit, post_ready)\",\n unit: \"ms\",\n },\n ),\n readmodelIndexingDuration: meter.createHistogram(\n \"reactor.readmodel.indexing.duration\",\n {\n description:\n \"Per-read-model indexing duration within a coordinator chain\",\n unit: \"ms\",\n },\n ),\n readmodelCoordinatorBatchSize: meter.createHistogram(\n \"reactor.readmodel.coordinator.batch.size\",\n {\n description: \"Operations per batch processed by the coordinator chain\",\n unit: \"{operation}\",\n },\n ),\n readmodelCoordinatorChainWaitDuration: meter.createHistogram(\n \"reactor.readmodel.coordinator.chain.wait_duration\",\n {\n description:\n \"Time a batch sat in the per-queueKey chain before runChain started\",\n unit: \"ms\",\n },\n ),\n\n // Postgres pool metrics\n dbPoolAcquireWaitDuration: meter.createHistogram(\n \"reactor.db.pool.acquire.wait_duration\",\n {\n description:\n \"Time spent waiting for a pg.Pool to hand out a client (pool.connect resolve latency)\",\n unit: \"ms\",\n },\n ),\n dbPoolSize: meter.createObservableGauge(\"reactor.db.pool.size\", {\n description: \"pg.Pool totalCount — connections currently open\",\n unit: \"{connection}\",\n }),\n dbPoolIdle: meter.createObservableGauge(\"reactor.db.pool.idle\", {\n description: \"pg.Pool idleCount — open connections not currently in use\",\n unit: \"{connection}\",\n }),\n dbPoolWaiting: meter.createObservableGauge(\"reactor.db.pool.waiting\", {\n description:\n \"pg.Pool waitingCount — callers queued waiting to acquire a connection\",\n unit: \"{request}\",\n }),\n\n // Event bus metrics\n eventbusEventsEmitted: meter.createCounter(\n \"reactor.eventbus.events.emitted\",\n {\n description: \"Events emitted\",\n unit: \"{event}\",\n },\n ),\n\n // Sync metrics\n syncRemotes: meter.createObservableGauge(\"reactor.sync.remotes\", {\n description: \"Active remote count\",\n unit: \"{remote}\",\n }),\n syncDeadLettersAdded: meter.createCounter(\n \"reactor.sync.dead_letters.added\",\n {\n description: \"Sync operations moved to dead letter storage\",\n unit: \"{operation}\",\n },\n ),\n\n // Read-side catch-up metrics\n catchupSequenceHead: meter.createObservableGauge(\n \"reactor.catchup.sequence_head\",\n {\n description: \"Highest ordinal the index sequence has handed out\",\n unit: \"{ordinal}\",\n },\n ),\n catchupSettledThrough: meter.createObservableGauge(\n \"reactor.catchup.settled_through\",\n {\n description:\n \"Every ordinal at or below this is visible or will never exist\",\n unit: \"{ordinal}\",\n },\n ),\n catchupSettleLag: meter.createObservableGauge(\n \"reactor.catchup.settle_lag\",\n {\n description: \"Sequence head minus the settled watermark\",\n unit: \"{ordinal}\",\n },\n ),\n catchupConsumerLag: meter.createObservableGauge(\n \"reactor.catchup.consumer_lag\",\n {\n description: \"Settled watermark minus a consumer's applied cursor\",\n unit: \"{ordinal}\",\n },\n ),\n catchupSweepDuration: meter.createHistogram(\n \"reactor.catchup.sweep.duration\",\n {\n description: \"Wall time of a catch-up sweep that moved or replayed\",\n unit: \"ms\",\n },\n ),\n catchupSweepReplayed: meter.createCounter(\n \"reactor.catchup.sweep.replayed\",\n {\n description: \"Operations a sweep applied that the live path never did\",\n unit: \"{operation}\",\n },\n ),\n catchupSweepFailures: meter.createCounter(\n \"reactor.catchup.sweep.failures\",\n {\n description: \"Sweeps that could not apply an operation\",\n unit: \"{sweep}\",\n },\n ),\n\n // Signature metrics\n signatureRefusals: meter.createCounter(\"reactor.signature.refusals\", {\n description:\n \"Writes that failed signature admission, refused or (in log mode) admitted\",\n unit: \"{operation}\",\n }),\n };\n}\n\nexport type ReactorMetrics = ReturnType<typeof createMetrics>;\n","import {\n JobExecutorEventTypes,\n ReactorEventTypes,\n SyncEventTypes,\n} from \"@powerhousedao/reactor\";\nimport type {\n CatchUpSweptEvent,\n DeadLetterAddedEvent,\n IEventBus,\n IJobExecutorManager,\n IQueue,\n JobCompletedEvent,\n JobFailedEvent as ExecutorJobFailedEvent,\n JobPendingEvent,\n JobReadReadyEvent,\n JobRunningEvent,\n JobWriteReadyEvent,\n PoolInstrumentation,\n ReactorJobFailedEvent,\n ReadModelBatchCompletedEvent,\n ReadModelIndexedEvent,\n SignatureRefusedEvent,\n IReadModelCoordinator,\n InProcessReactorModule,\n SyncModule,\n Unsubscribe,\n} from \"@powerhousedao/reactor\";\nimport type { ObservableCallback, ObservableGauge } from \"@opentelemetry/api\";\nimport { createMetrics, type ReactorMetrics } from \"./metrics.js\";\n\nexport class ReactorInstrumentation {\n private readonly module: InProcessReactorModule;\n private metrics: ReactorMetrics | undefined;\n private unsubscribes: Unsubscribe[] = [];\n private observableCallbacks: Array<[ObservableGauge, ObservableCallback]> =\n [];\n\n private pendingTimestamps = new Map<string, number>();\n private runningTimestamps = new Map<string, number>();\n private writeReadyTimestamps = new Map<string, number>();\n\n constructor(module: InProcessReactorModule) {\n this.module = module;\n }\n\n start(): void {\n this.metrics = createMetrics();\n const { eventBus, queue, executorManager, syncModule, pools } = this.module;\n\n this.subscribeJobPending(eventBus);\n this.subscribeJobRunning(eventBus);\n this.subscribeJobWriteReady(eventBus);\n this.subscribeJobReadReady(eventBus);\n this.subscribeJobFailed(eventBus);\n this.subscribeExecutorJobCompleted(eventBus);\n this.subscribeExecutorJobFailed(eventBus);\n this.subscribeDeadLetterAdded(eventBus);\n this.subscribeSignatureRefused(eventBus);\n this.subscribeReadModelBatchCompleted(eventBus);\n this.subscribeReadModelIndexed(eventBus);\n this.subscribeCatchUpSwept(eventBus);\n this.registerObservableGauges(\n queue,\n executorManager,\n this.module.readModelCoordinator,\n syncModule,\n );\n this.registerPoolInstrumentation(pools);\n this.registerCatchUpGauges();\n }\n\n stop(): void {\n for (const unsub of this.unsubscribes) {\n unsub();\n }\n this.unsubscribes = [];\n for (const [gauge, cb] of this.observableCallbacks) {\n gauge.removeCallback(cb);\n }\n this.observableCallbacks = [];\n this.pendingTimestamps.clear();\n this.runningTimestamps.clear();\n this.writeReadyTimestamps.clear();\n this.metrics = undefined;\n }\n\n private subscribeJobPending(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<JobPendingEvent>(\n ReactorEventTypes.JOB_PENDING,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.queueJobsEnqueued.add(1);\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"JOB_PENDING\",\n });\n this.pendingTimestamps.set(event.jobId, performance.now());\n },\n ),\n );\n }\n\n private subscribeJobRunning(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<JobRunningEvent>(\n ReactorEventTypes.JOB_RUNNING,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.queueJobsDequeued.add(1);\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"JOB_RUNNING\",\n });\n this.runningTimestamps.set(event.jobId, performance.now());\n },\n ),\n );\n }\n\n private subscribeJobWriteReady(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<JobWriteReadyEvent>(\n ReactorEventTypes.JOB_WRITE_READY,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.executorOperationsGenerated.add(event.operations.length);\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"JOB_WRITE_READY\",\n });\n this.writeReadyTimestamps.set(event.jobId, performance.now());\n },\n ),\n );\n }\n\n private subscribeJobReadReady(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<JobReadReadyEvent>(\n ReactorEventTypes.JOB_READ_READY,\n (_type, event) => {\n if (!this.metrics) return;\n const writeReadyTs = this.writeReadyTimestamps.get(event.jobId);\n if (writeReadyTs !== undefined) {\n this.metrics.readmodelIndexDuration.record(\n performance.now() - writeReadyTs,\n );\n }\n const pendingTs = this.pendingTimestamps.get(event.jobId);\n if (pendingTs !== undefined) {\n this.metrics.jobTotalDuration.record(\n performance.now() - pendingTs,\n { \"job.success\": \"true\" },\n );\n }\n this.metrics.queueJobsCompleted.add(1);\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"JOB_READ_READY\",\n });\n this.cleanup(event.jobId);\n },\n ),\n );\n }\n\n private subscribeJobFailed(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<ReactorJobFailedEvent>(\n ReactorEventTypes.JOB_FAILED,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.queueJobsFailed.add(1);\n const pendingTs = this.pendingTimestamps.get(event.jobId);\n if (pendingTs !== undefined) {\n this.metrics.jobTotalDuration.record(\n performance.now() - pendingTs,\n { \"job.success\": \"false\" },\n );\n }\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"JOB_FAILED\",\n });\n this.cleanup(event.jobId);\n },\n ),\n );\n }\n\n private subscribeExecutorJobCompleted(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<JobCompletedEvent>(\n JobExecutorEventTypes.JOB_COMPLETED,\n (_type, event) => {\n if (!this.metrics) return;\n const workerId = event.workerId ?? \"unknown\";\n const jobId = event.job.id;\n const runningTs = this.runningTimestamps.get(jobId);\n if (runningTs !== undefined) {\n this.metrics.executorJobDuration.record(\n performance.now() - runningTs,\n { \"job.success\": \"true\", \"worker.id\": workerId },\n );\n this.runningTimestamps.delete(jobId);\n }\n this.metrics.executorTotalProcessed.add(1, {\n \"job.success\": \"true\",\n \"worker.id\": workerId,\n });\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"EXECUTOR_JOB_COMPLETED\",\n });\n },\n ),\n );\n }\n\n private subscribeExecutorJobFailed(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<ExecutorJobFailedEvent>(\n JobExecutorEventTypes.JOB_FAILED,\n (_type, event) => {\n if (!this.metrics) return;\n const workerId = event.workerId ?? \"unknown\";\n const jobId = event.job.id;\n const runningTs = this.runningTimestamps.get(jobId);\n if (runningTs !== undefined) {\n this.metrics.executorJobDuration.record(\n performance.now() - runningTs,\n { \"job.success\": \"false\", \"worker.id\": workerId },\n );\n this.runningTimestamps.delete(jobId);\n }\n this.metrics.executorTotalProcessed.add(1, {\n \"job.success\": \"false\",\n \"worker.id\": workerId,\n });\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"EXECUTOR_JOB_FAILED\",\n });\n },\n ),\n );\n }\n\n private subscribeReadModelBatchCompleted(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<ReadModelBatchCompletedEvent>(\n ReactorEventTypes.READMODEL_BATCH_COMPLETED,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.readmodelCoordinatorChainWaitDuration.record(\n event.chainWaitDurationMs,\n );\n this.metrics.readmodelCoordinatorBatchSize.record(event.batchSize);\n this.metrics.readmodelCoordinatorStageDuration.record(\n event.preReadyDurationMs,\n { stage: \"pre_ready\" },\n );\n this.metrics.readmodelCoordinatorStageDuration.record(\n event.emitDurationMs,\n { stage: \"emit\" },\n );\n this.metrics.readmodelCoordinatorStageDuration.record(\n event.postReadyDurationMs,\n { stage: \"post_ready\" },\n );\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"READMODEL_BATCH_COMPLETED\",\n });\n },\n ),\n );\n }\n\n private subscribeReadModelIndexed(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<ReadModelIndexedEvent>(\n ReactorEventTypes.READMODEL_INDEXED,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.readmodelIndexingDuration.record(event.durationMs, {\n \"read_model.name\": event.readModelName,\n stage: event.stage,\n \"indexing.success\": event.success ? \"true\" : \"false\",\n });\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"READMODEL_INDEXED\",\n });\n },\n ),\n );\n }\n\n private subscribeCatchUpSwept(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<CatchUpSweptEvent>(\n ReactorEventTypes.CATCHUP_SWEPT,\n (_type, event) => {\n if (!this.metrics) return;\n const attrs = { consumer: event.consumerId, thread: event.thread };\n this.metrics.catchupSweepDuration.record(event.durationMs, attrs);\n if (event.replayed > 0) {\n this.metrics.catchupSweepReplayed.add(event.replayed, attrs);\n }\n if (event.blockedAt !== undefined) {\n this.metrics.catchupSweepFailures.add(1, attrs);\n }\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"CATCHUP_SWEPT\",\n });\n },\n ),\n );\n }\n\n private registerCatchUpGauges(): void {\n if (!this.metrics) return;\n const { catchUp } = this.module;\n const gauges: Array<[ObservableGauge, ObservableCallback]> = [\n [\n this.metrics.catchupSequenceHead,\n (result) => result.observe(catchUp.status().watermark.head),\n ],\n [\n this.metrics.catchupSettledThrough,\n (result) => result.observe(catchUp.status().watermark.settledThrough),\n ],\n [\n this.metrics.catchupSettleLag,\n (result) => {\n const { head, settledThrough } = catchUp.status().watermark;\n result.observe(Math.max(0, head - settledThrough));\n },\n ],\n [\n this.metrics.catchupConsumerLag,\n (result) => {\n const status = catchUp.status();\n for (const consumer of status.consumers) {\n result.observe(\n Math.max(\n 0,\n status.watermark.settledThrough - consumer.appliedThrough,\n ),\n { consumer: consumer.consumerId, thread: consumer.thread },\n );\n }\n },\n ],\n ];\n for (const [gauge, callback] of gauges) {\n gauge.addCallback(callback);\n this.observableCallbacks.push([gauge, callback]);\n }\n }\n\n private subscribeDeadLetterAdded(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<DeadLetterAddedEvent>(\n SyncEventTypes.DEAD_LETTER_ADDED,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.syncDeadLettersAdded.add(1, {\n \"remote.name\": event.remoteName,\n });\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"DEAD_LETTER_ADDED\",\n });\n },\n ),\n );\n }\n\n private subscribeSignatureRefused(eventBus: IEventBus): void {\n this.unsubscribes.push(\n eventBus.subscribe<SignatureRefusedEvent>(\n ReactorEventTypes.SIGNATURE_REFUSED,\n (_type, event) => {\n if (!this.metrics) return;\n this.metrics.signatureRefusals.add(1, {\n scheme: event.scheme,\n path: event.path,\n code: event.code,\n });\n this.metrics.eventbusEventsEmitted.add(1, {\n \"event.type\": \"SIGNATURE_REFUSED\",\n });\n },\n ),\n );\n }\n\n private registerObservableGauges(\n queue: IQueue,\n executorManager: IJobExecutorManager,\n readModelCoordinator: IReadModelCoordinator,\n syncModule: SyncModule | undefined,\n ): void {\n if (!this.metrics) return;\n\n const depthCb: ObservableCallback = async (result) => {\n if (!this.metrics) return;\n // queue.totalSize() is a DB query. If it exceeds the OTel collection\n // window the observation is silently dropped, making the gauge appear\n // to drop to zero under load. The timeout makes the failure explicit.\n const TIMEOUT_MS = 2_000;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n const depth = await Promise.race([\n queue.totalSize(),\n new Promise<never>((_, reject) => {\n timeoutId = setTimeout(\n () => reject(new Error(\"queue.totalSize() timed out\")),\n TIMEOUT_MS,\n );\n }),\n ]);\n result.observe(depth);\n } catch (err) {\n console.warn(\n \"[ReactorInstrumentation] queueDepth observation failed:\",\n err,\n );\n } finally {\n clearTimeout(timeoutId);\n }\n };\n this.metrics.queueDepth.addCallback(depthCb);\n this.observableCallbacks.push([this.metrics.queueDepth, depthCb]);\n\n const activeJobsCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n const status = executorManager.getStatus();\n result.observe(status.activeJobs);\n };\n this.metrics.executorActiveJobs.addCallback(activeJobsCb);\n this.observableCallbacks.push([\n this.metrics.executorActiveJobs,\n activeJobsCb,\n ]);\n\n const chainDepthCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n result.observe(readModelCoordinator.getChainDepth());\n };\n this.metrics.readmodelCoordinatorChainDepth.addCallback(chainDepthCb);\n this.observableCallbacks.push([\n this.metrics.readmodelCoordinatorChainDepth,\n chainDepthCb,\n ]);\n\n const remotesCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n const count = syncModule?.syncManager.list().length ?? 0;\n result.observe(count);\n };\n this.metrics.syncRemotes.addCallback(remotesCb);\n this.observableCallbacks.push([this.metrics.syncRemotes, remotesCb]);\n }\n\n private registerPoolInstrumentation(pools: PoolInstrumentation[]): void {\n if (!this.metrics || pools.length === 0) return;\n\n for (const pool of pools) {\n const attrs = { pool: pool.name };\n const unsub = pool.onAcquire((durationMs) => {\n if (!this.metrics) return;\n this.metrics.dbPoolAcquireWaitDuration.record(durationMs, attrs);\n });\n this.unsubscribes.push(unsub);\n }\n\n const sizeCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n for (const pool of pools) {\n const stats = pool.getStats();\n result.observe(stats.size, { pool: pool.name });\n }\n };\n this.metrics.dbPoolSize.addCallback(sizeCb);\n this.observableCallbacks.push([this.metrics.dbPoolSize, sizeCb]);\n\n const idleCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n for (const pool of pools) {\n const stats = pool.getStats();\n result.observe(stats.idle, { pool: pool.name });\n }\n };\n this.metrics.dbPoolIdle.addCallback(idleCb);\n this.observableCallbacks.push([this.metrics.dbPoolIdle, idleCb]);\n\n const waitingCb: ObservableCallback = (result) => {\n if (!this.metrics) return;\n for (const pool of pools) {\n const stats = pool.getStats();\n result.observe(stats.waiting, { pool: pool.name });\n }\n };\n this.metrics.dbPoolWaiting.addCallback(waitingCb);\n this.observableCallbacks.push([this.metrics.dbPoolWaiting, waitingCb]);\n }\n\n private cleanup(jobId: string): void {\n this.pendingTimestamps.delete(jobId);\n this.runningTimestamps.delete(jobId);\n this.writeReadyTimestamps.delete(jobId);\n }\n}\n","// Host event-loop and CPU instrumentation. Registers OTel observable\n// gauges on the global meter provider for monitorEventLoopDelay percentiles,\n// performance.eventLoopUtilization, and process.cpuUsage. Pure observation;\n// does not touch the reactor package. Started by the host process once its\n// meter provider is registered (switchboard: observability.mts; bench: main.ts).\nimport {\n metrics,\n type BatchObservableCallback,\n type BatchObservableResult,\n type Observable,\n} from \"@opentelemetry/api\";\nimport {\n monitorEventLoopDelay,\n performance,\n type EventLoopUtilization,\n} from \"node:perf_hooks\";\n\nconst METER_NAME = \"@powerhousedao/reactor-host\";\nconst DELAY_RESOLUTION_MS = 10;\nconst NS_PER_MS = 1_000_000;\nconst NS_PER_US = 1_000;\n\n/**\n * Handle returned by registerEventLoopInstrumentation. Calling stop()\n * disables the underlying monitorEventLoopDelay histogram and removes\n * the batch observable callback from the meter.\n */\nexport type EventLoopInstrumentation = {\n stop(): void;\n};\n\n/**\n * Registers six observable gauges on the host meter:\n *\n * reactor.host.eventloop.delay.{p50,p95,p99,max} (ms)\n * reactor.host.eventloop.utilization (ratio 0..1)\n * reactor.host.cpu.utilization (ratio, >1 if multi-core)\n *\n * The monitorEventLoopDelay histogram is reset on each scrape so each sample\n * represents the delay distribution over the prior scrape window rather than\n * process-lifetime cumulative. ELU and CPU deltas are computed against a\n * cached previous snapshot, also windowed to the prior scrape interval.\n */\nexport function registerEventLoopInstrumentation(): EventLoopInstrumentation {\n const meter = metrics.getMeter(METER_NAME);\n\n const histogram = monitorEventLoopDelay({ resolution: DELAY_RESOLUTION_MS });\n histogram.enable();\n\n const delayP50 = meter.createObservableGauge(\n \"reactor.host.eventloop.delay.p50\",\n {\n description: \"Event-loop callback delay p50 over the prior scrape window\",\n unit: \"ms\",\n },\n );\n const delayP95 = meter.createObservableGauge(\n \"reactor.host.eventloop.delay.p95\",\n {\n description: \"Event-loop callback delay p95 over the prior scrape window\",\n unit: \"ms\",\n },\n );\n const delayP99 = meter.createObservableGauge(\n \"reactor.host.eventloop.delay.p99\",\n {\n description: \"Event-loop callback delay p99 over the prior scrape window\",\n unit: \"ms\",\n },\n );\n const delayMax = meter.createObservableGauge(\n \"reactor.host.eventloop.delay.max\",\n {\n description: \"Event-loop callback delay max over the prior scrape window\",\n unit: \"ms\",\n },\n );\n const utilization = meter.createObservableGauge(\n \"reactor.host.eventloop.utilization\",\n {\n description:\n \"Event-loop utilization ratio (active / (active + idle)) over the prior scrape window\",\n unit: \"1\",\n },\n );\n const cpuUtilization = meter.createObservableGauge(\n \"reactor.host.cpu.utilization\",\n {\n description:\n \"Process CPU utilization over the prior scrape window. 1.0 = one core saturated.\",\n unit: \"1\",\n },\n );\n\n let prevElu: EventLoopUtilization = performance.eventLoopUtilization();\n let prevCpu: NodeJS.CpuUsage = process.cpuUsage();\n let prevHrtime: bigint = process.hrtime.bigint();\n\n const callback: BatchObservableCallback = (result: BatchObservableResult) => {\n const p50ms = histogram.percentile(50) / NS_PER_MS;\n const p95ms = histogram.percentile(95) / NS_PER_MS;\n const p99ms = histogram.percentile(99) / NS_PER_MS;\n const maxMs = histogram.max / NS_PER_MS;\n histogram.reset();\n\n const eluNow = performance.eventLoopUtilization();\n const eluDelta = performance.eventLoopUtilization(eluNow, prevElu);\n prevElu = eluNow;\n\n const cpuNow = process.cpuUsage();\n const hrtimeNow = process.hrtime.bigint();\n const cpuDeltaUs =\n cpuNow.user - prevCpu.user + (cpuNow.system - prevCpu.system);\n const elapsedUs = Number(hrtimeNow - prevHrtime) / NS_PER_US;\n const cpuRatio = elapsedUs > 0 ? cpuDeltaUs / elapsedUs : 0;\n prevCpu = cpuNow;\n prevHrtime = hrtimeNow;\n\n result.observe(delayP50, p50ms);\n result.observe(delayP95, p95ms);\n result.observe(delayP99, p99ms);\n result.observe(delayMax, maxMs);\n result.observe(utilization, eluDelta.utilization);\n result.observe(cpuUtilization, cpuRatio);\n };\n\n const observables: Observable[] = [\n delayP50,\n delayP95,\n delayP99,\n delayMax,\n utilization,\n cpuUtilization,\n ];\n\n meter.addBatchObservableCallback(callback, observables);\n\n return {\n stop(): void {\n meter.removeBatchObservableCallback(callback, observables);\n histogram.disable();\n },\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powerhousedao/opentelemetry-instrumentation-reactor",
|
|
3
|
-
"version": "6.2.3-
|
|
3
|
+
"version": "6.2.3-staging.0",
|
|
4
4
|
"description": "OpenTelemetry instrumentation for @powerhousedao/reactor",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -34,14 +34,18 @@
|
|
|
34
34
|
"@opentelemetry/api": "^1.9.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"
|
|
37
|
+
"@opentelemetry/sdk-metrics": "^2.7.1",
|
|
38
|
+
"@powerhousedao/reactor": "6.2.3-staging.0",
|
|
39
|
+
"tsdown": "0.23.0",
|
|
40
|
+
"vitest": "4.1.1"
|
|
38
41
|
},
|
|
39
42
|
"peerDependencies": {
|
|
40
|
-
"@powerhousedao/reactor": "6.2.3-
|
|
43
|
+
"@powerhousedao/reactor": "6.2.3-staging.0"
|
|
41
44
|
},
|
|
42
45
|
"scripts": {
|
|
43
46
|
"tsc": "tsc",
|
|
44
47
|
"build": "tsdown",
|
|
45
|
-
"
|
|
48
|
+
"test": "vitest --run",
|
|
49
|
+
"lint": "cd ../.. && oxlint packages/opentelemetry-instrumentation-reactor"
|
|
46
50
|
}
|
|
47
51
|
}
|