@@ -67,8 +67,8 @@ export class BuildMonitor {
67
67
private static instance : BuildMonitor ;
68
68
private logger : Logger ;
69
69
private sequenceMetrics : Map < string , SequenceMetrics > = new Map ( ) ;
70
- private static timeRecorders : Map < string , any [ ] > = new Map ( ) ;
71
- private static model = OpenAIModelProvider . getInstance ( ) ;
70
+ private timeRecorders : Map < string , any [ ] > = new Map ( ) ;
71
+ private model = OpenAIModelProvider . getInstance ( ) ;
72
72
73
73
private constructor ( ) {
74
74
this . logger = new Logger ( 'BuildMonitor' ) ;
@@ -81,7 +81,7 @@ export class BuildMonitor {
81
81
return BuildMonitor . instance ;
82
82
}
83
83
84
- public static async timeRecorder (
84
+ public async timeRecorder (
85
85
generateDuration : number ,
86
86
name : string ,
87
87
step : string ,
@@ -103,13 +103,45 @@ export class BuildMonitor {
103
103
104
104
// Node-level monitoring
105
105
startNodeExecution ( nodeId : string , sequenceId : string ) : void {
106
- const metrics = this . getOrCreateNodeMetrics ( nodeId , sequenceId ) ;
107
- metrics . startTime = Date . now ( ) ;
108
- metrics . status = 'pending' ;
106
+ let sequenceMetrics = this . sequenceMetrics . get ( sequenceId ) ;
107
+
108
+ // Create sequence metrics if not exists
109
+ if ( ! sequenceMetrics ) {
110
+ sequenceMetrics = {
111
+ sequenceId,
112
+ startTime : Date . now ( ) ,
113
+ endTime : 0 ,
114
+ duration : 0 ,
115
+ nodeMetrics : new Map ( ) ,
116
+ nodesOrder : [ ] ,
117
+ totalNodes : 0 , // Will be updated when we know the total
118
+ completedNodes : 0 ,
119
+ failedNodes : 0 ,
120
+ successRate : 0 ,
121
+ } ;
122
+ this . sequenceMetrics . set ( sequenceId , sequenceMetrics ) ;
123
+ }
124
+
125
+ // Create or get node metrics
126
+ if ( ! sequenceMetrics . nodeMetrics . has ( nodeId ) ) {
127
+ sequenceMetrics . nodeMetrics . set ( nodeId , {
128
+ nodeId,
129
+ startTime : Date . now ( ) ,
130
+ endTime : 0 ,
131
+ duration : 0 ,
132
+ status : 'pending' ,
133
+ retryCount : 0 ,
134
+ } ) ;
135
+ // Update total nodes count
136
+ sequenceMetrics . totalNodes ++ ;
137
+ }
138
+
139
+ const nodeMetrics = sequenceMetrics . nodeMetrics . get ( nodeId ) ! ;
140
+ nodeMetrics . startTime = Date . now ( ) ;
141
+ nodeMetrics . status = 'pending' ;
109
142
110
143
// Add node to execution order if not already present
111
- const sequenceMetrics = this . sequenceMetrics . get ( sequenceId ) ;
112
- if ( sequenceMetrics && ! sequenceMetrics . nodesOrder . includes ( nodeId ) ) {
144
+ if ( ! sequenceMetrics . nodesOrder . includes ( nodeId ) ) {
113
145
sequenceMetrics . nodesOrder . push ( nodeId ) ;
114
146
}
115
147
}
@@ -120,21 +152,60 @@ export class BuildMonitor {
120
152
success : boolean ,
121
153
error ?: Error ,
122
154
) : void {
123
- const metrics = this . getOrCreateNodeMetrics ( nodeId , sequenceId ) ;
124
- metrics . endTime = Date . now ( ) ;
125
- metrics . duration = metrics . endTime - metrics . startTime ;
126
- metrics . status = success ? 'completed' : 'failed' ;
127
- if ( error ) {
128
- metrics . error = error ;
155
+ let sequenceMetrics = this . sequenceMetrics . get ( sequenceId ) ;
156
+
157
+ // Create sequence metrics if not exists
158
+ if ( ! sequenceMetrics ) {
159
+ this . startNodeExecution ( nodeId , sequenceId ) ;
160
+ sequenceMetrics = this . sequenceMetrics . get ( sequenceId ) ! ;
161
+ }
162
+
163
+ const nodeMetrics = sequenceMetrics . nodeMetrics . get ( nodeId ) ;
164
+ if ( ! nodeMetrics ) {
165
+ // Create node metrics if not exists
166
+ sequenceMetrics . nodeMetrics . set ( nodeId , {
167
+ nodeId,
168
+ startTime : Date . now ( ) - 1 , // Set a minimal duration
169
+ endTime : Date . now ( ) ,
170
+ duration : 1 ,
171
+ status : success ? 'completed' : 'failed' ,
172
+ retryCount : 0 ,
173
+ error : error ,
174
+ } ) ;
175
+ sequenceMetrics . totalNodes ++ ;
176
+ if ( ! sequenceMetrics . nodesOrder . includes ( nodeId ) ) {
177
+ sequenceMetrics . nodesOrder . push ( nodeId ) ;
178
+ }
179
+ } else {
180
+ nodeMetrics . endTime = Date . now ( ) ;
181
+ nodeMetrics . duration = nodeMetrics . endTime - nodeMetrics . startTime ;
182
+ nodeMetrics . status = success ? 'completed' : 'failed' ;
183
+ if ( error ) {
184
+ nodeMetrics . error = error ;
185
+ }
129
186
}
130
187
131
188
// Update sequence metrics
132
189
this . updateSequenceMetrics ( sequenceId ) ;
133
190
}
134
191
135
192
incrementNodeRetry ( nodeId : string , sequenceId : string ) : void {
136
- const metrics = this . getOrCreateNodeMetrics ( nodeId , sequenceId ) ;
137
- metrics . retryCount ++ ;
193
+ let sequenceMetrics = this . sequenceMetrics . get ( sequenceId ) ;
194
+
195
+ // Create sequence metrics if not exists
196
+ if ( ! sequenceMetrics ) {
197
+ this . startNodeExecution ( nodeId , sequenceId ) ;
198
+ sequenceMetrics = this . sequenceMetrics . get ( sequenceId ) ! ;
199
+ }
200
+
201
+ let nodeMetrics = sequenceMetrics . nodeMetrics . get ( nodeId ) ;
202
+ if ( ! nodeMetrics ) {
203
+ // Create node metrics if not exists
204
+ this . startNodeExecution ( nodeId , sequenceId ) ;
205
+ nodeMetrics = sequenceMetrics . nodeMetrics . get ( nodeId ) ! ;
206
+ }
207
+
208
+ nodeMetrics . retryCount ++ ;
138
209
}
139
210
140
211
// Sequence-level monitoring
@@ -159,24 +230,30 @@ export class BuildMonitor {
159
230
projectUUID : string ,
160
231
) : Promise < void > {
161
232
const metrics = this . sequenceMetrics . get ( sequenceId ) ;
162
- if ( metrics ) {
163
- metrics . endTime = Date . now ( ) ;
164
- metrics . duration = metrics . endTime - metrics . startTime ;
233
+ if ( ! metrics ) {
234
+ throw new Error ( `No metrics found for sequence ${ sequenceId } ` ) ;
235
+ }
165
236
166
- this . updateSequenceMetrics ( sequenceId ) ;
237
+ metrics . endTime = Date . now ( ) ;
238
+ metrics . duration = metrics . endTime - metrics . startTime ;
167
239
168
- const report = await this . generateStructuredReport (
169
- sequenceId ,
170
- projectUUID ,
171
- ) ;
172
- await ProjectEventLogger . getInstance ( ) . logEvent ( {
173
- timestamp : report . metadata . timestamp ,
174
- projectId : report . metadata . projectId ,
175
- eventId : `build-${ report . metadata . sequenceId } ` ,
176
- type : 'BUILD_METRICS' ,
177
- data : report ,
178
- } ) ;
179
- }
240
+ this . updateSequenceMetrics ( sequenceId ) ;
241
+
242
+ // Generate and log the report
243
+ const report = await this . generateStructuredReport ( sequenceId , projectUUID ) ;
244
+ await ProjectEventLogger . getInstance ( ) . logEvent ( {
245
+ timestamp : report . metadata . timestamp ,
246
+ projectId : report . metadata . projectId ,
247
+ eventId : `build-${ report . metadata . sequenceId } ` ,
248
+ type : 'BUILD_METRICS' ,
249
+ data : report ,
250
+ } ) ;
251
+
252
+ // Clean up sequence metrics and time recorders after logging
253
+ this . sequenceMetrics . delete ( sequenceId ) ;
254
+ metrics . nodesOrder . forEach ( ( nodeId ) => {
255
+ this . timeRecorders . delete ( nodeId ) ;
256
+ } ) ;
180
257
}
181
258
182
259
private updateSequenceMetrics ( sequenceId : string ) : void {
@@ -192,28 +269,6 @@ export class BuildMonitor {
192
269
}
193
270
}
194
271
195
- private getOrCreateNodeMetrics (
196
- nodeId : string ,
197
- sequenceId : string ,
198
- ) : NodeMetrics {
199
- const sequenceMetrics = this . sequenceMetrics . get ( sequenceId ) ;
200
- if ( ! sequenceMetrics ) {
201
- throw new Error ( `No metrics found for sequence ${ sequenceId } ` ) ;
202
- }
203
-
204
- if ( ! sequenceMetrics . nodeMetrics . has ( nodeId ) ) {
205
- sequenceMetrics . nodeMetrics . set ( nodeId , {
206
- nodeId,
207
- startTime : 0 ,
208
- endTime : 0 ,
209
- duration : 0 ,
210
- status : 'pending' ,
211
- retryCount : 0 ,
212
- } ) ;
213
- }
214
- return sequenceMetrics . nodeMetrics . get ( nodeId ) ! ;
215
- }
216
-
217
272
async generateStructuredReport (
218
273
sequenceId : string ,
219
274
projectUUID : string ,
@@ -228,7 +283,7 @@ export class BuildMonitor {
228
283
const nodeMetric = metrics . nodeMetrics . get ( nodeId ) ;
229
284
if ( ! nodeMetric ) return null ;
230
285
231
- const values = BuildMonitor . timeRecorders . get ( nodeId ) ;
286
+ const values = this . timeRecorders . get ( nodeId ) ;
232
287
return {
233
288
id : nodeId ,
234
289
name : nodeId ,
@@ -254,7 +309,7 @@ export class BuildMonitor {
254
309
duration : metrics . duration ,
255
310
} ,
256
311
summary : {
257
- spendTime : Array . from ( BuildMonitor . timeRecorders . entries ( ) ) . map (
312
+ spendTime : Array . from ( this . timeRecorders . entries ( ) ) . map (
258
313
( [ id , time ] ) => `Node ${ id } duration is ${ time } ms` ,
259
314
) ,
260
315
totalNodes : metrics . totalNodes ,
@@ -288,7 +343,7 @@ export class BuildMonitor {
288
343
report += ` Duration: ${ nodeMetric . duration } ms\n` ;
289
344
report += ` Retries: ${ nodeMetric . retryCount } \n` ;
290
345
291
- const values = BuildMonitor . timeRecorders . get ( nodeId ) ;
346
+ const values = this . timeRecorders . get ( nodeId ) ;
292
347
if ( values ) {
293
348
report += ` Clock:\n` ;
294
349
values . forEach ( ( value ) => {
0 commit comments