@@ -37,7 +37,7 @@ type Event = { line: string; stateRank: number; timestamp: number }
37
37
* we received it. Perhaps suboptimal, but we cannot guarantee that
38
38
* random log lines from applications are timestamped.
39
39
*/
40
- type LogLineRecord = { id : string ; logLine : string ; localMillis : number }
40
+ type LogLineRecord = { id : string ; line : string ; timestamp : number }
41
41
42
42
/**
43
43
* Maintain a model of live data from a given set of file streams
@@ -81,9 +81,11 @@ export default class Live {
81
81
tail . stream . on ( "data" , ( data ) => {
82
82
if ( data ) {
83
83
if ( tail . kind === "logs" ) {
84
+ // handle a log line
84
85
this . pushLineAndPublish ( stripColors ( data ) , cb )
85
86
}
86
87
88
+ // otherwise, treat it as an event
87
89
const line = stripAnsi ( data )
88
90
const cols = line . split ( / \s + / )
89
91
@@ -162,14 +164,28 @@ export default class Live {
162
164
return line . replace ( / \s * ( \d \d \d \d - \d \d - \d \d T \d \d : \d \d : \d \d ( \. \d + ) ? Z ) \s * / , "{timestamp}" )
163
165
}
164
166
167
+ /** Strip out the worker name from `line` */
168
+ private stripWorkerName ( line : string ) {
169
+ return line
170
+ . replace ( / p o d \/ \S + - t o r c h x - \S + / , "" ) // worker name in torchx
171
+ . replace ( / p o d \/ r a y - ( h e a d | w o r k e r ) - \S + / , "" ) // worker name in ray
172
+ . replace ( / \* / , "" ) // wildcard worker name (codeflare)
173
+ }
174
+
175
+ private stripPageClear ( line : string ) {
176
+ // eslint-disable-next-line no-control-regex
177
+ return line . replace ( / \x1b \x5B \[ 2 J / g, "" )
178
+ }
179
+
180
+ private prepareLineForUI ( line : string ) {
181
+ return this . stripPageClear ( this . stripWorkerName ( this . timestamped ( line ) ) )
182
+ }
183
+
165
184
private readonly lookup : Record < string , Event > = { }
166
185
/** Add `line` to our heap `this.events` */
167
186
private pushEvent ( line : string , metric : WorkerState , timestamp : number ) {
168
- const key = this . timestamped ( line )
169
- . replace ( / p o d \/ t o r c h x - \S + / , "" ) // worker name in torchx
170
- . replace ( / p o d \/ r a y - ( h e a d | w o r k e r ) - \S + / , "" ) // worker name in ray
171
- . replace ( / \* / , "" ) // wildcard worker name (codeflare)
172
- . replace ( / \x1b \x5B \[ 2 J / g, "" ) // eslint-disable-line no-control-regex
187
+ const key = this . prepareLineForUI ( line )
188
+
173
189
// ^^^ [2J is part of clear screen; we don't want those to flow through
174
190
175
191
const rec = {
@@ -202,7 +218,7 @@ export default class Live {
202
218
private readonly workerIdPattern = new RegExp ( "^(" + ansiRegex ( ) . source + ")?\\[([^\\]]+)\\]" )
203
219
204
220
private readonly timeSorter = ( a : LogLineRecord , b : LogLineRecord ) : number => {
205
- return a . localMillis - b . localMillis
221
+ return a . timestamp - b . timestamp
206
222
}
207
223
208
224
private readonly idSorter = ( a : LogLineRecord , b : LogLineRecord ) : number => {
@@ -217,16 +233,17 @@ export default class Live {
217
233
const match = logLine . match ( this . workerIdPattern )
218
234
const id = match ? match [ 2 ] : "notsure"
219
235
if ( id ) {
220
- this . logLine [ id ] = { id, logLine, localMillis : Date . now ( ) }
236
+ const idx = logLine . lastIndexOf ( " " )
237
+ const timestamp = idx < 0 ? undefined : this . asMillisSinceEpoch ( stripAnsi ( logLine . slice ( idx + 1 ) ) )
238
+ this . logLine [ id ] = { id, line : this . prepareLineForUI ( logLine ) , timestamp : timestamp || Date . now ( ) }
221
239
222
240
// display the k most recent logLines per worker, ordering the display by worker id
223
241
const k = 4
224
242
cb ( {
225
243
logLine : Object . values ( this . logLine )
226
244
. sort ( this . timeSorter ) // so we can pick off the most recent
227
245
. slice ( 0 , k ) // now pick off the k most recent
228
- . sort ( this . idSorter ) // sort those k by worker id, so there is a consistent ordering in the UI
229
- . map ( ( _ ) => _ . logLine ) , // and display just the logLine
246
+ . sort ( this . idSorter ) , // sort those k by worker id, so there is a consistent ordering in the UI
230
247
} )
231
248
}
232
249
}
0 commit comments