Skip to content

Commit dcd4619

Browse files
committed
merging
1 parent c244fb3 commit dcd4619

File tree

6 files changed

+357
-78
lines changed

6 files changed

+357
-78
lines changed

include/perfetto/public/protos/trace/track_event/track_descriptor.pzc.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,20 @@ PERFETTO_PB_ENUM_IN_MSG(perfetto_protos_TrackDescriptor, ChildTracksOrdering){
4141
EXPLICIT) = 3,
4242
};
4343

44+
PERFETTO_PB_ENUM_IN_MSG(perfetto_protos_TrackDescriptor, SiblingMergeBehavior){
45+
PERFETTO_PB_ENUM_IN_MSG_ENTRY(perfetto_protos_TrackDescriptor,
46+
SIBLING_MERGE_BEHAVIOR_UNSPECIFIED) = 0,
47+
PERFETTO_PB_ENUM_IN_MSG_ENTRY(perfetto_protos_TrackDescriptor,
48+
SIBLING_MERGE_BEHAVIOR_LEGACY) = 1,
49+
PERFETTO_PB_ENUM_IN_MSG_ENTRY(perfetto_protos_TrackDescriptor,
50+
SIBLING_MERGE_BEHAVIOR_NONE) = 2,
51+
PERFETTO_PB_ENUM_IN_MSG_ENTRY(perfetto_protos_TrackDescriptor,
52+
SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME) = 3,
53+
PERFETTO_PB_ENUM_IN_MSG_ENTRY(perfetto_protos_TrackDescriptor,
54+
SIBLING_MERGE_BEHAVIOR_BY_SIBLING_MERGE_KEY) =
55+
4,
56+
};
57+
4458
PERFETTO_PB_MSG(perfetto_protos_TrackDescriptor);
4559
PERFETTO_PB_FIELD(perfetto_protos_TrackDescriptor, VARINT, uint64_t, uuid, 1);
4660
PERFETTO_PB_FIELD(perfetto_protos_TrackDescriptor,
@@ -103,5 +117,15 @@ PERFETTO_PB_FIELD(perfetto_protos_TrackDescriptor,
103117
int32_t,
104118
sibling_order_rank,
105119
12);
120+
PERFETTO_PB_FIELD(perfetto_protos_TrackDescriptor,
121+
VARINT,
122+
enum perfetto_protos_TrackDescriptor_SiblingMergeBehavior,
123+
sibling_merge_behavior,
124+
14);
125+
PERFETTO_PB_FIELD(perfetto_protos_TrackDescriptor,
126+
STRING,
127+
const char*,
128+
sibling_merge_key,
129+
15);
106130

107131
#endif // INCLUDE_PERFETTO_PUBLIC_PROTOS_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PZC_H_

protos/perfetto/trace/perfetto_trace.proto

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16144,6 +16144,7 @@ message TrackDescriptor {
1614416144

1614516145
// If true, forces Trace Processor to use separate tracks for track events
1614616146
// and system events for the same thread.
16147+
//
1614716148
// Track events timestamps in Chrome have microsecond resolution, while
1614816149
// system events use nanoseconds. It results in broken event nesting when
1614916150
// track events and system events share a track.
@@ -16180,9 +16181,128 @@ message TrackDescriptor {
1618016181
// tracks with higher ranks. An unspecified rank will be treated as a rank of
1618116182
// 0.
1618216183
//
16184+
// Note: this option is only relevant for tracks where the parent has
16185+
// `child_ordering` set to `EXPLICIT`. It is ignored otherwise.
16186+
//
1618316187
// Note: for tracks where the parent has `thread` or `process` are set, this
16184-
// option is *ignored*. See `parent_uuid` for details.
16188+
// option is *ignored* (even if the parent's `child_ordering` is `EXPLICIT``).
16189+
// See `parent_uuid` for details.
1618516190
optional int32 sibling_order_rank = 12;
16191+
16192+
// Specifies how the UI (and potentially in the future, the trace processor)
16193+
// should "merge" different sibling TrackEvent tracks into a single "analysis"
16194+
// track. This is useful for reducing the vertical space used in the UI when
16195+
// there are many tracks all showing the same "type" of events (e.g. network
16196+
// requests, Android broadcasts, Linux wakelocks).
16197+
//
16198+
// When tracks are merged togther, the properties for the merged track will be
16199+
// chosen from the source tracks based on the following rules:
16200+
// - for `sibling_order_rank`: the rank of the merged track will be the
16201+
// smallest rank among the source tracks.
16202+
// - for all other properties: the property taken is unspecified and can
16203+
// be any value provided by one of the source tracks
16204+
// - examples of other properties include `name`, `child_ordering` etc.
16205+
// - because of this, it's recommended to ensure that all source tracks
16206+
// have the same value for these properties.
16207+
// - the trace processor will also emit an error stat if it detects
16208+
// that the properties are not the same across all source tracks.
16209+
//
16210+
// Note: merging is done *recursively* so entire trees of tracks can be merged
16211+
// together. To make this clearer, consider an example track hierarchy (in
16212+
// the diagrams: "smk" refers to "sibling_merge_key", the first word on a
16213+
// track line, like "Updater", is its 'name' property):
16214+
//
16215+
// Initial track hierarchy:
16216+
// SystemActivity
16217+
// ├── AuthService (smk: "auth_main_cluster")
16218+
// │ └── LoginOp (smk: "login_v1")
16219+
// ├── AuthService (smk: "auth_main_cluster")
16220+
// │ └── LoginOp (smk: "login_v1")
16221+
// ├── AuthService (smk: "auth_backup_cluster")
16222+
// │ └── GuestOp (smk: "guest_v1")
16223+
// └── UserProfileService (smk: "profile_cluster")
16224+
// └── GetProfileOp (smk: "getprofile_v1")
16225+
//
16226+
// Merging outcomes:
16227+
//
16228+
// Scenario 1: Merging by `SIBLING_MERGE_BEHAVIOR_BY_SIBLING_MERGE_KEY`
16229+
// - The first two "AuthService" tracks merge because they share
16230+
// `smk: "auth_main_cluster"`. Their names are consistent ("AuthService"),
16231+
// aligning with recommendations. The merged track is named "AuthService".
16232+
// - The third "AuthService" track (with `smk: "auth_backup_cluster"`)
16233+
// remains separate, as its `sibling_merge_key` is different.
16234+
// - "UserProfileService" also remains separate.
16235+
// - Within the merged "AuthService" (from "auth_main_cluster"):
16236+
// "LoginOp" get merged as they have the same sibling merge key.
16237+
//
16238+
// Resulting UI (when merging by SIBLING_MERGE_KEY):
16239+
// SystemActivity
16240+
// ├── AuthService (merged by smk: "auth_main_cluster")
16241+
// │ ├── LoginOp (merged by smk: "login_v1")
16242+
// ├── AuthService (smk: "auth_backup_cluster")
16243+
// │ └── GuestOp (smk: "guest_v1")
16244+
// └── UserProfileService (smk: "profile_cluster")
16245+
// └── GetProfileOp (smk: "getprofile_v1")
16246+
//
16247+
// Scenario 2: Merging by `SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME`
16248+
// - All three tracks named "AuthService" merge because they share the same
16249+
// name. The merged track is named "AuthService". The `sibling_merge_key`
16250+
// for this merged track would be taken from one of the source tracks
16251+
// (e.g., "auth_main_cluster" or "auth_backup_cluster"), which could be
16252+
// relevant if its children had key-based merge behaviors.
16253+
// - "UserProfileService" remains separate due to its different name.
16254+
// - Within the single merged "AuthService" track:
16255+
// "LoginOp", "GuestOp" become siblings. "LoginOp" tracks gets merged as
16256+
// they have the same name.
16257+
//
16258+
// Resulting UI (when merging by SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME):
16259+
// SystemActivity
16260+
// ├── AuthService (merged from 3 "AuthService" tracks)
16261+
// │ ├── LoginOp (smk: "login_v1")
16262+
// │ └── GuestOp (smk: "guest_v1")
16263+
// └── UserProfileService (smk: "profile_cluster")
16264+
// └── GetProfileOp (smk: "getprofile_v1")
16265+
//
16266+
// Note: for tracks where `thread` or `process` are set, this option is
16267+
// *ignored*. See `parent_uuid` for details.
16268+
//
16269+
// Note: this flag only affects the UI for now but we expect this also to be
16270+
// respected by the trace processor in the future to allow for consistency
16271+
// between you see and what you query.
16272+
enum SiblingMergeBehavior {
16273+
// When unspecified or not set, defaults to `SIBLING_MERGE_BEHAVIOR_LEGACY`.
16274+
SIBLING_MERGE_BEHAVIOR_UNSPECIFIED = 0;
16275+
16276+
// The "legacy" behaviour for merging which predates the introduction of
16277+
// this field. Any siblings tracks with the same `name` will be merged
16278+
// together *except* when those tracks have a child *themselves*.
16279+
//
16280+
// A bit of history on why this exists: this behaviour was inherited from
16281+
// chrome://tracing (Catapult) and exists mainly to not break existing
16282+
// traces. In general, if possible don't use this and prefer to instead
16283+
// explicitly set the `sibling_merge_behavior` to one of the other
16284+
// options.
16285+
SIBLING_MERGE_BEHAVIOR_LEGACY = 1;
16286+
16287+
// Never merge this track with any siblings. Useful if if this track has a
16288+
// specific meaning and you want to see separately from any others.
16289+
SIBLING_MERGE_BEHAVIOR_NONE = 2;
16290+
16291+
// Merge this track with eligible siblings which have the same `name`.
16292+
SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME = 3;
16293+
16294+
// Merge this track with eligible siblings which have the same
16295+
// `sibling_merge_key`.
16296+
SIBLING_MERGE_BEHAVIOR_BY_SIBLING_MERGE_KEY = 4;
16297+
}
16298+
optional SiblingMergeBehavior sibling_merge_behavior = 14;
16299+
16300+
// An opaque value which allows specifying which tracks should be merged
16301+
// together.
16302+
//
16303+
// Only meaningful when `sibling_merge_behavior` is set to
16304+
// `SIBLING_MERGE_BEHAVIOR_BY_SIBLING_MERGE_KEY`.
16305+
optional string sibling_merge_key = 15;
1618616306
}
1618716307

1618816308
// End of protos/perfetto/trace/track_event/track_descriptor.proto

protos/perfetto/trace/track_event/track_descriptor.proto

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ message TrackDescriptor {
112112

113113
// If true, forces Trace Processor to use separate tracks for track events
114114
// and system events for the same thread.
115+
//
115116
// Track events timestamps in Chrome have microsecond resolution, while
116117
// system events use nanoseconds. It results in broken event nesting when
117118
// track events and system events share a track.
@@ -148,7 +149,126 @@ message TrackDescriptor {
148149
// tracks with higher ranks. An unspecified rank will be treated as a rank of
149150
// 0.
150151
//
152+
// Note: this option is only relevant for tracks where the parent has
153+
// `child_ordering` set to `EXPLICIT`. It is ignored otherwise.
154+
//
151155
// Note: for tracks where the parent has `thread` or `process` are set, this
152-
// option is *ignored*. See `parent_uuid` for details.
156+
// option is *ignored* (even if the parent's `child_ordering` is `EXPLICIT``).
157+
// See `parent_uuid` for details.
153158
optional int32 sibling_order_rank = 12;
159+
160+
// Specifies how the UI (and potentially in the future, the trace processor)
161+
// should "merge" different sibling TrackEvent tracks into a single "analysis"
162+
// track. This is useful for reducing the vertical space used in the UI when
163+
// there are many tracks all showing the same "type" of events (e.g. network
164+
// requests, Android broadcasts, Linux wakelocks).
165+
//
166+
// When tracks are merged togther, the properties for the merged track will be
167+
// chosen from the source tracks based on the following rules:
168+
// - for `sibling_order_rank`: the rank of the merged track will be the
169+
// smallest rank among the source tracks.
170+
// - for all other properties: the property taken is unspecified and can
171+
// be any value provided by one of the source tracks
172+
// - examples of other properties include `name`, `child_ordering` etc.
173+
// - because of this, it's recommended to ensure that all source tracks
174+
// have the same value for these properties.
175+
// - the trace processor will also emit an error stat if it detects
176+
// that the properties are not the same across all source tracks.
177+
//
178+
// Note: merging is done *recursively* so entire trees of tracks can be merged
179+
// together. To make this clearer, consider an example track hierarchy (in
180+
// the diagrams: "smk" refers to "sibling_merge_key", the first word on a
181+
// track line, like "Updater", is its 'name' property):
182+
//
183+
// Initial track hierarchy:
184+
// SystemActivity
185+
// ├── AuthService (smk: "auth_main_cluster")
186+
// │ └── LoginOp (smk: "login_v1")
187+
// ├── AuthService (smk: "auth_main_cluster")
188+
// │ └── LoginOp (smk: "login_v1")
189+
// ├── AuthService (smk: "auth_backup_cluster")
190+
// │ └── GuestOp (smk: "guest_v1")
191+
// └── UserProfileService (smk: "profile_cluster")
192+
// └── GetProfileOp (smk: "getprofile_v1")
193+
//
194+
// Merging outcomes:
195+
//
196+
// Scenario 1: Merging by `SIBLING_MERGE_BEHAVIOR_BY_SIBLING_MERGE_KEY`
197+
// - The first two "AuthService" tracks merge because they share
198+
// `smk: "auth_main_cluster"`. Their names are consistent ("AuthService"),
199+
// aligning with recommendations. The merged track is named "AuthService".
200+
// - The third "AuthService" track (with `smk: "auth_backup_cluster"`)
201+
// remains separate, as its `sibling_merge_key` is different.
202+
// - "UserProfileService" also remains separate.
203+
// - Within the merged "AuthService" (from "auth_main_cluster"):
204+
// "LoginOp" get merged as they have the same sibling merge key.
205+
//
206+
// Resulting UI (when merging by SIBLING_MERGE_KEY):
207+
// SystemActivity
208+
// ├── AuthService (merged by smk: "auth_main_cluster")
209+
// │ ├── LoginOp (merged by smk: "login_v1")
210+
// ├── AuthService (smk: "auth_backup_cluster")
211+
// │ └── GuestOp (smk: "guest_v1")
212+
// └── UserProfileService (smk: "profile_cluster")
213+
// └── GetProfileOp (smk: "getprofile_v1")
214+
//
215+
// Scenario 2: Merging by `SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME`
216+
// - All three tracks named "AuthService" merge because they share the same
217+
// name. The merged track is named "AuthService". The `sibling_merge_key`
218+
// for this merged track would be taken from one of the source tracks
219+
// (e.g., "auth_main_cluster" or "auth_backup_cluster"), which could be
220+
// relevant if its children had key-based merge behaviors.
221+
// - "UserProfileService" remains separate due to its different name.
222+
// - Within the single merged "AuthService" track:
223+
// "LoginOp", "GuestOp" become siblings. "LoginOp" tracks gets merged as
224+
// they have the same name.
225+
//
226+
// Resulting UI (when merging by SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME):
227+
// SystemActivity
228+
// ├── AuthService (merged from 3 "AuthService" tracks)
229+
// │ ├── LoginOp (smk: "login_v1")
230+
// │ └── GuestOp (smk: "guest_v1")
231+
// └── UserProfileService (smk: "profile_cluster")
232+
// └── GetProfileOp (smk: "getprofile_v1")
233+
//
234+
// Note: for tracks where `thread` or `process` are set, this option is
235+
// *ignored*. See `parent_uuid` for details.
236+
//
237+
// Note: this flag only affects the UI for now but we expect this also to be
238+
// respected by the trace processor in the future to allow for consistency
239+
// between you see and what you query.
240+
enum SiblingMergeBehavior {
241+
// When unspecified or not set, defaults to `SIBLING_MERGE_BEHAVIOR_LEGACY`.
242+
SIBLING_MERGE_BEHAVIOR_UNSPECIFIED = 0;
243+
244+
// The "legacy" behaviour for merging which predates the introduction of
245+
// this field. Any siblings tracks with the same `name` will be merged
246+
// together *except* when those tracks have a child *themselves*.
247+
//
248+
// A bit of history on why this exists: this behaviour was inherited from
249+
// chrome://tracing (Catapult) and exists mainly to not break existing
250+
// traces. In general, if possible don't use this and prefer to instead
251+
// explicitly set the `sibling_merge_behavior` to one of the other
252+
// options.
253+
SIBLING_MERGE_BEHAVIOR_LEGACY = 1;
254+
255+
// Never merge this track with any siblings. Useful if if this track has a
256+
// specific meaning and you want to see separately from any others.
257+
SIBLING_MERGE_BEHAVIOR_NONE = 2;
258+
259+
// Merge this track with eligible siblings which have the same `name`.
260+
SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME = 3;
261+
262+
// Merge this track with eligible siblings which have the same
263+
// `sibling_merge_key`.
264+
SIBLING_MERGE_BEHAVIOR_BY_SIBLING_MERGE_KEY = 4;
265+
}
266+
optional SiblingMergeBehavior sibling_merge_behavior = 14;
267+
268+
// An opaque value which allows specifying which tracks should be merged
269+
// together.
270+
//
271+
// Only meaningful when `sibling_merge_behavior` is set to
272+
// `SIBLING_MERGE_BEHAVIOR_BY_SIBLING_MERGE_KEY`.
273+
optional string sibling_merge_key = 15;
154274
}

python/perfetto/protos/perfetto/trace/perfetto_trace_pb2.py

Lines changed: 76 additions & 74 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)