+
+
@@ -1252,6 +1324,7 @@ export class TraceSheet extends BaseElement {
param.nativeMemoryCurrentIPid = ipid;
}
}
+ param.isImportSo = true;
this.rangeSelect(param, true);
return true;
} else {
@@ -1274,8 +1347,10 @@ export class TraceSheet extends BaseElement {
selection.threadIds.length > 0)
) {
this.importDiv!.style.display = 'flex';
+ this.symbolDiv!.style.display = 'flex';
} else {
this.importDiv!.style.display = 'none';
+ this.symbolDiv!.style.display = 'none';
}
}
isProcessEqual(treeData: Array<{ pid: number; ipid: number }>): boolean {
diff --git a/ide/src/trace/component/trace/base/Utils.ts b/ide/src/trace/component/trace/base/Utils.ts
index e9e4435a69e2d127719ad203228d72dabd53c7e9..dc406525096e883e12f46efa1154d43bc01a0e36 100644
--- a/ide/src/trace/component/trace/base/Utils.ts
+++ b/ide/src/trace/component/trace/base/Utils.ts
@@ -23,6 +23,7 @@ export class Utils {
static currentSelectTrace: string | null | undefined;
static currentTraceMode: TraceMode = TraceMode.NORMAL;
static distributedTrace: string[] = [];
+ static isRangeSelectRefresh: boolean = false;
static DMAFENCECAT_MAP: Map<
number,
{
diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts
index 9e4d54868053ab42e121b1b4bc21d85cd8c1aee4..0f82b5616e9e8ada9b8a561641335aa3bd5997da 100644
--- a/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts
+++ b/ide/src/trace/component/trace/sheet/TabPaneCurrentSelection.ts
@@ -473,6 +473,7 @@ export class TabPaneCurrentSelection extends BaseElement {
}
list.push(item);
});
+ this.addTabSliceDetail(data, list)
this.currentSelectionTbl!.dataSource = list;
// @ts-ignore
let startTimeAbsolute = (data.startTs || 0) + (window as unknown).recordStartNS;
@@ -494,6 +495,7 @@ export class TabPaneCurrentSelection extends BaseElement {
name: 'Thread',
value: (this.transferString(threadName ?? '') || 'NULL') + ' [' + dataTid + '] ',
});
+ this.addTabSliceDetail(data, list)
list.push({
name: 'StartTime(Relative)',
value: getTimeString(data.startTs || 0),
@@ -599,6 +601,7 @@ export class TabPaneCurrentSelection extends BaseElement {
argset.forEach((item) => {
list.push({ name: item.keyName, value: item.strValue });
});
+ this.addTabSliceDetail(data, list)
this.addTabPanelContent(list, data, information);
this.currentSelectionTbl!.dataSource = list;
});
@@ -653,6 +656,7 @@ export class TabPaneCurrentSelection extends BaseElement {
}
);
}
+ this.addTabSliceDetail(data, list)
this.addTabPanelContent(list, data, information);
this.currentSelectionTbl!.dataSource = list;
let funcClick = this.currentSelectionTbl?.shadowRoot?.querySelector('#function-jump');
@@ -686,6 +690,21 @@ export class TabPaneCurrentSelection extends BaseElement {
});
}
+ private addTabSliceDetail(data: FuncStruct, list: unknown[]) {
+ const properties = [
+ {key: 'trace_level', name: 'TraceLevel'},
+ {key: 'trace_tag', name: 'TraceTag'},
+ {key: 'category', name: 'Category'},
+ {key: 'custom_args', name: 'CustomArgs'},
+ ];
+ properties.forEach(prop => {
+ if (data[prop.key] && list !== undefined) {
+ list!.push({name: prop.name, value: data[prop.key]});
+ }
+ });
+ return list;
+ }
+
private handleAsyncBinder(
data: FuncStruct,
list: unknown[],
@@ -748,6 +767,7 @@ export class TabPaneCurrentSelection extends BaseElement {
value: (this.transferString(threadName ?? '') || 'NULL') + ' [' + data.tid + '] ',
});
}
+ this.addTabSliceDetail(data, list)
this.addTabPanelContent(list, data, information);
this.currentSelectionTbl!.dataSource = list;
let funcClick = this.currentSelectionTbl?.shadowRoot?.querySelector('#function-jump');
diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.html.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.html.ts
index 02249b1ec86b5d3944b5319a2dcb6c0e05de1126..787aa7d7c5a36c684fa89c4e07f99fd713315485 100644
--- a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.html.ts
+++ b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.html.ts
@@ -66,8 +66,21 @@ export const TabPanePerfAnalysisHtml = `
width: 100%;
height: 20px;
}
+@keyframes textGrowth {
+ 0% {
+ font-size: 16px;
+ transform: scale(0.9);
+ }
+ 100% {
+ font-size: 18px;
+ transform: scale(1.0);
+ }
+}
#SO-err-tips{
color:red;
+ animation: textGrowth 2.0s ease-in-out infinite alternate;
+ will-change: transform, font-size;
+ transform: translateZ(0);
}
diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts
index c04d2ce9193ebb9aa8d80437fac8ecac9538ebf6..ba92636abf3efa82937dbf54c7e755be5ba61c9f 100644
--- a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts
+++ b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts
@@ -68,13 +68,21 @@ export class TabPanePerfAnalysis extends BaseElement {
private isComplete: boolean = true;
private currentSelectionParam: SelectionParam | undefined | null;
static tabLoadingList: Array
= [];
+
private vaddrList: Array = [];
private selectedTabfileName: string = '';
private clickFuncVaddrList: Array = [];
private functionListener!: Function | undefined | null;
private currentSoName: string = '';
+ private currentProcessItem: unknown;
+ private currentThreadItem: unknown;
+ private currentLibrayItem: unknown;
set data(val: SelectionParam) {
+ if (val.isImportSo && this.currentLevel > 0) {
+ this.disableHomeRedirectAfterSoLoad(val);
+ return;
+ }
if (val === this.currentSelection) {
this.pidData.unshift(this.allProcessCount);
this.perfTableProcess!.recycleDataSource = this.pidData;
@@ -107,6 +115,66 @@ export class TabPanePerfAnalysis extends BaseElement {
}
}
+ private disableHomeRedirectAfterSoLoad(val: SelectionParam): void {
+ this.getDataByWorker(val, (results: unknown) => {
+ this.isComplete = true;
+ // @ts-ignore
+ this.processData = results;
+ // @ts-ignore
+ if (this.currentLevel === 3) {
+ this.reset(this.tableFunction!, true);
+ this.getHiperfFunction(this.currentLibrayItem);
+ let title = '';
+ if (this.processName.length > 0) {
+ title += `${this.processName} / `;
+ }
+ if (this.threadName.length > 0) {
+ title += `${this.threadName} / `;
+ }
+ if (this.currentSoName.length > 0) {
+ title += this.currentSoName;
+ }
+ this.titleEl!.textContent = title;
+ this.perfAnalysisPie?.hideTip();
+ this.selectedTabfileName = this.currentSoName;
+ } else if (this.currentLevel === 1) {
+ if (this.hideThreadCheckBox!.checked) {
+ this.hideThread(this.currentProcessItem);
+ } else {
+ this.reset(this.perfTableThread!, true);
+ this.getHiperfThread(this.currentProcessItem, val);
+ }
+ // @ts-ignore
+ this.titleEl!.textContent = this.currentProcessItem.tableName;
+ // @ts-ignore
+ this.processName = this.currentProcessItem.tableName;
+ this.perfAnalysisPie?.hideTip();
+ } else if (this.currentLevel === 2) {
+ this.reset(this.perfTableSo!, true);
+ this.getHiperfSo(this.currentThreadItem, val);
+ let pName = this.processName;
+ // @ts-ignore
+ if (this.processName.length > 0 && this.currentThreadItem.tableName.length > 0) {
+ pName = `${this.processName} / `;
+ }
+ // @ts-ignore
+ this.titleEl!.textContent = pName + this.currentThreadItem.tableName;
+ // @ts-ignore
+ this.threadName = this.currentThreadItem.tableName;
+ this.perfAnalysisPie?.hideTip();
+ }
+ const args = [
+ {
+ funcName: 'getVaddrToFile',
+ funcArgs: [val],
+ },
+ ];
+ procedurePool.submitWithName('logic0', 'perf-vaddr', args, undefined, (results: Array) => {
+ this.vaddrList = results;
+ });
+ });
+ }
+
private initPerfTableListener(): void {
for (let perfTable of this.tableArray!) {
let querySelector = perfTable.shadowRoot?.querySelector('.table');
@@ -407,6 +475,7 @@ export class TabPanePerfAnalysis extends BaseElement {
}
private perfProcessLevelClickEvent(it: unknown, val: SelectionParam): void {
+ this.currentProcessItem = it;
if (this.hideThreadCheckBox!.checked) {
this.hideThread(it);
this.showAssignLevel(this.perfTableSo!, this.perfTableProcess!, 1, this.soData);
@@ -478,6 +547,7 @@ export class TabPanePerfAnalysis extends BaseElement {
}
private perfThreadLevelClickEvent(it: unknown, val: SelectionParam): void {
+ this.currentThreadItem = it;
this.reset(this.perfTableSo!, true);
this.showAssignLevel(this.perfTableSo!, this.perfTableThread!, 2, this.soData);
this.getHiperfSo(it, val);
@@ -556,6 +626,7 @@ export class TabPanePerfAnalysis extends BaseElement {
}
private perfSoLevelClickEvent(it: unknown): void {
+ this.currentLibrayItem = it;
this.reset(this.tableFunction!, true);
this.showAssignLevel(this.tableFunction!, this.perfTableSo!, 3, this.functionData);
// @ts-ignore
diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfFuncAsm.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfFuncAsm.ts
index b0db75e263f836ece63d3a647e6279669f574427..25aed797615aa4b77d468cc1d0bbba4186b887f8 100644
--- a/ide/src/trace/component/trace/sheet/hiperf/TabPerfFuncAsm.ts
+++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfFuncAsm.ts
@@ -13,6 +13,7 @@
* limitations under the License.
*/
import { TabPerfFuncAsmHtml } from './TabPerfFuncAsm.html';
+import { Utils } from '../../base/Utils';
import { BaseElement, element } from '../../../../../base-ui/BaseElement';
import { LitTable } from '../../../../../base-ui/table/lit-table';
import {
@@ -140,6 +141,9 @@ export class TabPerfFuncAsm extends BaseElement {
}
set data(data: PerfFunctionAsmParam) {
+ if (Utils.isRangeSelectRefresh) {
+ this.functionName = '';
+ }
if (this.functionName === data.functionName || data.functionName === undefined) {
return;
}
@@ -151,6 +155,7 @@ export class TabPerfFuncAsm extends BaseElement {
this.totalCount = data.totalCount;
this.updateTotalCount();
this.showLoading();
+ Utils.isRangeSelectRefresh = false;
// @ts-ignore
const vaddrInFile = data.vaddrList[0].vaddrInFile;
// 1. 先转成 BigInt
@@ -256,8 +261,10 @@ export class TabPerfFuncAsm extends BaseElement {
private calcutelateShowUpData(): void {
this.funcSampleMap.forEach((selfCount, offsetToVaddr) => {
let instructionPosition = offsetToVaddr / 4;
- this.formattedAsmIntructionArray[instructionPosition].selfcount = selfCount;
- this.formattedAsmIntructionArray[instructionPosition].percent = Math.round((selfCount / this.totalCount) * 10000) / 100;
+ if (this.formattedAsmIntructionArray[instructionPosition]) {
+ this.formattedAsmIntructionArray[instructionPosition].selfcount = selfCount;
+ this.formattedAsmIntructionArray[instructionPosition].percent = Math.round((selfCount / this.totalCount) * 10000) / 100;
+ }
});
this.originalShowUpData = this.formattedAsmIntructionArray;
}
diff --git a/ide/src/trace/component/trace/sheet/process/TabPaneSliceChild.ts b/ide/src/trace/component/trace/sheet/process/TabPaneSliceChild.ts
index e75097d1ddeacdf678056a825c76d442d759ffe3..c8e6916c30af4d9c7b25856b32e51fefe0aa2e42 100644
--- a/ide/src/trace/component/trace/sheet/process/TabPaneSliceChild.ts
+++ b/ide/src/trace/component/trace/sheet/process/TabPaneSliceChild.ts
@@ -37,8 +37,10 @@ export class TabPaneSliceChild extends BaseElement {
//合并SF异步信息,相同pid和tid的name
let sfAsyncFuncMap: Map = new Map();
let filterSfAsyncFuncName = boxChildValue.selection!.funAsync;
- if (!boxChildValue.param.isSummary!) {
- filterSfAsyncFuncName = filterSfAsyncFuncName.filter((item) => item.name === boxChildValue.param.name![0]);
+ if (boxChildValue.param.name) {
+ filterSfAsyncFuncName = filterSfAsyncFuncName.filter((item) =>
+ boxChildValue.param.name?.some((boxItem) => item.name === boxItem)
+ );
}
filterSfAsyncFuncName.forEach((it: { name: string; pid: number, tid: number | undefined }) => {
if (sfAsyncFuncMap.has(`${it.pid}-${it.tid}`)) {
diff --git a/ide/src/trace/database/sql/Func.sql.ts b/ide/src/trace/database/sql/Func.sql.ts
index d99a23090d963a890c553b682cb8c42cf6b256e6..f9ca8595cc8e109af7bcc7bcdcd4dee04103112d 100644
--- a/ide/src/trace/database/sql/Func.sql.ts
+++ b/ide/src/trace/database/sql/Func.sql.ts
@@ -152,14 +152,19 @@ export const queryProcessAsyncFunc = (
P.pid,
c.ts-${traceRange.startTs} as startTs,
c.dur,
- c.cat,
+ c.custom_category as category,
c.id,
c.depth,
c.argsetid,
- c.cookie
+ c.cookie,
+ c.trace_level,
+ c.trace_tag,
+ c.custom_args,
+ c.child_callid
FROM
- (SELECT id, ts, parent_id, dur, depth, argsetid, cookie, cat from callstack where cookie NOT NULL) c
- LEFT JOIN thread A ON A.id = c.parent_id
+ (SELECT id, ts, parent_id, dur, depth, argsetid, cookie, custom_category, child_callid, trace_level,
+ trace_tag, custom_args from callstack where cookie NOT NULL) c
+ LEFT JOIN thread A ON A.id = c.child_callid
LEFT JOIN process P ON P.id = A.ipid
WHERE
startTs NOT NULL;`,
@@ -179,21 +184,26 @@ export const queryProcessAsyncFuncCat = (
select
A.tid,
P.pid,
- c.cat as threadName,
+ c.custom_category as threadName,
c.name as funName,
c.ts-${traceRange.startTs} as startTs,
c.dur,
c.depth,
- c.cookie
+ c.cookie,
+ c.trace_level,
+ c.trace_tag,
+ c.custom_args,
+ c.child_callid
from
- (select callid, name, ts, dur, cat, depth, cookie, parent_id from callstack where cookie not null and cat not null and parent_id is null) C
+ (select callid, name, ts, dur, custom_category, depth, cookie, parent_id,trace_level,trace_tag,
+ custom_args,child_callid from callstack where cookie not null and custom_category not null and child_callid is null) c
left join
- thread A on A.id = C.callid
+ thread A on A.id = c.callid
left join
process P on P.id = A.ipid
where
startTs not null
- order by cat;
+ order by custom_category;
`,
{}
);
@@ -590,6 +600,10 @@ export const querySearchFunc = (search: string): Promise>
t.name as threadName,
p.pid,
c.argsetid,
+ c.trace_level,
+ c.trace_tag,
+ c.custom_args,
+ c.custom_category as category,
'func' as type
from callstack c left join thread t on c.callid = t.id left join process p on t.ipid = p.id
left join trace_range r
@@ -613,6 +627,10 @@ export const querySearchFunc = (search: string): Promise>
t.name as threadName,
p.pid,
c.argsetid,
+ c.trace_level,
+ c.trace_tag,
+ c.custom_args,
+ c.custom_category as category,
'func' as type
from callstack c left join thread t on c.callid = t.id left join process p on t.ipid = p.id
left join trace_range r
diff --git a/ide/src/trace/database/sql/SqlLite.sql.ts b/ide/src/trace/database/sql/SqlLite.sql.ts
index 2b547526cca08af488a76c7dbba48ba403ec8f3b..aa6364e1fb9df78adcea3cd45a39abfc855d3c02 100644
--- a/ide/src/trace/database/sql/SqlLite.sql.ts
+++ b/ide/src/trace/database/sql/SqlLite.sql.ts
@@ -29,6 +29,7 @@ import type { DeviceStruct } from '../../bean/FrameComponentBean';
import { LogStruct } from '../ui-worker/ProcedureWorkerLog';
import { query } from '../SqlLite';
import { Utils } from '../../component/trace/base/Utils';
+import { FuncStruct } from '../ui-worker/ProcedureWorkerFunc';
export const queryEventCountMap = (
traceId?: string
@@ -405,7 +406,11 @@ export const queryBinderBySliceId = (
c.depth,
c.argsetid,
c.name AS funName,
- c.cookie
+ c.cookie,
+ c.trace_level,
+ c.trace_tag,
+ c.custom_category as category,
+ c.custom_args
FROM
callstack c,
trace_range D
@@ -449,8 +454,12 @@ export const queryBinderByArgsId = (
p.pid,
c.depth,
c.argsetid,
- c.name as funName,
- c.cookie
+ c.name as funName,
+ c.cookie,
+ c.trace_level,
+ c.trace_tag,
+ c.custom_category as category,
+ c.custom_args
from callstack c,trace_range D
left join thread t on c.callid = t.id
left join process p on p.id = t.ipid
@@ -1592,3 +1601,21 @@ export const queryPerfToolsDur = (): Promise> =>
dur
FROM callstack where name = 'H:GRAB'`
);
+
+export const queryCallstackDetail = (): Promise> =>
+ query(
+ 'queryCallstackDetail',
+ `SELECT
+ id,
+ trace_level,
+ trace_tag,
+ custom_category as category,
+ custom_args
+ FROM callstack, trace_range AS TR
+ where (trace_level is not null or
+ trace_tag is not null or
+ custom_args is not null or
+ custom_category is not null)
+ and ts - TR.start_ts >= 0
+ and TR.end_ts - ts >=0;`
+ );
diff --git a/trace_streamer/doc/des_tables.md b/trace_streamer/doc/des_tables.md
index fa1e90f3074a8cc056974e4ae524e4249965db93..74580f0fd933916ffa778f0e0112ce66e101e137 100755
--- a/trace_streamer/doc/des_tables.md
+++ b/trace_streamer/doc/des_tables.md
@@ -18,7 +18,7 @@ TraceStreamer可以将trace数据源转化为易于理解和使用的数据库
| app_startup | 记录了应用启动相关数据|
| args | 记录方法参数集合|
| bio_latency_sample | 记录IO操作相关方法调用,及调用栈数据|
-| callstack | 记录调用堆栈和异步调用信息,其中depth,stack_id和parent_stack_id仅在非异步调用中有效。当cookid不为空时,为异步调用,此时callid为进程唯一号,否则为线程唯一号|
+| callstack | 记录调用堆栈和异步调用信息,其中depth仅在非异步调用中有效。当cookid不为空时,为异步调用,此时callid为进程唯一号,child_callid为子线程唯一号|
| clk_event_filter | 记录时钟相关的信息|
| clock_event_filter | 此结构用来维护时钟事件,cpu与唯一的ID做关联|
| clock_snapshot | 时钟号和时间,时钟名的映射表|
@@ -359,8 +359,13 @@ js_heap_sample:记录timeline的时间轴信息
|spanId |TEXT |
|parentSpanId |TEXT |
|flag |TEXT |
+|trace_level |TEXT |
+|trace_tag |TEXT |
+|custom_category |TEXT |
+|custom_args |TEXT |
+|child_callid |INT |
#### 表描述
-记录调用堆栈和异步调用信息,其中depth,stack_id和parent_stack_id仅在非异步的调用中有效。当cookid不为空时,为异步调用,此时callid为进程唯一号,否则为线程唯一号。
+记录调用堆栈和异步调用信息,其中depth仅在非异步的调用中有效。当cookid不为空时,为异步调用,此时callid为进程唯一号,child_callid为子线程唯一号。
#### 字段详细描述
- id: 唯一标识
- ts: 数据事件上报时间戳
@@ -376,6 +381,11 @@ js_heap_sample:记录timeline的时间轴信息
- spanId:分布式调用关联关系,当前帧的id
- parentSpanId: 分布式调用关联关系,当前帧的parent的SpanId,对应当前表的spandId
- flag:C表示分布式调用发送方,S表示接受方
+- trace_level:决定trace的等级,log和nolog等级不同,其中log表示详细记录所有相关的调用信息,nolog 表示不记录
+- trace_tag:Tag标签,标识请求的来源或类型
+- custom_category:聚合标签,用于关联同类信息
+- custom_args:自定义参数,用于存储与调用相关的额外信息
+- child_callid:当为异步调用,此时callid为进程唯一号,child_callid为子线程唯一号,反之为无效值
### clk_event_filter表
#### 表结构
diff --git a/trace_streamer/src/base/string_help.cpp b/trace_streamer/src/base/string_help.cpp
index f18316d33e958b1df1f235b6fbaa8ae681501925..8fd7dbdd3dfcd38f18ee2e37fce3ff028259bd27 100644
--- a/trace_streamer/src/base/string_help.cpp
+++ b/trace_streamer/src/base/string_help.cpp
@@ -44,19 +44,21 @@ bool EndWith(const std::string &str, const std::string &res)
return str.compare(str.size() - res.size(), res.size(), res) == 0;
}
-std::vector SplitStringToVec(const std::string &str, const std::string &pat)
+std::vector SplitStringToVec(const std::string &str, const std::string &pat, uint32_t expectedCount)
{
std::vector result;
size_t curPos = 0;
size_t strSize = str.size();
size_t patSize = pat.size();
+ uint32_t endFlag = 0;
while (curPos < strSize) {
auto patPos = str.find(pat, curPos);
- if (patPos == std::string::npos) {
+ if (patPos == std::string::npos || endFlag == expectedCount) {
break;
}
result.emplace_back(str.substr(curPos, patPos - curPos));
curPos = patPos + patSize;
+ endFlag++;
}
if (curPos < strSize) {
result.emplace_back(str.substr(curPos));
diff --git a/trace_streamer/src/base/string_help.h b/trace_streamer/src/base/string_help.h
index c104641078c1baae30e38c2e020c1d2f0a43a81d..df4bb6a7e3edda5428cfb691cdf62f5b47ba08c6 100644
--- a/trace_streamer/src/base/string_help.h
+++ b/trace_streamer/src/base/string_help.h
@@ -23,7 +23,9 @@
namespace SysTuning {
namespace base {
char *GetDemangleSymbolIndex(const char *mangled);
-std::vector SplitStringToVec(const std::string &str, const std::string &pat);
+std::vector SplitStringToVec(const std::string &str,
+ const std::string &pat,
+ uint32_t expectedCount = UINT32_MAX);
bool StartWith(const std::string &str, const std::string &res);
bool EndWith(const std::string &str, const std::string &res);
std::string FormatString(const char *p);
diff --git a/trace_streamer/src/filter/slice_filter.cpp b/trace_streamer/src/filter/slice_filter.cpp
index 00ad01d3a72cc112cc4763d0cf040f7dabc7619e..0e14097f7a251fdfe9d1077f3daae62af7984192 100644
--- a/trace_streamer/src/filter/slice_filter.cpp
+++ b/trace_streamer/src/filter/slice_filter.cpp
@@ -325,9 +325,13 @@ size_t SliceFilter::StartSlice(uint64_t timeStamp,
uint32_t depth = stack.size();
auto slices = traceDataCache_->GetInternalSlicesData();
uint32_t parentId = depth == 0 ? INVALID_UINT32 : slices->IdsData()[stack.back().index];
- CallStackInternalRow callStackInternalRow = {sliceData.timeStamp, static_cast(sliceData.duration),
- sliceData.internalTid, sliceData.cat,
- sliceData.name, 0};
+ CallStackInternalRow callStackInternalRow = {sliceData.timeStamp,
+ static_cast(sliceData.duration),
+ sliceData.internalTid,
+ sliceData.cat,
+ sliceData.name,
+ 0,
+ INVALID_UINT32};
size_t index = slices->AppendInternalSlice(callStackInternalRow, parentId);
if (depth >= std::numeric_limits::max()) {
return SIZE_MAX;
@@ -464,8 +468,9 @@ uint64_t SliceFilter::StartAsyncSlice(uint64_t timeStamp,
// the IDE need a depth to paint call slice in different position of the canvas, the depth of async call
// do not mean the parent-to-child relationship, it is different from no-async call
uint8_t depth = 0;
+ uint32_t childCallid = parentId;
CallStackInternalRow callStackInternalRow = {timeStamp, static_cast(-1), internalTid, cat, nameIndex,
- depth};
+ depth, childCallid};
size_t index = slices->AppendInternalAsyncSlice(callStackInternalRow, cookie, parentId);
asyncEventFilterMap_.insert(std::make_pair(asyncEventSize_, AsyncEvent{timeStamp, index}));
return index;
diff --git a/trace_streamer/src/parser/common_types.h b/trace_streamer/src/parser/common_types.h
index 16a3e3bddec1a2dfee05e9834a744d94e681a797..76d48f7765848e796de45af54c3b0757ead7cca8 100644
--- a/trace_streamer/src/parser/common_types.h
+++ b/trace_streamer/src/parser/common_types.h
@@ -90,7 +90,11 @@ public:
args_(point.args_),
funcPrefixId_(point.funcPrefixId_),
funcPrefix_(point.funcPrefix_),
- funcArgs_(point.funcArgs_)
+ funcArgs_(point.funcArgs_),
+ traceLevel_(point.traceLevel_),
+ traceTagId_(point.traceTagId_),
+ customCategoryId_(point.customCategoryId_),
+ customArgsId_(point.customArgsId_)
{
}
void operator=(const TracePoint &point)
@@ -108,6 +112,10 @@ public:
funcPrefixId_ = point.funcPrefixId_;
funcPrefix_ = point.funcPrefix_;
funcArgs_ = point.funcArgs_;
+ traceLevel_ = point.traceLevel_;
+ traceTagId_ = point.traceTagId_;
+ customCategoryId_ = point.customCategoryId_;
+ customArgsId_ = point.customArgsId_;
}
char phase_ = '\0';
uint32_t tgid_ = 0;
@@ -123,6 +131,10 @@ public:
uint32_t funcPrefixId_ = 0;
std::string funcPrefix_ = "";
std::string funcArgs_ = "";
+ std::string traceLevel_ = "";
+ DataIndex traceTagId_ = INVALID_UINT64;
+ DataIndex customCategoryId_ = INVALID_UINT64;
+ DataIndex customArgsId_ = INVALID_UINT64;
};
enum class SplitDataDataType { SPLIT_FILE_DATA = 0, SPLIT_FILE_JSON };
diff --git a/trace_streamer/src/parser/print_event_parser.cpp b/trace_streamer/src/parser/print_event_parser.cpp
index a72718144f336ee6150658f5fdc31b1a9dd9df3a..6d324cbb39dea915dca12421a0aabe2efb4f9ef7 100644
--- a/trace_streamer/src/parser/print_event_parser.cpp
+++ b/trace_streamer/src/parser/print_event_parser.cpp
@@ -24,6 +24,9 @@ namespace SysTuning {
namespace TraceStreamer {
const uint8_t POINT_LENGTH = 1;
const uint8_t MAX_POINT_LENGTH = 2;
+const uint8_t CATEGORY_INDEX = 2;
+const uint8_t PARSER_SYNC_SUM = 2;
+const uint8_t PARSER_ASYNC_SUM = 3;
PrintEventParser::PrintEventParser(TraceDataCache *dataCache, const TraceStreamerFilters *filter)
: EventParserBase(dataCache, filter)
{
@@ -105,6 +108,10 @@ void PrintEventParser::ParseBeginEvent(const std::string &comm,
// add distributed data
traceDataCache_->GetInternalSlicesData()->SetDistributeInfo(index, point.chainId_, point.spanId_,
point.parentSpanId_, point.flag_);
+
+ // add traceMeta data
+ traceDataCache_->GetInternalSlicesData()->SetTraceMetadata(index, point.traceLevel_, point.traceTagId_,
+ point.customArgsId_);
if (HandleFrameSliceBeginEvent(point.funcPrefixId_, index, point.funcArgs_, line)) {
return;
}
@@ -136,9 +143,16 @@ void PrintEventParser::ParseStartEvent(const std::string &comm,
auto cookie = static_cast(point.value_);
auto index = streamFilters_->sliceFilter_->StartAsyncSlice(ts, pid, point.tgid_, cookie,
traceDataCache_->GetDataIndex(point.name_));
- if (point.name_ == onFrameQueeuStartEvent_ && index != INVALID_UINT64) {
+ if (index == INVALID_UINT64) {
+ return;
+ }
+ // add traceMeta data
+ traceDataCache_->GetInternalSlicesData()->SetTraceMetadata(index, point.traceLevel_, point.traceTagId_,
+ point.customArgsId_, point.customCategoryId_);
+
+ if (point.name_ == onFrameQueeuStartEvent_) {
OnFrameQueueStart(ts, index, point.tgid_);
- } else if (traceDataCache_->AnimationTraceEnabled() && index != INVALID_UINT64 &&
+ } else if (traceDataCache_->AnimationTraceEnabled() &&
(base::EndWith(comm, onAnimationProcEvent_) ||
base::EndWith(comm, newOnAnimationProcEvent_))) { // the comm is taskName
streamFilters_->animationFilter_->StartAnimationEvent(line, point, index);
@@ -247,6 +261,36 @@ std::string_view PrintEventParser::GetPointNameForBegin(std::string_view pointSt
return name;
}
+void PrintEventParser::ParseSplitTraceMetaData(const std::string &dataStr, TracePoint &outPoint, bool isAsynEvent) const
+{
+ std::string metaDataStr = base::Strip(dataStr);
+ uint32_t expectedCount = isAsynEvent ? PARSER_ASYNC_SUM : PARSER_SYNC_SUM;
+ std::vector traceMetaDatas = base::SplitStringToVec(metaDataStr, "|", expectedCount);
+ if (traceMetaDatas.size() <= 1) {
+ TS_LOGD("traceMetaDatas size: %zu, dataStr: %s", traceMetaDatas.size(), dataStr.c_str());
+ return;
+ }
+
+ std::string &marker = traceMetaDatas[1];
+ if (!marker.empty()) {
+ outPoint.traceLevel_ = marker.substr(0, 1);
+ if (marker.size() > 1) {
+ std::string traceTag = marker.substr(1);
+ outPoint.traceTagId_ = traceDataCache_->GetDataIndex(traceTag);
+ }
+ }
+
+ if (isAsynEvent && traceMetaDatas.size() > CATEGORY_INDEX) {
+ std::string customCategory = traceMetaDatas[CATEGORY_INDEX];
+ outPoint.customCategoryId_ = traceDataCache_->GetDataIndex(customCategory);
+ }
+
+ if (traceMetaDatas.size() > expectedCount) {
+ std::string customArgs = traceMetaDatas[expectedCount];
+ outPoint.customArgsId_ = traceDataCache_->GetDataIndex(customArgs);
+ }
+}
+
ParseResult PrintEventParser::HandlerB(std::string_view pointStr, TracePoint &outPoint, size_t tGidlength) const
{
outPoint.name_ = GetPointNameForBegin(pointStr, tGidlength);
@@ -274,6 +318,9 @@ ParseResult PrintEventParser::HandlerB(std::string_view pointStr, TracePoint &ou
} else {
outPoint.funcPrefixId_ = traceDataCache_->GetDataIndex(outPoint.name_);
}
+
+ // traceMetaDatasSrt: H:name|%X%TAG|customArgs
+ ParseSplitTraceMetaData(outPoint.name_, outPoint, false);
}
return PARSE_SUCCESS;
}
@@ -535,7 +582,11 @@ ParseResult PrintEventParser::HandlerCSF(std::string_view pointStr, TracePoint &
outPoint.categoryGroup_ = std::string_view(pointStr.data() + valuePipe + 1, groupLen);
}
-
+ // traceMetaDatasSrt: taskId|%X%TAG|customCategory|customArgs
+ std::string metaDataStr(pointStr.data() + valueIndex);
+ if (outPoint.phase_ == 'S') {
+ ParseSplitTraceMetaData(metaDataStr, outPoint, true);
+ }
return PARSE_SUCCESS;
}
diff --git a/trace_streamer/src/parser/print_event_parser.h b/trace_streamer/src/parser/print_event_parser.h
index 2a6aab55245417f43c232c920e1a3b7f519c20f5..4fbb16340a49054ad09719084fcef63ebfdb40df 100644
--- a/trace_streamer/src/parser/print_event_parser.h
+++ b/trace_streamer/src/parser/print_event_parser.h
@@ -53,6 +53,7 @@ public:
void Finish();
void SetTraceType(TraceFileType traceType);
void SetTraceClockId(BuiltinClocks clock);
+ void ParseSplitTraceMetaData(const std::string &dataStr, TracePoint &outPoint, bool isAsynEvent) const;
private:
using FrameFuncCall = std::function;
diff --git a/trace_streamer/src/table/ftrace/callstack_table.cpp b/trace_streamer/src/table/ftrace/callstack_table.cpp
index 48a1bda1f33c5763ee9b01fa60a6e0f84a9f4db1..ff2d133ec4656dd3db987e2781704fbcb2d11c94 100644
--- a/trace_streamer/src/table/ftrace/callstack_table.cpp
+++ b/trace_streamer/src/table/ftrace/callstack_table.cpp
@@ -34,7 +34,12 @@ enum class Index : int32_t {
CHAIN_IDS,
SPAN_IDS,
PARENT_SPAN_IDS,
- FLAGS
+ FLAGS,
+ TRACE_LEVEL,
+ TRACE_TAG,
+ CUSTOM_CATEGORY,
+ CUSTOM_ARGS,
+ CHILD_CALLID
};
CallStackTable::CallStackTable(const TraceDataCache *dataCache) : TableBase(dataCache)
{
@@ -55,6 +60,11 @@ CallStackTable::CallStackTable(const TraceDataCache *dataCache) : TableBase(data
tableColumn_.push_back(TableBase::ColumnInfo("spanId", "TEXT"));
tableColumn_.push_back(TableBase::ColumnInfo("parentSpanId", "TEXT"));
tableColumn_.push_back(TableBase::ColumnInfo("flag", "TEXT"));
+ tableColumn_.push_back(TableBase::ColumnInfo("trace_level", "TEXT"));
+ tableColumn_.push_back(TableBase::ColumnInfo("trace_tag", "TEXT"));
+ tableColumn_.push_back(TableBase::ColumnInfo("custom_category", "TEXT"));
+ tableColumn_.push_back(TableBase::ColumnInfo("custom_args", "TEXT"));
+ tableColumn_.push_back(TableBase::ColumnInfo("child_callid", "INTEGER"));
tablePriKey_.push_back("callid");
tablePriKey_.push_back("ts");
tablePriKey_.push_back("depth");
@@ -215,6 +225,26 @@ void CallStackTable::Cursor::HandleTypeColumns(int32_t col) const
SetTypeColumnTextNotEmpty(slicesObj_.Flags()[CurrentRow()].empty(),
slicesObj_.Flags()[CurrentRow()].c_str());
break;
+ case Index::TRACE_LEVEL:
+ SetTypeColumnTextNotEmpty(slicesObj_.TraceLevelsData()[CurrentRow()].empty(),
+ slicesObj_.TraceLevelsData()[CurrentRow()].c_str());
+ break;
+ case Index::TRACE_TAG:
+ SetTypeColumnText(slicesObj_.TraceTagsData()[CurrentRow()], INVALID_UINT64);
+ break;
+ case Index::CUSTOM_CATEGORY:
+ SetTypeColumnText(slicesObj_.CustomCategorysData()[CurrentRow()], INVALID_UINT64);
+ break;
+ case Index::CUSTOM_ARGS:
+ SetTypeColumnText(slicesObj_.CustomArgsData()[CurrentRow()], INVALID_UINT64);
+ break;
+ case Index::CHILD_CALLID: {
+ if (slicesObj_.ChildCallidData()[CurrentRow()].has_value()) {
+ sqlite3_result_int64(context_,
+ static_cast(slicesObj_.ChildCallidData()[CurrentRow()].value()));
+ }
+ break;
+ }
default:
TS_LOGF("Unregistered column : %d", col);
break;
diff --git a/trace_streamer/src/trace_data/trace_stdtype/ftrace/callstack_stdtype.cpp b/trace_streamer/src/trace_data/trace_stdtype/ftrace/callstack_stdtype.cpp
index b13386b5a37b963ba4dd9e13be4e494031c7c72d..3bbbe4b82a05dd06655f5ddfaac219c912b353f2 100644
--- a/trace_streamer/src/trace_data/trace_stdtype/ftrace/callstack_stdtype.cpp
+++ b/trace_streamer/src/trace_data/trace_stdtype/ftrace/callstack_stdtype.cpp
@@ -21,8 +21,10 @@ size_t CallStack::AppendInternalAsyncSlice(const CallStackInternalRow &callStack
const std::optional &parentId)
{
AppendCommonInfo(callStackInternalRow.startT, callStackInternalRow.durationNs, callStackInternalRow.internalTid);
- AppendCallStack(callStackInternalRow.cat, callStackInternalRow.name, callStackInternalRow.depth, parentId);
+ AppendCallStack(callStackInternalRow.cat, callStackInternalRow.name, callStackInternalRow.depth,
+ callStackInternalRow.childCallid, parentId);
AppendDistributeInfo();
+ AppendTraceMetadata();
cookies_.emplace_back(cookid);
ids_.emplace_back(id_++);
return Size() - 1;
@@ -31,10 +33,12 @@ size_t CallStack::AppendInternalSlice(const CallStackInternalRow &callStackInter
const std::optional &parentId)
{
AppendCommonInfo(callStackInternalRow.startT, callStackInternalRow.durationNs, callStackInternalRow.internalTid);
- AppendCallStack(callStackInternalRow.cat, callStackInternalRow.name, callStackInternalRow.depth, parentId);
+ AppendCallStack(callStackInternalRow.cat, callStackInternalRow.name, callStackInternalRow.depth,
+ callStackInternalRow.childCallid, parentId);
ids_.emplace_back(id_++);
cookies_.emplace_back(INVALID_INT64);
AppendDistributeInfo();
+ AppendTraceMetadata();
return Size() - 1;
}
@@ -45,12 +49,17 @@ void CallStack::AppendCommonInfo(uint64_t startT, uint64_t durationNs, InternalT
callIds_.emplace_back(internalTid);
colorIndexs_.emplace_back(0);
}
-void CallStack::AppendCallStack(DataIndex cat, DataIndex name, uint8_t depth, std::optional parentId)
+void CallStack::AppendCallStack(DataIndex cat,
+ DataIndex name,
+ uint8_t depth,
+ std::optional childCallid,
+ std::optional parentId)
{
parentIds_.emplace_back(parentId);
cats_.emplace_back(cat);
names_.emplace_back(name);
depths_.emplace_back(depth);
+ childCallid_.emplace_back(childCallid);
}
void CallStack::SetDistributeInfo(size_t index,
const std::string &chainId,
@@ -64,6 +73,17 @@ void CallStack::SetDistributeInfo(size_t index,
flags_[index] = flag;
argSet_[index] = INVALID_UINT32;
}
+void CallStack::SetTraceMetadata(size_t index,
+ const std::string &traceLevel,
+ const DataIndex &tag,
+ const DataIndex &customArg,
+ const DataIndex &customCategory)
+{
+ traceLevels_[index] = traceLevel;
+ traceTags_[index] = tag;
+ customArgs_[index] = customArg;
+ customCategorys_[index] = customCategory;
+}
void CallStack::AppendDistributeInfo()
{
chainIds_.emplace_back("");
@@ -72,6 +92,13 @@ void CallStack::AppendDistributeInfo()
flags_.emplace_back("");
argSet_.emplace_back(INVALID_UINT32);
}
+void CallStack::AppendTraceMetadata()
+{
+ traceLevels_.emplace_back("");
+ traceTags_.emplace_back(INVALID_UINT64);
+ customArgs_.emplace_back(INVALID_UINT64);
+ customCategorys_.emplace_back(INVALID_UINT64);
+}
void CallStack::SetDuration(size_t index, uint64_t timeStamp)
{
durs_[index] = timeStamp - timeStamps_[index];
@@ -161,5 +188,25 @@ const std::deque &CallStack::ArgSetIdsData() const
{
return argSet_;
}
+const std::deque &CallStack::TraceLevelsData() const
+{
+ return traceLevels_;
+}
+const std::deque &CallStack::TraceTagsData() const
+{
+ return traceTags_;
+}
+const std::deque &CallStack::CustomCategorysData() const
+{
+ return customCategorys_;
+}
+const std::deque &CallStack::CustomArgsData() const
+{
+ return customArgs_;
+}
+const std::deque> &CallStack::ChildCallidData() const
+{
+ return childCallid_;
+}
} // namespace TraceStdtype
} // namespace SysTuning
diff --git a/trace_streamer/src/trace_data/trace_stdtype/ftrace/callstack_stdtype.h b/trace_streamer/src/trace_data/trace_stdtype/ftrace/callstack_stdtype.h
index 033d25db69434ed63d6e59f31b1214569fbe219e..07b5322b212a9b57bb7e1430e76b79e01317e68f 100644
--- a/trace_streamer/src/trace_data/trace_stdtype/ftrace/callstack_stdtype.h
+++ b/trace_streamer/src/trace_data/trace_stdtype/ftrace/callstack_stdtype.h
@@ -29,6 +29,7 @@ struct CallStackInternalRow {
DataIndex cat = INVALID_UINT64;
DataIndex name = INVALID_UINT64;
uint8_t depth = INVALID_UINT8;
+ uint32_t childCallid = INVALID_UINT32;
};
class CallStack : public CacheBase, public CpuCacheBase, public BatchCacheBase {
public:
@@ -43,7 +44,13 @@ public:
const std::string &parentSpanId,
const std::string &flag);
void AppendDistributeInfo();
+ void AppendTraceMetadata();
void SetDuration(size_t index, uint64_t timeStamp);
+ void SetTraceMetadata(size_t index,
+ const std::string &traceLevel,
+ const DataIndex &tag,
+ const DataIndex &customArg,
+ const DataIndex &customCategory = INVALID_UINT64);
void SetDurationWithFlag(size_t index, uint64_t timeStamp);
void SetFlag(size_t index, uint8_t flag);
void SetDurationEx(size_t index, uint32_t dur);
@@ -67,11 +74,17 @@ public:
parentSpanIds_.clear();
flags_.clear();
argSet_.clear();
+ traceLevels_.clear();
+ traceTags_.clear();
+ customCategorys_.clear();
+ customArgs_.clear();
+ childCallid_.clear();
}
void ClearExportedData() override
{
EraseElements(timeStamps_, ids_, durs_, cats_, cookies_, colorIndexs_, callIds_, names_, depths_, chainIds_,
- spanIds_, parentSpanIds_, flags_, argSet_);
+ spanIds_, parentSpanIds_, flags_, argSet_, traceLevels_, traceTags_, customCategorys_,
+ customArgs_, childCallid_);
}
const std::deque> &ParentIdData() const;
const std::deque &CatsData() const;
@@ -85,10 +98,19 @@ public:
const std::deque &ParentSpanIds() const;
const std::deque &Flags() const;
const std::deque &ArgSetIdsData() const;
+ const std::deque &TraceLevelsData() const;
+ const std::deque &TraceTagsData() const;
+ const std::deque &CustomCategorysData() const;
+ const std::deque &CustomArgsData() const;
+ const std::deque> &ChildCallidData() const;
private:
void AppendCommonInfo(uint64_t startT, uint64_t durationNs, InternalTid internalTid);
- void AppendCallStack(DataIndex cat, DataIndex name, uint8_t depth, std::optional parentId);
+ void AppendCallStack(DataIndex cat,
+ DataIndex name,
+ uint8_t depth,
+ std::optional childCallid,
+ std::optional parentId);
private:
std::deque> parentIds_;
@@ -103,6 +125,11 @@ private:
std::deque parentSpanIds_ = {};
std::deque flags_ = {};
std::deque argSet_ = {};
+ std::deque traceLevels_ = {};
+ std::deque traceTags_ = {};
+ std::deque customCategorys_ = {};
+ std::deque customArgs_ = {};
+ std::deque> childCallid_;
};
} // namespace TraceStdtype
} // namespace SysTuning
diff --git a/trace_streamer/src/version.cpp b/trace_streamer/src/version.cpp
index 9544e6498e01649b5442a02d199c414bfe7986de..7a8226dd8c43818192660f6e726af26a3d8992f7 100644
--- a/trace_streamer/src/version.cpp
+++ b/trace_streamer/src/version.cpp
@@ -17,7 +17,7 @@ namespace SysTuning {
namespace TraceStreamer {
size_t g_loadSize = 0;
size_t g_fileSize = 0;
-const std::string TRACE_STREAMER_VERSION = "4.2.9"; // version
-const std::string TRACE_STREAMER_PUBLISH_VERSION = "2025/1/2"; // publish datetime
+const std::string TRACE_STREAMER_VERSION = "4.3.2"; // version
+const std::string TRACE_STREAMER_PUBLISH_VERSION = "2025/4/24"; // publish datetime
} // namespace TraceStreamer
} // namespace SysTuning