blob: 43616b7eb6dc9805a5b009715f64692863e4ae56 [file] [edit]
// Copyright (C) 2026 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import m from 'mithril';
import type {Engine} from '../../../trace_processor/engine';
import {NUM_NULL, STR_NULL} from '../../../trace_processor/query_result';
import {Section} from '../../../widgets/section';
import {Grid, GridCell, GridHeaderCell} from '../../../widgets/grid';
// Trace row spec and type
const traceRowSpec = {
traceId: NUM_NULL,
uniqueSessionName: STR_NULL,
traceUuid: STR_NULL,
traceType: STR_NULL,
traceSizeBytes: NUM_NULL,
traceTrigger: STR_NULL,
machines: STR_NULL,
};
type TraceRow = typeof traceRowSpec;
export interface TracesData {
readonly traces: TraceRow[];
}
export async function loadTracesData(engine: Engine): Promise<TracesData> {
const result = await engine.query(`
INCLUDE PERFETTO MODULE std.traceinfo.trace;
select
trace_id as traceId,
unique_session_name as uniqueSessionName,
trace_uuid as traceUuid,
trace_type as traceType,
trace_size_bytes as traceSizeBytes,
trace_trigger as traceTrigger,
machines
from _metadata_by_trace
order by trace_id;
`);
const traces: TraceRow[] = [];
for (const it = result.iter(traceRowSpec); it.valid(); it.next()) {
traces.push({
traceId: it.traceId,
uniqueSessionName: it.uniqueSessionName,
traceUuid: it.traceUuid,
traceType: it.traceType,
traceSizeBytes: it.traceSizeBytes,
traceTrigger: it.traceTrigger,
machines: it.machines,
});
}
return {traces};
}
export interface TracesTabAttrs {
data: TracesData;
}
export class TracesTab implements m.ClassComponent<TracesTabAttrs> {
view({attrs}: m.CVnode<TracesTabAttrs>) {
return m(
'.pf-trace-info-page__tab-content',
m(
Section,
{
title: 'Traces',
subtitle: 'Information about individual traces in this session',
},
m(TraceListSection, {data: attrs.data.traces}),
),
);
}
}
interface TraceListSectionAttrs {
data: TraceRow[];
}
class TraceListSection implements m.ClassComponent<TraceListSectionAttrs> {
view({attrs}: m.CVnode<TraceListSectionAttrs>) {
const data = attrs.data;
if (data === undefined || data.length === 0) {
return undefined;
}
const traceTables = data.map((row) => {
const gridRows = [];
for (const key of Object.keys(traceRowSpec)) {
const value = row[key as keyof TraceRow];
if (value !== undefined && value !== null) {
gridRows.push([m(GridCell, key), m(GridCell, String(value))]);
}
}
return m(
'',
m(
'h3',
`Trace ${row.traceId}${row.uniqueSessionName ? ': ' + row.uniqueSessionName : row.traceType ? ': ' + row.traceType : ''}`,
),
m(Grid, {
columns: [
{
key: 'name',
header: m(GridHeaderCell, 'Name'),
},
{
key: 'value',
header: m(GridHeaderCell, 'Value'),
},
],
rowData: gridRows,
className: 'pf-trace-info-page__logs-grid',
}),
);
});
return traceTables;
}
}