Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion profiler-cli/schemas.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ CounterSummary:
{
counterHandle, counterIndex, name, label, category,
unit, graphType,
color, pid, mainThreadIndex, mainThreadHandle, mainThreadName,
color, pid, processIndex, processName, etld1?,
mainThreadIndex, mainThreadHandle, mainThreadName,
rangeSampleCount,
stats: [{ source, label, value, formattedValue, carbon? }],
graph: [number]
Expand Down
17 changes: 16 additions & 1 deletion profiler-cli/src/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,20 @@ function formatCounterStats(counter: CounterSummary): string {
return `${stats} [${counter.rangeSampleCount} samples]`;
}

/** `p-N Process Name (etld+1)`, dropping the handle when the process is unknown. */
function formatCounterProcessName(counter: CounterSummary): string {
const handle = counter.processIndex >= 0 ? `p-${counter.processIndex} ` : '';
const etld1 = counter.etld1 ? ` (${counter.etld1})` : '';
return `${handle}${counter.processName}${etld1}`;
}

/** The ` [p-N Process Name (etld+1), pid X]` segment identifying the owning process. */
function formatCounterProcess(counter: CounterSummary): string {
return ` [${formatCounterProcessName(counter)}, pid ${counter.pid}]`;
}

function formatCounterSummaryLine(counter: CounterSummary): string {
return ` ${counter.counterHandle}: ${counter.label} (${counter.category})${formatCounterStats(counter)}`;
return ` ${counter.counterHandle}: ${counter.label} (${counter.category})${formatCounterProcess(counter)}${formatCounterStats(counter)}`;
}

/**
Expand Down Expand Up @@ -566,6 +578,9 @@ export function formatCounterInfoResult(
}
lines.push(` Unit: ${result.unit || '(none)'}`);
lines.push(` Graph type: ${result.graphType}`);
lines.push(
` Process: ${formatCounterProcessName(result)} [pid ${result.pid}]`
);
lines.push(
` Main thread: ${result.mainThreadHandle} (${result.mainThreadName})`
);
Expand Down
15 changes: 13 additions & 2 deletions profiler-cli/src/test/unit/counter-formatting.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ function makeCounter(overrides: Partial<CounterSummary> = {}): CounterSummary {
graphType: 'line-accumulated',
color: 'orange',
pid: '123',
processIndex: 0,
processName: 'Parent Process',
mainThreadIndex: 0,
mainThreadHandle: 't-0',
mainThreadName: 'GeckoMain',
Expand Down Expand Up @@ -64,6 +66,10 @@ describe('formatCounterListResult', function () {
label: 'Bandwidth',
category: 'Bandwidth',
graphType: 'line-rate',
processIndex: 3,
processName: 'Isolated Web Content',
etld1: 'example.com',
pid: '456',
stats: [
{
source: 'count-range',
Expand All @@ -78,10 +84,14 @@ describe('formatCounterListResult', function () {

const output = formatCounterListResult(result);
expect(output).toContain('Counters (2):');
expect(output).toContain('c-0: Memory (Memory)');
expect(output).toContain(
'c-0: Memory (Memory) [p-0 Parent Process, pid 123]'
);
expect(output).toContain('memory range in graph: 27B');
expect(output).toContain('[7 samples]');
expect(output).toContain('c-1: Bandwidth (Bandwidth)');
expect(output).toContain(
'c-1: Bandwidth (Bandwidth) [p-3 Isolated Web Content (example.com), pid 456]'
);
expect(output).toContain('Data transferred in the visible range: 2KB');
});

Expand Down Expand Up @@ -180,6 +190,7 @@ describe('formatCounterInfoResult', function () {
expect(output).toContain('Category: Memory');
expect(output).toContain('Unit: bytes');
expect(output).toContain('Graph type: line-accumulated');
expect(output).toContain('Process: p-0 Parent Process [pid 123]');
expect(output).toContain('Main thread: t-0 (GeckoMain)');
expect(output).toContain('Description: Amount of allocated memory');
expect(output).toContain('memory range in graph: 27B');
Expand Down
22 changes: 17 additions & 5 deletions src/profile-query/formatters/counter-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
} from 'firefox-profiler/components/timeline/TrackCounterTooltipFormat';
import { getSampleIndexRangeForSelection } from 'firefox-profiler/profile-logic/profile-data';
import { getCounterHandle, parseCounterHandle } from '../counter-map';
import { getProcessName } from '../process-thread-list';
import type {
CounterIndex,
CounterDisplayConfig,
Expand Down Expand Up @@ -184,6 +185,7 @@ function collectCounterStats(
export function collectCounterSummary(
store: Store,
threadMap: ThreadMap,
processIndexMap: Map<string, number>,
counterIndex: CounterIndex
): CounterSummary {
const state = store.getState();
Expand All @@ -197,7 +199,7 @@ export function collectCounterSummary(
counterIndex
);

const mainThreadName = profile.threads[counter.mainThreadIndex]?.name ?? '';
const mainThread = profile.threads[counter.mainThreadIndex];

return {
counterHandle: getCounterHandle(counterIndex),
Expand All @@ -209,9 +211,12 @@ export function collectCounterSummary(
graphType: display.graphType,
color: display.color,
pid: counter.pid,
processIndex: processIndexMap.get(counter.pid) ?? -1,
processName: mainThread ? getProcessName(mainThread) : 'unknown',
etld1: mainThread?.['eTLD+1'],
mainThreadIndex: counter.mainThreadIndex,
mainThreadHandle: threadMap.handleForThreadIndex(counter.mainThreadIndex),
mainThreadName,
mainThreadName: mainThread?.name ?? '',
rangeSampleCount: Math.max(0, rangeEndIndex - rangeStartIndex),
stats: collectCounterStats(store, counterIndex),
graph: collectCounterGraph(store, counterIndex),
Expand All @@ -224,12 +229,13 @@ export function collectCounterSummary(
*/
export function collectCounterList(
store: Store,
threadMap: ThreadMap
threadMap: ThreadMap,
processIndexMap: Map<string, number>
): CounterListResult {
return {
type: 'counter-list',
counters: getSortedCounterIndexes(store).map((index) =>
collectCounterSummary(store, threadMap, index)
collectCounterSummary(store, threadMap, processIndexMap, index)
),
};
}
Expand Down Expand Up @@ -503,14 +509,20 @@ function collectCounterGraph(
export function collectCounterInfo(
store: Store,
threadMap: ThreadMap,
processIndexMap: Map<string, number>,
timestampManager: TimestampManager,
counterHandle: string
): CounterInfoResult {
const state = store.getState();
const counters = getCounters(state) ?? [];
const counterIndex = parseCounterHandle(counterHandle, counters.length);

const summary = collectCounterSummary(store, threadMap, counterIndex);
const summary = collectCounterSummary(
store,
threadMap,
processIndexMap,
counterIndex
);
const selectors = getCounterSelectors(counterIndex);
const counter = selectors.getCounter(state);
const [rangeStartIndex, rangeEndIndex] = getInRangeSampleIndexes(
Expand Down
14 changes: 8 additions & 6 deletions src/profile-query/formatters/profile-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
getRangeFilteredCombinedThreadActivitySlices,
} from 'firefox-profiler/selectors/profile';
import { getProfileNameWithDefault } from 'firefox-profiler/selectors/url-state';
import { buildProcessThreadList } from '../process-thread-list';
import { buildProcessThreadList, getProcessName } from '../process-thread-list';
import { collectSliceTree } from '../cpu-activity';
import { collectCounterSummary, getSortedCounterIndexes } from './counter-info';
import type { Store } from '../../types/store';
Expand Down Expand Up @@ -92,10 +92,7 @@ export function collectProfileInfo(
(t) => t.pid === processItem.pid
);
if (threadFromProcess) {
processItem.name =
threadFromProcess.processName ||
threadFromProcess.processType ||
'unknown';
processItem.name = getProcessName(threadFromProcess);
processItem.etld1 = threadFromProcess['eTLD+1'];
processItem.startTime = threadFromProcess.processStartupTime;
processItem.endTime = threadFromProcess.processShutdownTime;
Expand All @@ -110,7 +107,12 @@ export function collectProfileInfo(

const countersByPid = new Map<string, CounterSummary[]>();
for (const index of getSortedCounterIndexes(store)) {
const counter = collectCounterSummary(store, threadMap, index);
const counter = collectCounterSummary(
store,
threadMap,
processIndexMap,
index
);
const list = countersByPid.get(counter.pid) ?? [];
list.push(counter);
countersByPid.set(counter.pid, list);
Expand Down
7 changes: 6 additions & 1 deletion src/profile-query/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,11 @@ export class ProfileQuerier {
}

async counterList(): Promise<WithContext<CounterListResult>> {
const result = collectCounterList(this._store, this._threadMap);
const result = collectCounterList(
this._store,
this._threadMap,
this._processIndexMap
);
return { ...result, context: this._getContext() };
}

Expand All @@ -230,6 +234,7 @@ export class ProfileQuerier {
const result = collectCounterInfo(
this._store,
this._threadMap,
this._processIndexMap,
this._timestampManager,
counterHandle
);
Expand Down
7 changes: 7 additions & 0 deletions src/profile-query/process-thread-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import type { RawThread } from 'firefox-profiler/types';

/** The display name of the process a thread belongs to. */
export function getProcessName(thread: RawThread): string {
return thread.processName || thread.processType || 'unknown';
}

export type ThreadInfo = {
threadIndex: number;
name: string;
Expand Down
3 changes: 3 additions & 0 deletions src/profile-query/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,9 @@ export type CounterSummary = {
graphType: CounterGraphType;
color: string;
pid: string;
processIndex: number;
processName: string; // e.g. "Parent Process"
etld1?: string; // eTLD+1 of an isolated content process, when known
mainThreadIndex: number;
mainThreadHandle: string; // e.g. "t-0"
mainThreadName: string;
Expand Down
5 changes: 4 additions & 1 deletion src/test/unit/profile-query/profile-querier.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,12 +370,15 @@ describe('ProfileQuerier', function () {
}

it('counterList returns a schema-driven summary per counter', async function () {
const { profile } = profileWithMemoryCounter();
const { profile, counter } = profileWithMemoryCounter();
const result = await querierFor(profile).counterList();

expect(result.counters).toHaveLength(1);
expect(result.counters[0].counterHandle).toBe('c-0');
expect(result.counters[0].label).toBe('Memory');
expect(result.counters[0].pid).toBe(counter.pid);
expect(result.counters[0].processIndex).toBeGreaterThanOrEqual(0);
expect(result.counters[0].processName).toBeTruthy();
expect(
result.counters[0].stats.some((s) => s.source === 'count-range')
).toBe(true);
Expand Down
Loading