Bug 1202706 - Part 1: Add telemetry histograms for worker use counters; r=chutten,bzbarsky

This patch uses similar architecture of use counters of main thread for workers.

Which introduces the following format histograms for use counters of workers

USE_COUNTER2_*_DEDICATED_WORKER
USE_COUNTER2_*_SHARED_WORKER
USE_COUNTER2_*_SERVICE_WORKER

And add the following histograms used in conjunction with above use counter histograms

DEDICATED_WORKER_DESTROYED
SHARED_WORKER_DESTROYED
SERVICE_WORKER_DESTROYED

Differential Revision: https://phabricator.services.mozilla.com/D53221

--HG--
rename : dom/base/UseCounters.conf => dom/base/UseCountersWorker.conf
extra : moz-landing-system : lando
This commit is contained in:
Edgar Chen 2019-11-26 17:36:44 +00:00
Родитель 58c1a14caa
Коммит 3f1d64ce15
7 изменённых файлов: 172 добавлений и 39 удалений

Просмотреть файл

@ -0,0 +1,67 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This file defines a list of use counters, which are things that can
// record usage of Web platform features and then report this information
// through Telemetry.
//
// The format of this file is very strict. Each line can be:
//
// (a) a blank line
//
// (b) a comment, which is a line that begins with "//"
//
// (c) one of four possible use counter declarations:
//
// method <IDL interface name>.<IDL operation name>
// attribute <IDL interface name>.<IDL attribute name>
// custom <any valid identifier> <description>
//
// The <description> for custom counters will be appended to "Whether a
// dedicated worker " or "Whether a shared worker" or "Whether a service worker
// ", so phrase it appropriately. For instance, "constructs a
// Foo object" or "calls Bar.baz('some value')". It may contain any character
// (including whitespace).
//
// To actually cause use counters to be incremented, DOM methods
// and attributes must have a [UseCounter] extended attribute and be exposed to
// workers in the Web IDL file.
// Custom counters are incremented when
// SetUseCounter(UseCounterWoker::Custom_MyName) is called on a WorkerPrivate
// object.
//
// You might reasonably ask why we have this file and we require
// annotating things with [UseCounter] in the relevant WebIDL file as
// well. Generating things from bindings codegen and ensuring all the
// dependencies were correct would have been rather difficult.
// Push API
method PushManager.subscribe
method PushSubscription.unsubscribe
// Console API
method console.assert
method console.clear
method console.count
method console.countReset
method console.debug
method console.error
method console.info
method console.log
method console.table
method console.trace
method console.warn
method console.dir
method console.dirxml
method console.group
method console.groupCollapsed
method console.groupEnd
method console.time
method console.timeLog
method console.timeEnd
method console.exception
method console.timeStamp
method console.profile
method console.profileEnd

Просмотреть файл

@ -43,9 +43,14 @@ def read_conf(conf_filename):
return parse_counters(stream)
def generate_histograms(filename):
def generate_histograms(filename, is_for_worker=False):
# The mapping for use counters to telemetry histograms depends on the
# ordering of items in the dictionary.
# The ordering of the ending for workers depends on the WorkerType defined
# in WorkerPrivate.h.
endings = ["DEDICATED_WORKER", "SHARED_WORKER", "SERVICE_WORKER"] if is_for_worker else ["DOCUMENT", "PAGE"]
items = collections.OrderedDict()
for counter in read_conf(filename):
def append_counter(name, desc):
@ -54,8 +59,9 @@ def generate_histograms(filename):
'description': desc }
def append_counters(name, desc):
append_counter('USE_COUNTER2_%s_DOCUMENT' % name, 'Whether a document %s' % desc)
append_counter('USE_COUNTER2_%s_PAGE' % name, 'Whether a page %s' % desc)
for ending in endings:
append_counter('USE_COUNTER2_%s_%s' % (name, ending),
'Whether a %s %s' % (ending.replace('_', ' ').lower(), desc))
if counter['type'] == 'method':
method = '%s.%s' % (counter['interface_name'], counter['method_name'])

Просмотреть файл

@ -11987,6 +11987,16 @@
"description": "Time (in ms) measured between when the fetch handler finished executing and when we reset the network channel."
},
"SERVICE_WORKER_DESTROYED": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec", "geckoview"],
"expires_in_version": "never",
"kind": "count",
"releaseChannelCollection": "opt-out",
"bug_numbers": [1202706],
"alert_emails": ["tdsmith@mozilla.com", "compatibility@lists.mozilla.org"],
"description": "Number of service workers destroyed; used in conjunction with use counter histograms"
},
"ONBEFOREUNLOAD_PROMPT_ACTION" : {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec", "geckoview"],
@ -12542,6 +12552,16 @@
"kind": "count",
"description": "Tracking whether a SharedWorker spawn gets queued due to hitting max workers per domain limit. File bugs in Core::DOM in case of a Telemetry regression."
},
"SHARED_WORKER_DESTROYED": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec", "geckoview"],
"expires_in_version": "never",
"kind": "count",
"releaseChannelCollection": "opt-out",
"bug_numbers": [1202706],
"alert_emails": ["tdsmith@mozilla.com", "compatibility@lists.mozilla.org"],
"description": "Number of shared workers destroyed; used in conjunction with use counter histograms"
},
"DEDICATED_WORKER_SPAWN_GETS_QUEUED": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec", "geckoview"],
@ -12551,6 +12571,16 @@
"kind": "count",
"description": "Tracking whether a DedicatedWorker spawn gets queued due to hitting max workers per domain limit. File bugs in Core::DOM in case of a Telemetry regression."
},
"DEDICATED_WORKER_DESTROYED": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec", "geckoview"],
"expires_in_version": "never",
"kind": "count",
"releaseChannelCollection": "opt-out",
"bug_numbers": [1202706],
"alert_emails": ["tdsmith@mozilla.com", "compatibility@lists.mozilla.org"],
"description": "Number of dedicated workers destroyed; used in conjunction with use counter histograms"
},
"SERVICE_WORKER_REGISTRATIONS": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec", "geckoview"],

Просмотреть файл

@ -40,6 +40,13 @@ footer = """
#endif // mozilla_TelemetryHistogramEnums_h"""
def get_histogram_typename(histogram):
name = histogram.name()
if name.startswith("USE_COUNTER2_"):
return "UseCounterWorker" if name.endswith("_WORKER") else "UseCounter"
return None
def main(output, *filenames):
# Print header.
print(banner, file=output)
@ -52,42 +59,46 @@ def main(output, *filenames):
print("\nError processing histograms:\n" + str(ex) + "\n")
sys.exit(1)
groups = itertools.groupby(all_histograms,
lambda h: h.name().startswith("USE_COUNTER2_"))
groups = itertools.groupby(all_histograms, get_histogram_typename)
# Print the histogram enums.
# Note that parse_histograms.py guarantees that all of the USE_COUNTER2_*
# histograms are defined in a contiguous block. We therefore assume
# that there's at most one group for which use_counter_group is true.
# Note that parse_histograms.py guarantees that all of the
# USE_COUNTER2_*_WORKER and USE_COUNTER2_* histograms are both defined in a
# contiguous block.
print("enum HistogramID : uint32_t {", file=output)
seen_use_counters = False
for (use_counter_group, histograms) in groups:
if use_counter_group:
seen_use_counters = True
# The HistogramDUMMY* enum variables are used to make the computation
# of Histogram{First,Last}UseCounter easier. Otherwise, we'd have to
# special case the first and last histogram in the group.
if use_counter_group:
print(" HistogramFirstUseCounter,", file=output)
print(" HistogramDUMMY1 = HistogramFirstUseCounter - 1,", file=output)
seen_group_types = {"UseCounter": False, "UseCounterWorker": False}
for (group_type, histograms) in groups:
if group_type is not None:
assert isinstance(group_type, basestring)
assert group_type in seen_group_types.keys()
assert not seen_group_types[group_type]
seen_group_types[group_type] = True
# The Histogram*DUMMY enum variables are used to make the computation
# of Histogram{First,Last}* easier. Otherwise, we'd have to special
# case the first and last histogram in the group.
print(" HistogramFirst%s," % group_type, file=output)
print(" Histogram{0}DUMMY1 = HistogramFirst{0} - 1,".format(group_type), file=output)
for histogram in histograms:
if histogram.record_on_os(buildconfig.substs["OS_TARGET"]):
print(" %s," % histogram.name(), file=output)
if use_counter_group:
print(" HistogramDUMMY2,", file=output)
print(" HistogramLastUseCounter = HistogramDUMMY2 - 1,", file=output)
if group_type is not None:
assert isinstance(group_type, basestring)
print(" Histogram%sDUMMY2," % group_type, file=output)
print(" HistogramLast{0} = Histogram{0}DUMMY2 - 1,".format(group_type), file=output)
print(" HistogramCount,", file=output)
if seen_use_counters:
print(" HistogramUseCounterCount = HistogramLastUseCounter -"
" HistogramFirstUseCounter + 1", file=output)
else:
print(" HistogramFirstUseCounter = 0,", file=output)
print(" HistogramLastUseCounter = 0,", file=output)
print(" HistogramUseCounterCount = 0", file=output)
for (key, value) in seen_group_types.items():
if value:
print(" Histogram{0}Count = HistogramLast{0} - HistogramFirst{0} + 1,"
.format(key), file=output)
else:
print(" HistogramFirst%s = 0," % key, file=output)
print(" HistogramLast%s = 0," % key, file=output)
print(" Histogram%sCount = 0," % key, file=output)
print("};", file=output)
# Write categorical label enums.

Просмотреть файл

@ -725,6 +725,10 @@ def from_UseCounters_conf(filename, strict_type_checks):
return usecounters.generate_histograms(filename)
def from_UseCountersWorker_conf(filename, strict_type_checks):
return usecounters.generate_histograms(filename, True)
def from_nsDeprecatedOperationList(filename, strict_type_checks):
operation_regex = re.compile('^DEPRECATED_OPERATION\\(([^)]+)\\)')
histograms = collections.OrderedDict()
@ -828,6 +832,8 @@ try:
import usecounters
FILENAME_PARSERS.append(lambda x: from_UseCounters_conf if x == 'UseCounters.conf' else None)
FILENAME_PARSERS.append(
lambda x: from_UseCountersWorker_conf if x == 'UseCountersWorker.conf' else None)
except ImportError:
pass
@ -864,17 +870,26 @@ the histograms defined in filenames.
ParserError('Duplicate histogram name "%s".' % name).handle_later()
all_histograms[name] = definition
# We require that all USE_COUNTER2_* histograms be defined in a contiguous
def check_continuity(iterable, filter_function, name):
indices = filter(filter_function, enumerate(iterable.iterkeys()))
if indices:
lower_bound = indices[0][0]
upper_bound = indices[-1][0]
n_counters = upper_bound - lower_bound + 1
if n_counters != len(indices):
ParserError("Histograms %s must be defined in a contiguous block." %
name).handle_later()
# We require that all USE_COUNTER2_*_WORKER histograms be defined in a contiguous
# block.
use_counter_indices = filter(lambda x: x[1].startswith("USE_COUNTER2_"),
enumerate(all_histograms.iterkeys()))
if use_counter_indices:
lower_bound = use_counter_indices[0][0]
upper_bound = use_counter_indices[-1][0]
n_counters = upper_bound - lower_bound + 1
if n_counters != len(use_counter_indices):
ParserError("Use counter histograms must be defined in a contiguous block."
).handle_later()
check_continuity(all_histograms,
lambda x: x[1].startswith("USE_COUNTER2_") and x[1].endswith("_WORKER"),
"use counter worker")
# And all other USE_COUNTER2_* histograms be defined in a contiguous
# block.
check_continuity(all_histograms,
lambda x: x[1].startswith("USE_COUNTER2_") and not x[1].endswith("_WORKER"),
"use counter")
# Check that histograms that were removed from Histograms.json etc.
# are also removed from the allowlists.

Просмотреть файл

@ -1188,6 +1188,7 @@
"D3D11_COMPOSITING_FAILURE_ID",
"D3D11_SYNC_HANDLE_FAILURE",
"DEDICATED_WORKER_SPAWN_GETS_QUEUED",
"DEDICATED_WORKER_DESTROYED",
"DEFECTIVE_PERMISSIONS_SQL_REMOVED",
"DENIED_TRANSLATION_OFFERS",
"DEVTOOLS_ABOUTDEBUGGING_OPENED_COUNT",
@ -1259,7 +1260,9 @@
"SERVICE_WORKER_SPAWN_GETS_QUEUED",
"SERVICE_WORKER_UPDATED",
"SERVICE_WORKER_WAS_SPAWNED",
"SERVICE_WORKER_DESTROYED",
"SHARED_WORKER_SPAWN_GETS_QUEUED",
"SHARED_WORKER_DESTROYED",
"SHOULD_AUTO_DETECT_LANGUAGE",
"SHOULD_TRANSLATION_UI_APPEAR",
"SLOW_SCRIPT_NOTICE_COUNT",

Просмотреть файл

@ -143,6 +143,7 @@ histogram_files = [
'/dom/base/nsDeprecatedOperationList.h',
'!/layout/style/ServoCSSPropList.py',
'/servo/components/style/properties/counted_unknown_properties.py',
'/dom/base/UseCountersWorker.conf',
]
if CONFIG['MOZ_TELEMETRY_EXTRA_HISTOGRAM_FILES']:
histogram_files.extend(CONFIG['MOZ_TELEMETRY_EXTRA_HISTOGRAM_FILES'])