Add out/in thread+process info to flow events
Screenshot: https://screenshot.googleplex.com/9XoghXsgQzLbJqk
NULL in the selection case as the UI doesn't display
per-event info in that case so the join isn't worth it.
Clicking any column currently toggles the selection (same as
before). In a follow-up I plan to have Duration select the
begin<=>end range and Thread/Process scroll to the
source/destination of the flow.
Dropped the .half-width CSS property from this table as it
was unnecessarily collapsing the added info.
Bug: b/224527755
Change-Id: I6229209b388eca34d098d75f8b7ba6abdea3c98d
diff --git a/ui/src/controller/flow_events_controller.ts b/ui/src/controller/flow_events_controller.ts
index 8e9254c..20ae793 100644
--- a/ui/src/controller/flow_events_controller.ts
+++ b/ui/src/controller/flow_events_controller.ts
@@ -64,6 +64,8 @@
beginSliceStartTs: NUM,
beginSliceEndTs: NUM,
beginDepth: NUM,
+ beginThreadName: STR_NULL,
+ beginProcessName: STR_NULL,
endSliceId: NUM,
endTrackId: NUM,
endSliceName: STR_NULL,
@@ -71,6 +73,8 @@
endSliceStartTs: NUM,
endSliceEndTs: NUM,
endDepth: NUM,
+ endThreadName: STR_NULL,
+ endProcessName: STR_NULL,
name: STR_NULL,
category: STR_NULL,
id: NUM,
@@ -85,6 +89,10 @@
const beginSliceStartTs = fromNs(it.beginSliceStartTs);
const beginSliceEndTs = fromNs(it.beginSliceEndTs);
const beginDepth = it.beginDepth;
+ const beginThreadName =
+ it.beginThreadName === null ? 'NULL' : it.beginThreadName;
+ const beginProcessName =
+ it.beginProcessName === null ? 'NULL' : it.beginProcessName;
const endSliceId = it.endSliceId;
const endTrackId = it.endTrackId;
@@ -95,6 +103,10 @@
const endSliceStartTs = fromNs(it.endSliceStartTs);
const endSliceEndTs = fromNs(it.endSliceEndTs);
const endDepth = it.endDepth;
+ const endThreadName =
+ it.endThreadName === null ? 'NULL' : it.endThreadName;
+ const endProcessName =
+ it.endProcessName === null ? 'NULL' : it.endProcessName;
// Category and name present only in version 1 flow events
// It is most likelly NULL for all other versions
@@ -111,7 +123,9 @@
sliceCategory: beginSliceCategory,
sliceStartTs: beginSliceStartTs,
sliceEndTs: beginSliceEndTs,
- depth: beginDepth
+ depth: beginDepth,
+ threadName: beginThreadName,
+ processName: beginProcessName
},
end: {
trackId: endTrackId,
@@ -120,7 +134,9 @@
sliceCategory: endSliceCategory,
sliceStartTs: endSliceStartTs,
sliceEndTs: endSliceEndTs,
- depth: endDepth
+ depth: endDepth,
+ threadName: endThreadName,
+ processName: endProcessName
},
dur: endSliceStartTs - beginSliceEndTs,
category,
@@ -156,6 +172,8 @@
t1.ts as beginSliceStartTs,
(t1.ts+t1.dur) as beginSliceEndTs,
t1.depth as beginDepth,
+ (thread_out.name || ' ' || thread_out.tid) as beginThreadName,
+ (process_out.name || ' ' || process_out.pid) as beginProcessName,
f.slice_in as endSliceId,
t2.track_id as endTrackId,
t2.name as endSliceName,
@@ -163,12 +181,20 @@
t2.ts as endSliceStartTs,
(t2.ts+t2.dur) as endSliceEndTs,
t2.depth as endDepth,
+ (thread_in.name || ' ' || thread_in.tid) as endThreadName,
+ (process_in.name || ' ' || process_in.pid) as endProcessName,
extract_arg(f.arg_set_id, 'cat') as category,
extract_arg(f.arg_set_id, 'name') as name,
f.id as id
from ${connectedFlows} f
join slice t1 on f.slice_out = t1.slice_id
join slice t2 on f.slice_in = t2.slice_id
+ join thread_track track_out on track_out.id = t1.track_id
+ join thread thread_out on thread_out.utid = track_out.utid
+ join thread_track track_in on track_in.id = t2.track_id
+ join thread thread_in on thread_in.utid = track_in.utid
+ join process process_out on process_out.upid = thread_out.upid
+ join process process_in on process_in.upid = thread_in.upid
`;
this.queryFlowEvents(
query, (flows: Flow[]) => publishConnectedFlows(flows));
@@ -217,6 +243,8 @@
t1.ts as beginSliceStartTs,
(t1.ts+t1.dur) as beginSliceEndTs,
t1.depth as beginDepth,
+ NULL as beginThreadName,
+ NULL as beginProcessName,
f.slice_in as endSliceId,
t2.track_id as endTrackId,
t2.name as endSliceName,
@@ -224,6 +252,8 @@
t2.ts as endSliceStartTs,
(t2.ts+t2.dur) as endSliceEndTs,
t2.depth as endDepth,
+ NULL as endThreadName,
+ NULL as endProcessName,
extract_arg(f.arg_set_id, 'cat') as category,
extract_arg(f.arg_set_id, 'name') as name,
f.id as id
diff --git a/ui/src/frontend/flow_events_panel.ts b/ui/src/frontend/flow_events_panel.ts
index 500148c..c7783b9 100644
--- a/ui/src/frontend/flow_events_panel.ts
+++ b/ui/src/frontend/flow_events_panel.ts
@@ -61,7 +61,11 @@
m('th', 'Direction'),
m('th', 'Duration'),
m('th', 'Connected Slice ID'),
- m('th', 'Connected Slice Name')
+ m('th', 'Connected Slice Name'),
+ m('th', 'Thread Out'),
+ m('th', 'Thread In'),
+ m('th', 'Process Out'),
+ m('th', 'Process In')
];
if (haveCategories) {
@@ -93,7 +97,11 @@
m('td.flow-link', args, outgoing ? 'Outgoing' : 'Incoming'),
m('td.flow-link', args, timeToCode(flow.dur)),
m('td.flow-link', args, otherEnd.sliceId.toString()),
- m('td.flow-link', args, otherEnd.sliceName)
+ m('td.flow-link', args, otherEnd.sliceName),
+ m('td.flow-link', args, flow.begin.threadName),
+ m('td.flow-link', args, flow.end.threadName),
+ m('td.flow-link', args, flow.begin.processName),
+ m('td.flow-link', args, flow.end.processName)
];
if (haveCategories) {
@@ -106,7 +114,7 @@
return m('.details-panel', [
m('.details-panel-heading', m('h2', `Flow events`)),
- m('.flow-events-table', m('table.half-width', rows))
+ m('.flow-events-table', m('table', rows))
]);
}
diff --git a/ui/src/frontend/globals.ts b/ui/src/frontend/globals.ts
index 473a945..71e2a34 100644
--- a/ui/src/frontend/globals.ts
+++ b/ui/src/frontend/globals.ts
@@ -77,6 +77,12 @@
sliceId: number;
sliceStartTs: number;
sliceEndTs: number;
+ // Thread and process info. Only set in sliceSelected not in areaSelected as
+ // the latter doesn't display per-flow info and it'd be a waste to join
+ // additional tables for undisplayed info in that case. Nothing precludes
+ // adding this in a future iteration however.
+ threadName: string;
+ processName: string;
depth: number;
}