@@ -3,6 +3,8 @@ import { singleton } from "./utils/singleton";
33import { tracer } from "./v3/tracer.server" ;
44import { env } from "./env.server" ;
55import { context , Context } from "@opentelemetry/api" ;
6+ import { performance } from "node:perf_hooks" ;
7+ import { logger } from "./services/logger.server" ;
68
79const THRESHOLD_NS = env . EVENT_LOOP_MONITOR_THRESHOLD_MS * 1e6 ;
810
@@ -69,16 +71,46 @@ function after(asyncId: number) {
6971export 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