Skip to content

Commit 6d95fad

Browse files
committed
add event loop utilization logging as well
1 parent 50fa94d commit 6d95fad

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

apps/webapp/app/env.server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,8 @@ const EnvironmentSchema = z
11671167
AI_RUN_FILTER_MODEL: z.string().optional(),
11681168

11691169
EVENT_LOOP_MONITOR_THRESHOLD_MS: z.coerce.number().int().default(100),
1170+
EVENT_LOOP_MONITOR_UTILIZATION_INTERVAL_MS: z.coerce.number().int().default(1000),
1171+
EVENT_LOOP_MONITOR_UTILIZATION_SAMPLE_RATE: z.coerce.number().default(0.05),
11701172

11711173
VERY_SLOW_QUERY_THRESHOLD_MS: z.coerce.number().int().optional(),
11721174
})

apps/webapp/app/eventLoopMonitor.server.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { singleton } from "./utils/singleton";
33
import { tracer } from "./v3/tracer.server";
44
import { env } from "./env.server";
55
import { context, Context } from "@opentelemetry/api";
6+
import { performance } from "node:perf_hooks";
7+
import { logger } from "./services/logger.server";
68

79
const THRESHOLD_NS = env.EVENT_LOOP_MONITOR_THRESHOLD_MS * 1e6;
810

@@ -69,16 +71,46 @@ function after(asyncId: number) {
6971
export const eventLoopMonitor = singleton("eventLoopMonitor", () => {
7072
const hook = createHook({ init, before, after, destroy });
7173

74+
let stopEventLoopUtilizationMonitoring: () => void;
75+
7276
return {
7377
enable: () => {
7478
console.log("🥸 Initializing event loop monitor");
7579

7680
hook.enable();
81+
82+
stopEventLoopUtilizationMonitoring = startEventLoopUtilizationMonitoring();
7783
},
7884
disable: () => {
7985
console.log("🥸 Disabling event loop monitor");
8086

8187
hook.disable();
88+
89+
stopEventLoopUtilizationMonitoring?.();
8290
},
8391
};
8492
});
93+
94+
function startEventLoopUtilizationMonitoring() {
95+
let lastEventLoopUtilization = performance.eventLoopUtilization();
96+
97+
const interval = setInterval(() => {
98+
const currentEventLoopUtilization = performance.eventLoopUtilization();
99+
100+
const diff = performance.eventLoopUtilization(
101+
currentEventLoopUtilization,
102+
lastEventLoopUtilization
103+
);
104+
const utilization = Number.isFinite(diff.utilization) ? diff.utilization : 0;
105+
106+
if (Math.random() < env.EVENT_LOOP_MONITOR_UTILIZATION_SAMPLE_RATE) {
107+
logger.info("nodejs.event_loop.utilization", { utilization });
108+
}
109+
110+
lastEventLoopUtilization = currentEventLoopUtilization;
111+
}, env.EVENT_LOOP_MONITOR_UTILIZATION_INTERVAL_MS);
112+
113+
return () => {
114+
clearInterval(interval);
115+
};
116+
}

0 commit comments

Comments
 (0)