@@ -95,7 +95,7 @@ class ActionTelemetryAccumulator {
9595 private totalErrorCount = 0 ;
9696 private playerBuildInfoSteps : PlayerBuildInfoStepSummary [ ] = [ ] ;
9797
98- record ( action : UTPBase ) : boolean {
98+ public record ( action : UTPBase ) : boolean {
9999 if ( action . phase === Phase . Begin ) {
100100 this . pendingActions . set ( this . getActionKey ( action ) , action ) ;
101101 return true ;
@@ -133,7 +133,7 @@ class ActionTelemetryAccumulator {
133133 return false ;
134134 }
135135
136- recordPlayerBuildInfo ( info : UTPPlayerBuildInfo ) : boolean {
136+ public recordPlayerBuildInfo ( info : UTPPlayerBuildInfo ) : boolean {
137137 if ( ! Array . isArray ( info . steps ) || info . steps . length === 0 ) {
138138 return false ;
139139 }
@@ -162,7 +162,7 @@ class ActionTelemetryAccumulator {
162162 return true ;
163163 }
164164
165- snapshot ( ) : ActionTableSnapshot | undefined {
165+ public snapshot ( ) : ActionTableSnapshot | undefined {
166166 if ( this . completedActions . length === 0 && this . pendingActions . size === 0 && this . playerBuildInfoSteps . length === 0 ) {
167167 return undefined ;
168168 }
@@ -902,14 +902,13 @@ function formatMemoryLeakTable(memLeaks: UTPMemoryLeak): string {
902902
903903function buildUtpLogPath ( logPath : string ) : string {
904904 const parsed = path . parse ( logPath ) ;
905- const utpFileName = `utp- ${ parsed . name } . json` ;
905+ const utpFileName = `${ parsed . name } -utp- json.log ` ;
906906 return parsed . dir ? path . join ( parsed . dir , utpFileName ) : utpFileName ;
907907}
908908
909909async function writeUtpTelemetryLog ( filePath : string , entries : UTP [ ] , logger : Logger ) : Promise < void > {
910910 try {
911- const content = `${ JSON . stringify ( entries , null , 2 ) } \n` ;
912- await fs . promises . writeFile ( filePath , content , 'utf8' ) ;
911+ await fs . promises . writeFile ( filePath , `${ JSON . stringify ( entries ) } \n` , 'utf8' ) ;
913912 } catch ( error ) {
914913 logger . warn ( `Failed to write UTP telemetry log (${ filePath } ): ${ error } ` ) ;
915914 }
@@ -940,21 +939,52 @@ export function TailLogFile(logPath: string, projectPath: string | undefined): L
940939 } ;
941940
942941 const flushTelemetryLog = async ( ) : Promise < void > => {
943- if ( telemetryFlushed ) {
944- return ;
945- }
942+ if ( telemetryFlushed ) { return ; }
946943 telemetryFlushed = true ;
947944 await writeUtpTelemetryLog ( utpLogPath , telemetry , logger ) ;
948945 } ;
949946
950- const writeStdout = ( content : string , restoreTable : boolean = true ) : void => {
947+ const writeStdoutThenTableContent = ( content : string , restoreTable : boolean = true ) : void => {
951948 actionTableRenderer . prepareForContent ( ) ;
952949 process . stdout . write ( content ) ;
953950 if ( restoreTable ) {
954951 renderActionTable ( ) ;
955952 }
956953 } ;
957954
955+ function printUTP ( utp : UTP ) : void {
956+ // switch utp types, fallback to json if we don't have a toString() implementation or a type implementation
957+ switch ( utp . type ) {
958+ case 'Action' : {
959+ const actionEntry = utp as UTPBase ;
960+ const tableChanged = actionAccumulator . record ( actionEntry ) ;
961+
962+ if ( tableChanged ) {
963+ renderActionTable ( ) ;
964+ }
965+
966+ break ;
967+ }
968+ case 'MemoryLeaks' :
969+ logger . debug ( formatMemoryLeakTable ( utp as UTPMemoryLeak ) ) ;
970+ break ;
971+ case 'PlayerBuildInfo' : {
972+ const infoEntry = utp as UTPPlayerBuildInfo ;
973+ const changed = actionAccumulator . recordPlayerBuildInfo ( infoEntry ) ;
974+
975+ if ( changed ) {
976+ renderActionTable ( ) ;
977+ }
978+
979+ break ;
980+ }
981+ default :
982+ // Print raw JSON for unhandled UTP types
983+ writeStdoutThenTableContent ( `${ JSON . stringify ( utp ) } \n` ) ;
984+ break ;
985+ }
986+ }
987+
958988 async function readNewLogContent ( ) : Promise < void > {
959989 try {
960990 if ( ! fs . existsSync ( logPath ) ) { return ; }
@@ -990,10 +1020,7 @@ export function TailLogFile(logPath: string, projectPath: string | undefined): L
9901020 const jsonPart = line . substring ( '##utp:' . length ) . trim ( ) ;
9911021 try {
9921022 const sanitizedJson = sanitizeTelemetryJson ( jsonPart ) ;
993-
994- if ( ! sanitizedJson ) {
995- continue ;
996- }
1023+ if ( ! sanitizedJson ) { continue ; }
9971024
9981025 const utpJson = JSON . parse ( sanitizedJson ) ;
9991026 const utp = utpJson as UTP ;
@@ -1030,44 +1057,15 @@ export function TailLogFile(logPath: string, projectPath: string | undefined): L
10301057 }
10311058 }
10321059 }
1033- } else {
1034- // switch utp types, fallback to json if we don't have a toString() implementation or a type implementation
1035- switch ( utp . type ) {
1036- case 'Action' : {
1037- const actionEntry = utp as UTPBase ;
1038- const tableChanged = actionAccumulator . record ( actionEntry ) ;
1039-
1040- if ( tableChanged ) {
1041- renderActionTable ( ) ;
1042- }
1043-
1044- break ;
1045- }
1046- case 'MemoryLeaks' :
1047- logger . debug ( formatMemoryLeakTable ( utp as UTPMemoryLeak ) ) ;
1048- break ;
1049- case 'PlayerBuildInfo' : {
1050- const infoEntry = utp as UTPPlayerBuildInfo ;
1051- const changed = actionAccumulator . recordPlayerBuildInfo ( infoEntry ) ;
1052-
1053- if ( changed ) {
1054- renderActionTable ( ) ;
1055- }
1056-
1057- break ;
1058- }
1059- default :
1060- // Print raw JSON for unhandled UTP types
1061- writeStdout ( `${ jsonPart } \n` ) ;
1062- break ;
1063- }
1060+ } else if ( Logger . instance . logLevel === LogLevel . UTP ) {
1061+ printUTP ( utp ) ;
10641062 }
10651063 } catch ( error ) {
10661064 logger . warn ( `Failed to parse telemetry JSON: ${ error } -- raw: ${ jsonPart } ` ) ;
10671065 }
10681066 } else {
10691067 if ( Logger . instance . logLevel !== LogLevel . UTP ) {
1070- writeStdout ( `${ line } \n` ) ;
1068+ process . stdout . write ( `${ line } \n` ) ;
10711069 }
10721070 }
10731071 }
@@ -1098,7 +1096,7 @@ export function TailLogFile(logPath: string, projectPath: string | undefined): L
10981096
10991097 try {
11001098 // write a final newline to separate log output
1101- writeStdout ( '\n' ) ;
1099+ process . stdout . write ( '\n' ) ;
11021100 } catch ( error : any ) {
11031101 if ( error . code !== 'EPIPE' ) {
11041102 logger . warn ( `Error while writing log tail: ${ error } ` ) ;
0 commit comments