@@ -57,6 +57,7 @@ import { flattenAttributes } from "@trigger.dev/core/v3";
57
57
import { prisma } from "~/db.server" ;
58
58
import { metricsRegister } from "~/metrics.server" ;
59
59
import type { Prisma } from "@trigger.dev/database" ;
60
+ import { performance } from "node:perf_hooks" ;
60
61
61
62
export const SEMINTATTRS_FORCE_RECORDING = "forceRecording" ;
62
63
@@ -602,10 +603,17 @@ function configureNodejsMetrics({ meter }: { meter: Meter }) {
602
603
description : "Event loop 99th percentile delay" ,
603
604
unit : "s" ,
604
605
} ) ;
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
+ } ) ;
605
611
606
612
// Get UV threadpool size (defaults to 4 if not set)
607
613
const uvThreadpoolSize = parseInt ( process . env . UV_THREADPOOL_SIZE || "4" , 10 ) ;
608
614
615
+ let lastEventLoopUtilization = performance . eventLoopUtilization ( ) ;
616
+
609
617
// Single helper to read metrics from prom-client
610
618
async function readNodeMetrics ( ) {
611
619
const metrics = await metricsRegister . getMetricsAsJSON ( ) ;
@@ -648,6 +656,16 @@ function configureNodejsMetrics({ meter }: { meter: Meter }) {
648
656
}
649
657
}
650
658
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
+
651
669
return {
652
670
threadpoolSize : uvThreadpoolSize ,
653
671
handlesByType,
@@ -661,6 +679,7 @@ function configureNodejsMetrics({ meter }: { meter: Meter }) {
661
679
p50 : eventLoopLagP50 ?. values ?. [ 0 ] ?. value ?? 0 ,
662
680
p90 : eventLoopLagP90 ?. values ?. [ 0 ] ?. value ?? 0 ,
663
681
p99 : eventLoopLagP99 ?. values ?. [ 0 ] ?. value ?? 0 ,
682
+ utilization,
664
683
} ,
665
684
} ;
666
685
}
@@ -698,6 +717,7 @@ function configureNodejsMetrics({ meter }: { meter: Meter }) {
698
717
res . observe ( eventLoopLagP50Gauge , eventLoop . p50 ) ;
699
718
res . observe ( eventLoopLagP90Gauge , eventLoop . p90 ) ;
700
719
res . observe ( eventLoopLagP99Gauge , eventLoop . p99 ) ;
720
+ res . observe ( eluGauge , eventLoop . utilization ) ;
701
721
} ,
702
722
[
703
723
uvThreadpoolSizeGauge ,
@@ -711,6 +731,7 @@ function configureNodejsMetrics({ meter }: { meter: Meter }) {
711
731
eventLoopLagP50Gauge ,
712
732
eventLoopLagP90Gauge ,
713
733
eventLoopLagP99Gauge ,
734
+ eluGauge ,
714
735
]
715
736
) ;
716
737
}
0 commit comments