Skip to content

Commit b41e166

Browse files
padenotcanova
andauthored
Fix extractGeckoLogs for structured Log marker format (bug 2022540) (#5927)
Bug 2022540 switched Log markers from {module, name} fields to structured {level, message} fields, with the module name stored as the marker name. The old format used a single module string that could include the log level prefix (e.g. D/cubeb); the new format uses an integer level field. Profiles use one format exclusively, never a mix. We detect which by checking the first Log marker found in each thread. Co-authored-by: Nazım Can Altınova <canaltinova@gmail.com>
1 parent ac19bf3 commit b41e166

3 files changed

Lines changed: 90 additions & 24 deletions

File tree

src/test/unit/window-console.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,56 @@ describe('console-accessible values on the window object', function () {
112112
`);
113113
});
114114

115+
it('can extract gecko logs in new structured format', function () {
116+
const profile = getProfileWithMarkers([
117+
[
118+
'nsHttp',
119+
170,
120+
null,
121+
{
122+
type: 'Log',
123+
level: 1,
124+
message:
125+
'ParentChannelListener::ParentChannelListener [this=7fb5e19b98d0]',
126+
},
127+
],
128+
[
129+
'nsJarProtocol',
130+
190,
131+
null,
132+
{
133+
type: 'Log',
134+
level: 2,
135+
message: 'nsJARChannel::nsJARChannel [this=0x87f1ec80]\n',
136+
},
137+
],
138+
['cubeb', 200, null, { type: 'Log', level: 3, message: 'cubeb_init' }],
139+
[
140+
'AudioStream',
141+
210,
142+
null,
143+
{ type: 'Log', level: 4, message: 'AudioStream init\n' },
144+
],
145+
[
146+
'VideoSink',
147+
220,
148+
null,
149+
{ type: 'Log', level: 5, message: 'VideoSink::VideoSink' },
150+
],
151+
]);
152+
const store = storeWithProfile(profile);
153+
const target: MixedObject = {};
154+
addDataToWindowObject(store.getState, store.dispatch, target);
155+
const result = (target as any).extractGeckoLogs();
156+
expect(result).toBe(stripIndent`
157+
1970-01-01 00:00:00.170000000 UTC - [Unknown Process 0: Empty]: E/nsHttp ParentChannelListener::ParentChannelListener [this=7fb5e19b98d0]
158+
1970-01-01 00:00:00.190000000 UTC - [Unknown Process 0: Empty]: W/nsJarProtocol nsJARChannel::nsJARChannel [this=0x87f1ec80]
159+
1970-01-01 00:00:00.200000000 UTC - [Unknown Process 0: Empty]: I/cubeb cubeb_init
160+
1970-01-01 00:00:00.210000000 UTC - [Unknown Process 0: Empty]: D/AudioStream AudioStream init
161+
1970-01-01 00:00:00.220000000 UTC - [Unknown Process 0: Empty]: V/VideoSink VideoSink::VideoSink
162+
`);
163+
});
164+
115165
describe('totalMarkerDuration', function () {
116166
function setup(): ExtraPropertiesOnWindowForConsole {
117167
jest.spyOn(console, 'log').mockImplementation(() => {});

src/types/markers.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -634,11 +634,17 @@ export type ChromeEventPayload = {
634634
* Gecko includes rich log information. This marker payload is used to mirror that
635635
* log information in the profile.
636636
*/
637-
export type LogMarkerPayload = {
638-
type: 'Log';
639-
name: string;
640-
module: string;
641-
};
637+
export type LogMarkerPayload =
638+
| {
639+
type: 'Log';
640+
name: string;
641+
module: string;
642+
}
643+
| {
644+
type: 'Log';
645+
level: number;
646+
message: string;
647+
};
642648

643649
export type DOMEventMarkerPayload = {
644650
type: 'DOMEvent';

src/utils/window-console.ts

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {
99
Profile,
1010
Thread,
1111
Marker,
12+
LogMarkerPayload,
1213
} from 'firefox-profiler/types';
1314
import { selectorsForConsole } from 'firefox-profiler/selectors';
1415
import actions from 'firefox-profiler/actions';
@@ -297,36 +298,45 @@ export function addDataToWindowObject(
297298
const range =
298299
selectorsForConsole.profile.getPreviewSelectionRange(getState());
299300

301+
const LOG_LEVEL_LETTER: Record<number, string> = {
302+
1: 'E',
303+
2: 'W',
304+
3: 'I',
305+
4: 'D',
306+
5: 'V',
307+
};
308+
300309
for (const thread of profile.threads) {
301310
const { markers } = thread;
311+
302312
for (let i = 0; i < markers.length; i++) {
303313
const startTime = markers.startTime[i];
304-
// Note that Log markers are instant markers, so they only have a start time.
305314
if (
306315
startTime !== null &&
307-
markers.data[i] &&
308316
markers.data[i]?.type === 'Log' &&
309317
startTime >= range.start &&
310318
startTime <= range.end
311319
) {
312-
const data = markers.data[i];
313-
const markerStartTime = markers.startTime[i];
314-
if (
315-
data &&
316-
markerStartTime !== null &&
317-
(data as any).module &&
318-
(data as any).name
319-
) {
320-
const strTimestamp = d2s(profile.meta.startTime + markerStartTime);
321-
const processName = thread.processName ?? 'Unknown Process';
322-
323-
// The log module may contain the log level for profiles captured after bug 1995503.
324-
// If the log module does not contain /, we fake it to D/module
325-
const logModule = (data as any).module;
326-
const prefix = logModule.includes('/') ? '' : 'D/';
327-
const statement = `${strTimestamp} - [${processName} ${thread.pid}: ${thread.name}]: ${prefix}${logModule} ${(data as any).name.trim()}`;
328-
logs.push(statement);
320+
const data = markers.data[i] as LogMarkerPayload;
321+
const strTimestamp = d2s(profile.meta.startTime + startTime);
322+
const processName = thread.processName ?? 'Unknown Process';
323+
324+
let statement;
325+
if ('message' in data) {
326+
if (!data.message) {
327+
continue;
328+
}
329+
const moduleName = profile.shared.stringArray[markers.name[i]];
330+
const levelLetter = LOG_LEVEL_LETTER[data.level] ?? 'D';
331+
statement = `${strTimestamp} - [${processName} ${thread.pid}: ${thread.name}]: ${levelLetter}/${moduleName} ${data.message.trim()}`;
332+
} else {
333+
if (!data.name) {
334+
continue;
335+
}
336+
const prefix = data.module.includes('/') ? '' : 'D/';
337+
statement = `${strTimestamp} - [${processName} ${thread.pid}: ${thread.name}]: ${prefix}${data.module} ${data.name.trim()}`;
329338
}
339+
logs.push(statement);
330340
}
331341
}
332342
}

0 commit comments

Comments
 (0)