1
1
import { Performance , performance } from "node:perf_hooks" ;
2
2
import { basename } from "node:path" ;
3
+ import { cpus } from "node:os" ;
3
4
4
5
// Global array to store complete events.
5
6
const traceEvents = [ ] ;
@@ -76,20 +77,24 @@ Performance.prototype.mark = function(name, options) {
76
77
} ) ;
77
78
return originalMark . call ( this , name , opt ) ;
78
79
} ;
79
-
80
- // Override measure to create complete events.
81
80
Performance . prototype . measure = function ( name , start , end , options ) {
82
81
const startEntry = performance . getEntriesByName ( start , 'mark' ) [ 0 ] ;
83
82
const endEntry = performance . getEntriesByName ( end , 'mark' ) [ 0 ] ;
84
83
let event = null ;
84
+
85
85
if ( startEntry && endEntry ) {
86
- const ts = startEntry . startTime * 1000 ; // Convert ms to microseconds.
86
+ const ts = startEntry . startTime * 1000 ; // Convert ms to µs
87
87
const dur = ( endEntry . startTime - startEntry . startTime ) * 1000 ;
88
88
89
- // Enrich event further if needed (here keeping it minimal to match your profile).
89
+ const correlationId = generateCorrelationId ( ) ;
90
+ const callFrame = ( startEntry . detail ?. callStack || [ ] ) [ 0 ] || { } ;
91
+ const file = ( callFrame . file || 'unknown' ) . replace ( process . cwd ( ) , '.' ) ;
92
+ const functionName = callFrame . functionName != null ? callFrame . functionName : 'anonymous' ;
93
+ const line = callFrame . line || null ;
94
+
90
95
event = {
91
- name,
92
- cat : 'measure' , // Keeping the same category as in your uploaded trace.
96
+ name : name . replace ( process . cwd ( ) , '' ) , // sometimes the name includes a path
97
+ cat : 'measure' ,
93
98
ph : 'X' ,
94
99
ts,
95
100
dur,
@@ -98,23 +103,29 @@ Performance.prototype.measure = function(name, start, end, options) {
98
103
args : {
99
104
startDetail : startEntry . detail || { } ,
100
105
endDetail : endEntry . detail || { } ,
101
- // Optionally: add correlation and extra labels.
102
- uiLabel : name
106
+ uiLabel : functionName ,
107
+ correlationId,
108
+ timestamp : new Date ( ) . toISOString ( ) ,
109
+ durationMs : dur / 1000 ,
110
+ file,
111
+ functionName,
112
+ line
103
113
}
104
114
} ;
105
115
106
- // Push metadata events once.
107
116
if ( traceEvents . length < 1 ) {
108
117
traceEvents . push ( threadMetadata ) ;
109
118
console . log ( `traceEvent:JSON:${ JSON . stringify ( threadMetadata ) } ` ) ;
110
119
traceEvents . push ( processMetadata ) ;
111
120
console . log ( `traceEvent:JSON:${ JSON . stringify ( processMetadata ) } ` ) ;
112
121
}
122
+
113
123
traceEvents . push ( event ) ;
114
124
console . log ( `traceEvent:JSON:${ JSON . stringify ( event ) } ` ) ;
115
125
} else {
116
126
console . warn ( 'Missing start or end mark for measure' , name ) ;
117
127
}
128
+
118
129
return originalMeasure . call ( this , name , start , end , options ) ;
119
130
} ;
120
131
@@ -124,7 +135,7 @@ performance.profile = function() {
124
135
metadata : {
125
136
source : "Nx Advanced Profiling" ,
126
137
startTime : Date . now ( ) / 1000 ,
127
- hardwareConcurrency : 12 ,
138
+ hardwareConcurrency : cpus ( ) . length ,
128
139
dataOrigin : "TraceEvents" ,
129
140
modifications : {
130
141
entriesModifications : {
0 commit comments