1// Copyright (C) 2025 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import m from 'mithril'; 16import {PerfettoPlugin} from '../../public/plugin'; 17import {Trace} from '../../public/trace'; 18 19function formatMillis(millis: number) { 20 return millis.toFixed(1); 21} 22 23export default class implements PerfettoPlugin { 24 static readonly id = 'dev.perfetto.QueryLog'; 25 async onTraceLoad(trace: Trace): Promise<void> { 26 const tabUri = `${trace.pluginId}#QueryLogTab`; 27 28 trace.commands.registerCommand({ 29 id: `${trace.pluginId}#ShowQueryLogTab`, 30 name: 'Show query log tab', 31 callback: () => { 32 trace.tabs.showTab(tabUri); 33 }, 34 }); 35 36 trace.tabs.registerTab({ 37 isEphemeral: false, 38 uri: tabUri, 39 content: { 40 getTitle() { 41 return 'Query log'; 42 }, 43 render() { 44 // Show the logs in reverse order 45 const queryLog = Array.from(trace.engine.queryLog).reverse(); 46 return m( 47 'table.pf-query-log-table', 48 m( 49 'tr', 50 m('th', 'Query'), 51 m('th', 'Tag'), 52 m('th', 'Status'), 53 m('th', 'Start time (ms)'), 54 m('th', 'Duration (ms)'), 55 ), 56 queryLog.map((ql) => 57 m( 58 'tr', 59 m('td', ql.query), 60 m('td', ql.tag), 61 m( 62 'td', 63 ql.success === undefined 64 ? 'Running...' 65 : ql.success 66 ? 'Completed' 67 : 'Failed', 68 ), 69 m('td', formatMillis(ql.startTime)), 70 m( 71 'td', 72 ql.endTime === undefined 73 ? '...' 74 : formatMillis(ql.endTime - ql.startTime), 75 ), 76 ), 77 ), 78 ); 79 }, 80 }, 81 }); 82 } 83} 84