Skip to content

Commit 39d510f

Browse files
add additional utp data objects
1 parent 515eb9c commit 39d510f

3 files changed

Lines changed: 178 additions & 6 deletions

File tree

src/logging.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as fs from 'fs';
33
export enum LogLevel {
44
DEBUG = 'debug',
55
CI = 'ci',
6-
UTP = 'utp',
6+
UTP = 'utp', // minimal logging level
77
INFO = 'info',
88
WARN = 'warning',
99
ERROR = 'error',

src/unity-logging.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@ import * as fs from 'fs';
22
import * as path from 'path';
33
import { LogLevel, Logger } from './logging';
44
import { Delay, WaitForFileToBeUnlocked } from './utilities';
5-
import { Phase, Severity, UTP, UTPBase, UTPMemoryLeak, UTPPlayerBuildInfo } from './utp/utp';
5+
import {
6+
Phase,
7+
Severity,
8+
UTP,
9+
UTPBase,
10+
UTPMemoryLeak,
11+
UTPPlayerBuildInfo,
12+
normalizeTelemetryEntry
13+
} from './utp/utp';
614

715
/**
816
* Result of the tailLogFile function containing cleanup resources.
@@ -977,7 +985,7 @@ export function TailLogFile(logPath: string, projectPath: string | undefined): L
977985
if (!sanitizedJson) { return; }
978986

979987
const utpJson = JSON.parse(sanitizedJson);
980-
const utp = utpJson as UTP;
988+
const utp = normalizeTelemetryEntry(utpJson);
981989
telemetry.push(utp);
982990

983991
if (utp.message && 'severity' in utp &&
@@ -989,7 +997,7 @@ export function TailLogFile(logPath: string, projectPath: string | undefined): L
989997
}
990998

991999
const file = utp.file ? utp.file.replace(/\\/g, '/') : undefined;
992-
const stacktrace = sanitizeStackTrace(utp.stacktrace);
1000+
const stacktrace = sanitizeStackTrace(utp.stackTrace);
9931001
const message = stacktrace == undefined ? utp.message : `${utp.message}\n${stacktrace}`;
9941002

9951003
if (!githubAnnotationPrefixRegex.test(message)) {
@@ -1051,6 +1059,7 @@ export function TailLogFile(logPath: string, projectPath: string | undefined): L
10511059
break;
10521060
}
10531061
default:
1062+
logger.warn(`UTP entry has unknown type: ${utp.type ?? 'undefined'}`);
10541063
// Print raw JSON for unhandled UTP types
10551064
writeStdoutThenTableContent(`${JSON.stringify(utp)}\n`);
10561065
break;

src/utp/utp.ts

Lines changed: 165 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Logger } from "../logging";
2+
13
export class UTPBase {
24
type?: string;
35
version?: number;
@@ -6,12 +8,15 @@ export class UTPBase {
68
processId?: number;
79
severity?: Severity;
810
message?: string;
9-
stacktrace?: string;
11+
stackTrace?: string;
1012
line?: number;
13+
lineNumber?: number;
1114
file?: string;
15+
fileName?: string;
1216
name?: string;
1317
description?: string;
1418
duration?: number;
19+
durationMicroseconds?: number;
1520
errors?: unknown[];
1621
}
1722

@@ -20,6 +25,87 @@ export class UTPMemoryLeak extends UTPBase {
2025
memoryLabels?: Record<string, number> | Array<Record<string, number>>;
2126
}
2227

28+
export class UTPLogEntry extends UTPBase { }
29+
30+
export class UTPTestPlan extends UTPBase {
31+
tests?: string[];
32+
}
33+
34+
export interface ScreenSettingsInfo {
35+
ScreenWidth?: number;
36+
ScreenHeight?: number;
37+
ScreenRefreshRate?: number;
38+
Fullscreen?: boolean;
39+
}
40+
41+
export class UTPScreenSettings extends UTPBase {
42+
ScreenSettings?: ScreenSettingsInfo;
43+
}
44+
45+
export interface PlayerSettingsInfo {
46+
ScriptingBackend?: string;
47+
MtRendering?: boolean;
48+
GraphicsJobs?: boolean;
49+
GpuSkinning?: boolean;
50+
GraphicsApi?: string;
51+
Batchmode?: string;
52+
StereoRenderingPath?: string;
53+
RenderThreadingMode?: string;
54+
AndroidMinimumSdkVersion?: string;
55+
AndroidTargetSdkVersion?: string;
56+
ScriptingRuntimeVersion?: string;
57+
AndroidTargetArchitecture?: string;
58+
StripEngineCode?: boolean;
59+
}
60+
61+
export class UTPPlayerSettings extends UTPBase {
62+
PlayerSettings?: PlayerSettingsInfo;
63+
}
64+
65+
export interface BuildSettingsInfo {
66+
Platform?: string;
67+
BuildTarget?: string;
68+
DevelopmentPlayer?: boolean;
69+
AndroidBuildSystem?: string;
70+
}
71+
72+
export class UTPBuildSettings extends UTPBase {
73+
BuildSettings?: BuildSettingsInfo;
74+
}
75+
76+
export interface PlayerSystemInfoDetails {
77+
OperatingSystem?: string;
78+
DeviceModel?: string;
79+
DeviceName?: string;
80+
ProcessorType?: string;
81+
ProcessorCount?: number;
82+
GraphicsDeviceName?: string;
83+
SystemMemorySize?: number;
84+
XrModel?: string;
85+
XrDevice?: string;
86+
}
87+
88+
export class UTPPlayerSystemInfo extends UTPBase {
89+
PlayerSystemInfo?: PlayerSystemInfoDetails;
90+
}
91+
92+
export interface QualitySettingsInfo {
93+
Vsync?: number;
94+
AntiAliasing?: number;
95+
ColorSpace?: string;
96+
AnisotropicFiltering?: string;
97+
BlendWeights?: string;
98+
}
99+
100+
export class UTPQualitySettings extends UTPBase {
101+
QualitySettings?: QualitySettingsInfo;
102+
}
103+
104+
export class UTPTestStatus extends UTPBase {
105+
state?: number;
106+
iteration?: number;
107+
}
108+
23109
export interface PlayerBuildInfoStep {
24110
description?: string;
25111
duration?: number;
@@ -30,7 +116,18 @@ export class UTPPlayerBuildInfo extends UTPBase {
30116
steps?: PlayerBuildInfoStep[];
31117
}
32118

33-
export type UTP = UTPBase | UTPMemoryLeak | UTPPlayerBuildInfo;
119+
export type UTP =
120+
| UTPBase
121+
| UTPLogEntry
122+
| UTPTestPlan
123+
| UTPScreenSettings
124+
| UTPPlayerSettings
125+
| UTPBuildSettings
126+
| UTPPlayerSystemInfo
127+
| UTPQualitySettings
128+
| UTPTestStatus
129+
| UTPMemoryLeak
130+
| UTPPlayerBuildInfo;
34131

35132
export enum Phase {
36133
Begin = 'Begin',
@@ -44,4 +141,70 @@ export enum Severity {
44141
Error = 'Error',
45142
Exception = 'Exception',
46143
Assert = 'Assert'
144+
}
145+
146+
const allowedUtpKeys = new Set<string>([
147+
'allocatedMemory',
148+
'BuildSettings',
149+
'description',
150+
'duration',
151+
'durationMicroseconds',
152+
'errors',
153+
'file',
154+
'fileName',
155+
'iteration',
156+
'line',
157+
'lineNumber',
158+
'memoryLabels',
159+
'message',
160+
'name',
161+
'phase',
162+
'PlayerSettings',
163+
'PlayerSystemInfo',
164+
'processId',
165+
'QualitySettings',
166+
'ScreenSettings',
167+
'severity',
168+
'stackTrace',
169+
'state',
170+
'steps',
171+
'tests',
172+
'time',
173+
'type',
174+
'version',
175+
]);
176+
177+
/**
178+
* Normalizes UTP telemetry entries to canonical shapes and reports unexpected properties.
179+
* Accepts an optional warn callback to avoid importing logging dependencies here.
180+
*/
181+
export function normalizeTelemetryEntry(entry: unknown): UTP {
182+
if (!entry || typeof entry !== 'object') {
183+
return entry as UTP;
184+
}
185+
186+
const utp = entry as UTP;
187+
const record = entry as Record<string, unknown>;
188+
189+
const stackTraceLegacy = record.stacktrace;
190+
if (utp.stackTrace === undefined && typeof stackTraceLegacy === 'string') {
191+
utp.stackTrace = stackTraceLegacy;
192+
}
193+
194+
if (!utp.type) {
195+
Logger.instance.warn('UTP entry missing type property; telemetry entry may be ignored.');
196+
}
197+
198+
const extras: string[] = [];
199+
for (const key of Object.keys(record)) {
200+
if (!allowedUtpKeys.has(key)) {
201+
extras.push(key);
202+
}
203+
}
204+
205+
if (extras.length > 0) {
206+
Logger.instance.warn(`UTP entry contains unrecognized properties: ${extras.join(', ')}`);
207+
}
208+
209+
return utp;
47210
}

0 commit comments

Comments
 (0)