[ dart:developer ] Added filterKey optional parameter to TimelineTask constructors.

Providing `filterKey` will result in all timeline events associated with
the TimelineTask including a `filterKey` entry in their arguments map,
set to the value provided in the constructor. This will allow for a
consistent way for tooling to filter asynchronous timeline events.

Fixes https://github.com/dart-lang/sdk/issues/40861

Change-Id: I06d3f9c73f06c2ff0e495f1b6a57fcf357d625a8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/139312
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Kenzie Schmoll <kenzieschmoll@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
Ben Konyi 2020-03-16 18:04:58 +00:00 committed by commit-bot@chromium.org
parent 3cbf1f65f3
commit 09f756b9a1
4 changed files with 64 additions and 9 deletions

View file

@ -14,6 +14,14 @@
was allowed. The value of that getter on a `TypeError` was the same
string as returned by `toString`, so it is still available.
#### `dart:developer`
* The constructors for `TimelineTask` now accept an optional `filterKey`
parameter. If provided, the arguments for all events associated with the task
will contain an entry named `filterKey`, set to the value of the `filterKey`
parameter provided in the constructor. This will be used by tooling to allow
for better filtering of timeline events.
#### `dart:html`
* **Breaking Change**: Changed the return type of several html native methods

View file

@ -15,7 +15,7 @@ primeTimeline() {
Timeline.instantSync('ISYNC', arguments: {'fruit': 'banana'});
Timeline.finishSync();
TimelineTask parentTask = TimelineTask.withTaskId(42);
TimelineTask task = TimelineTask(parent: parentTask);
TimelineTask task = TimelineTask(parent: parentTask, filterKey: 'testFilter');
task.start('TASK1', arguments: {'task1-start-key': 'task1-start-value'});
task.instant('ITASK',
arguments: {'task1-instant-key': 'task1-instant-value'});
@ -133,17 +133,22 @@ var tests = <VMTest>[
expect(eventsContains(dartEvents, 'E', 'apple'), isTrue);
expect(
eventsContains(dartEvents, 'b', 'TASK1', {
'filterKey': 'testFilter',
'task1-start-key': 'task1-start-value',
'parentId': 42.toRadixString(16)
}),
isTrue);
expect(
eventsContains(dartEvents, 'e', 'TASK1',
{'task1-finish-key': 'task1-finish-value'}),
eventsContains(dartEvents, 'e', 'TASK1', {
'filterKey': 'testFilter',
'task1-finish-key': 'task1-finish-value',
}),
isTrue);
expect(
eventsContains(dartEvents, 'n', 'ITASK',
{'task1-instant-key': 'task1-instant-value'}),
eventsContains(dartEvents, 'n', 'ITASK', {
'filterKey': 'testFilter',
'task1-instant-key': 'task1-instant-value',
}),
isTrue);
expect(eventsContains(dartEvents, 'q', 'ITASK'), isFalse);
expect(eventsContains(dartEvents, 'B', 'peach'), isTrue);

View file

@ -186,8 +186,13 @@ class TimelineTask {
/// If [parent] is provided, the parent's task ID is provided as argument
/// 'parentId' when [start] is called. In DevTools, this argument will result
/// in this [TimelineTask] being linked to the [parent] [TimelineTask].
TimelineTask({TimelineTask parent})
///
/// If [filterKey] is provided, a property named `filterKey` will be inserted
/// into the arguments of each event associated with this task. The
/// `filterKey` will be set to the value of [filterKey].
TimelineTask({TimelineTask parent, String filterKey})
: _parent = parent,
_filterKey = filterKey,
_taskId = _getNextAsyncId() {}
/// Create a task with an explicit [taskId]. This is useful if you are
@ -196,8 +201,13 @@ class TimelineTask {
/// Important note: only provide task IDs which have been obtained as a
/// result of invoking [TimelineTask.pass]. Specifying a custom ID can lead
/// to ID collisions, resulting in incorrect rendering of timeline events.
TimelineTask.withTaskId(int taskId)
///
/// If [filterKey] is provided, a property named `filterKey` will be inserted
/// into the arguments of each event associated with this task. The
/// `filterKey` will be set to the value of [filterKey].
TimelineTask.withTaskId(int taskId, {String filterKey})
: _parent = null,
_filterKey = filterKey,
_taskId = taskId {
ArgumentError.checkNotNull(taskId, 'taskId');
}
@ -212,6 +222,7 @@ class TimelineTask {
block._start({
if (arguments != null) ...arguments,
if (_parent != null) 'parentId': _parent._taskId.toRadixString(16),
if (_filterKey != null) _kFilterKey: _filterKey,
});
}
@ -224,6 +235,10 @@ class TimelineTask {
if (arguments != null) {
instantArguments = new Map.from(arguments);
}
if (_filterKey != null) {
instantArguments ??= {};
instantArguments[_kFilterKey] = _filterKey;
}
_reportTaskEvent(
_taskId, 'n', 'Dart', name, _argumentsAsJson(instantArguments));
}
@ -237,6 +252,10 @@ class TimelineTask {
if (_stack.length == 0) {
throw new StateError('Uneven calls to start and finish');
}
if (_filterKey != null) {
arguments ??= {};
arguments[_kFilterKey] = _filterKey;
}
// Pop top item off of stack.
var block = _stack.removeLast();
block._finish(arguments);
@ -254,7 +273,9 @@ class TimelineTask {
return r;
}
static const String _kFilterKey = 'filterKey';
final TimelineTask _parent;
final String _filterKey;
final int _taskId;
final List<_AsyncBlock> _stack = [];
}

View file

@ -186,8 +186,13 @@ class TimelineTask {
/// If [parent] is provided, the parent's task ID is provided as argument
/// 'parentId' when [start] is called. In DevTools, this argument will result
/// in this [TimelineTask] being linked to the [parent] [TimelineTask].
TimelineTask({TimelineTask? parent})
///
/// If [filterKey] is provided, a property named `filterKey` will be inserted
/// into the arguments of each event associated with this task. The
/// `filterKey` will be set to the value of [filterKey].
TimelineTask({TimelineTask? parent, String? filterKey})
: _parent = parent,
_filterKey = filterKey,
_taskId = _getNextAsyncId() {}
/// Create a task with an explicit [taskId]. This is useful if you are
@ -196,8 +201,13 @@ class TimelineTask {
/// Important note: only provide task IDs which have been obtained as a
/// result of invoking [TimelineTask.pass]. Specifying a custom ID can lead
/// to ID collisions, resulting in incorrect rendering of timeline events.
TimelineTask.withTaskId(int taskId)
///
/// If [filterKey] is provided, a property named `filterKey` will be inserted
/// into the arguments of each event associated with this task. The
/// `filterKey` will be set to the value of [filterKey].
TimelineTask.withTaskId(int taskId, {String? filterKey})
: _parent = null,
_filterKey = filterKey,
_taskId = taskId {
// TODO: When NNBD is complete, delete the following line.
ArgumentError.checkNotNull(taskId, 'taskId');
@ -222,6 +232,7 @@ class TimelineTask {
}
}
if (_parent != null) map['parentId'] = _parent!._taskId.toRadixString(16);
if (_filterKey != null) map[_kFilterKey] = _filterKey;
block._start(map);
}
@ -235,6 +246,10 @@ class TimelineTask {
if (arguments != null) {
instantArguments = new Map.from(arguments);
}
if (_filterKey != null) {
instantArguments ??= {};
instantArguments[_kFilterKey] = _filterKey;
}
_reportTaskEvent(
_taskId, 'n', 'Dart', name, _argumentsAsJson(instantArguments));
}
@ -248,6 +263,10 @@ class TimelineTask {
if (_stack.length == 0) {
throw new StateError('Uneven calls to start and finish');
}
if (_filterKey != null) {
arguments ??= {};
arguments[_kFilterKey] = _filterKey;
}
// Pop top item off of stack.
var block = _stack.removeLast();
block._finish(arguments);
@ -265,7 +284,9 @@ class TimelineTask {
return r;
}
static const String _kFilterKey = 'filterKey';
final TimelineTask? _parent;
final String? _filterKey;
final int _taskId;
final List<_AsyncBlock> _stack = [];
}