@@ -57,6 +57,7 @@ import { flattenAttributes } from "@trigger.dev/core/v3";
5757import { prisma } from "~/db.server" ;
5858import { metricsRegister } from "~/metrics.server" ;
5959import type { Prisma } from "@trigger.dev/database" ;
60+ import { performance } from "node:perf_hooks" ;
6061
6162export const SEMINTATTRS_FORCE_RECORDING = "forceRecording" ;
6263
@@ -602,10 +603,17 @@ function configureNodejsMetrics({ meter }: { meter: Meter }) {
602603 description : "Event loop 99th percentile delay" ,
603604 unit : "s" ,
604605 } ) ;
606+ // ELU observable gauge (unit is a ratio, 0..1)
607+ const eluGauge = meter . createObservableGauge ( "nodejs.event_loop.utilization" , {
608+ description : "Event loop utilization over the last collection interval" ,
609+ unit : "1" , // OpenTelemetry convention for ratios
610+ } ) ;
605611
606612 // Get UV threadpool size (defaults to 4 if not set)
607613 const uvThreadpoolSize = parseInt ( process . env . UV_THREADPOOL_SIZE || "4" , 10 ) ;
608614
615+ let lastEventLoopUtilization = performance . eventLoopUtilization ( ) ;
616+
609617 // Single helper to read metrics from prom-client
610618 async function readNodeMetrics ( ) {
611619 const metrics = await metricsRegister . getMetricsAsJSON ( ) ;
@@ -648,6 +656,16 @@ function configureNodejsMetrics({ meter }: { meter: Meter }) {
648656 }
649657 }
650658
659+ const currentEventLoopUtilization = performance . eventLoopUtilization ( ) ;
660+ // Diff over [lastSnapshot, current]
661+ const diff = performance . eventLoopUtilization (
662+ currentEventLoopUtilization ,
663+ lastEventLoopUtilization
664+ ) ;
665+
666+ // diff.utilization is between 0 and 1 (fraction of time "active")
667+ const utilization = Number . isFinite ( diff . utilization ) ? diff . utilization : 0 ;
668+
651669 return {
652670 threadpoolSize : uvThreadpoolSize ,
653671 handlesByType,
@@ -661,6 +679,7 @@ function configureNodejsMetrics({ meter }: { meter: Meter }) {
661679 p50 : eventLoopLagP50 ?. values ?. [ 0 ] ?. value ?? 0 ,
662680 p90 : eventLoopLagP90 ?. values ?. [ 0 ] ?. value ?? 0 ,
663681 p99 : eventLoopLagP99 ?. values ?. [ 0 ] ?. value ?? 0 ,
682+ utilization,
664683 } ,
665684 } ;
666685 }
@@ -698,6 +717,7 @@ function configureNodejsMetrics({ meter }: { meter: Meter }) {
698717 res . observe ( eventLoopLagP50Gauge , eventLoop . p50 ) ;
699718 res . observe ( eventLoopLagP90Gauge , eventLoop . p90 ) ;
700719 res . observe ( eventLoopLagP99Gauge , eventLoop . p99 ) ;
720+ res . observe ( eluGauge , eventLoop . utilization ) ;
701721 } ,
702722 [
703723 uvThreadpoolSizeGauge ,
@@ -711,6 +731,7 @@ function configureNodejsMetrics({ meter }: { meter: Meter }) {
711731 eventLoopLagP50Gauge ,
712732 eventLoopLagP90Gauge ,
713733 eventLoopLagP99Gauge ,
734+ eluGauge ,
714735 ]
715736 ) ;
716737}
0 commit comments