forked from mirrors/gecko-dev
Bug 1852098 - mach command gen-use-counter-metrics r=emilio,firefox-build-system-reviewers,ahochheiden
Takes use counter definitions and generates a use_counter_metrics.yaml with `counter` metric definitions for each use counter and denominator. Total use counters at time of writing: 2271 (excludes denominators) Differential Revision: https://phabricator.services.mozilla.com/D193246
This commit is contained in:
parent
4129adf3e2
commit
efd2596fde
6 changed files with 36944 additions and 0 deletions
21
dom/base/mach_commands.py
Normal file
21
dom/base/mach_commands.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# 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/.
|
||||
|
||||
from mach.decorators import Command
|
||||
|
||||
|
||||
@Command(
|
||||
"gen-use-counter-metrics",
|
||||
category="misc",
|
||||
description="Generate a Glean use_counter_metrics.yaml file, creating metrics definitions for every use counter.",
|
||||
)
|
||||
def gen_use_counter_metrics(command_context):
|
||||
# Dispatch to usecounters.py
|
||||
import sys
|
||||
from os import path
|
||||
|
||||
sys.path.append(path.dirname(__file__))
|
||||
from usecounters import gen_use_counter_metrics
|
||||
|
||||
return gen_use_counter_metrics()
|
||||
36456
dom/base/use_counter_metrics.yaml
Normal file
36456
dom/base/use_counter_metrics.yaml
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -87,3 +87,448 @@ def generate_histograms(filename, is_for_worker=False):
|
|||
append_counters(counter["name"].upper(), counter["desc"])
|
||||
|
||||
return items
|
||||
|
||||
|
||||
YAML_HEADER = """\
|
||||
# This file is AUTOGENERATED by usecounters.py. DO NOT EDIT.
|
||||
# (instead, re-run ./mach gen-use-counter-metrics)
|
||||
|
||||
# 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/.
|
||||
|
||||
---
|
||||
$schema: moz://mozilla.org/schemas/glean/metrics/2-0-0
|
||||
$tags:
|
||||
- 'Core :: DOM: Core & HTML'
|
||||
|
||||
"""
|
||||
|
||||
# TODO: What are good notification emails?
|
||||
# TODO: What's good info to include in these descriptions?
|
||||
DENOMINATOR_METRICS = """\
|
||||
use.counter:
|
||||
content_documents_destroyed:
|
||||
type: counter
|
||||
description: >
|
||||
A count of how many content documents were destroyed.
|
||||
Used to turn document use counters' counts into rates.
|
||||
Excludes documents for which we do not count use counters
|
||||
(See `Document::ShouldIncludeInTelemetry`).
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1204994
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1569672
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1845779
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1569672
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
top_level_content_documents_destroyed:
|
||||
type: counter
|
||||
description: >
|
||||
A count of how many "pages" were destroyed.
|
||||
Used to turn page use counters' counts into rates.
|
||||
Excludes pages that contain only documents for which we do not count use
|
||||
counters (See `Document::ShouldIncludeInTelemetry`).
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1204994
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1569672
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1845779
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1569672
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
dedicated_workers_destroyed:
|
||||
type: counter
|
||||
description: >
|
||||
A count of how many `Dedicated`-kind workers were destroyed.
|
||||
Used to turn dedicated worker use counters' counts into rates.
|
||||
Excludes chrome workers.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
shared_workers_destroyed:
|
||||
type: counter
|
||||
description: >
|
||||
A count of how many `Shared`-kind workers were destroyed.
|
||||
Used to turn shared worker use counters' counts into rates.
|
||||
Excludes chrome workers.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
service_workers_destroyed:
|
||||
type: counter
|
||||
description: >
|
||||
A count of how many `Service`-kind workers were destroyed.
|
||||
Used to turn service worker use counters' counts into rates.
|
||||
Excludes chrome workers.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1202706
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
"""
|
||||
|
||||
USE_COUNTER_TEMPLATE = """\
|
||||
{name}:
|
||||
type: counter
|
||||
description: >
|
||||
{desc}
|
||||
Compare against `{denominator}`
|
||||
to calculate the rate.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
expires: never
|
||||
send_in_pings:
|
||||
- use-counters
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def gen_use_counter_metrics():
|
||||
"""
|
||||
Finds use counters in:
|
||||
* dom/base/UseCounters.conf
|
||||
* dom/base/UseCountersWorker.conf
|
||||
* dom/base/nsDeprecatedOperationsList.h
|
||||
* !/layout/style/ServoCSSPropList.py
|
||||
* servo/components/style/properties/counted_unknown_properties.py
|
||||
and overwrites the Glean metrics definition file
|
||||
`dom/base/use_counter_metrics.yaml` with definitions for each use counter found.
|
||||
|
||||
IF YOU CHANGE THIS FUNCTION:
|
||||
* You should probably add your bug's number to USE_COUNTER_TEMPLATE, above.
|
||||
|
||||
Returns 0 on success.
|
||||
"""
|
||||
|
||||
# There are 3 kinds of Use Counters in conf files: method, attribute, custom.
|
||||
# `method` and `attribute` are presumed label-safe and are taken as-is.
|
||||
# `custom` can be any case, so are coerced to snake_case.
|
||||
import os
|
||||
|
||||
import buildconfig
|
||||
|
||||
uc_path = os.path.join(buildconfig.topsrcdir, "dom", "base", "UseCounters.conf")
|
||||
page = []
|
||||
doc = []
|
||||
for counter in read_conf(uc_path):
|
||||
if counter["type"] == "method":
|
||||
name = f"{counter['interface_name']}_{counter['method_name']}".lower()
|
||||
method = f"called {counter['interface_name']}.{counter['method_name']}"
|
||||
page.append((name, f"Whether a page called {method}."))
|
||||
doc.append((name, f"Whether a document called {method}."))
|
||||
elif counter["type"] == "attribute":
|
||||
name = f"{counter['interface_name']}_{counter['attribute_name']}".lower()
|
||||
attr = f"{counter['interface_name']}.{counter['attribute_name']}"
|
||||
page.append((f"{name}_getter", f"Whether a page got {attr}."))
|
||||
page.append((f"{name}_setter", f"Whether a page set {attr}."))
|
||||
doc.append((f"{name}_getter", f"Whether a document got {attr}."))
|
||||
doc.append((f"{name}_setter", f"Whether a document set {attr}."))
|
||||
elif counter["type"] == "custom":
|
||||
page.append(
|
||||
(to_snake_case(counter["name"]), f"Whether a page {counter['desc']}.")
|
||||
)
|
||||
doc.append(
|
||||
(
|
||||
to_snake_case(counter["name"]),
|
||||
f"Whether a document {counter['desc']}.",
|
||||
)
|
||||
)
|
||||
else:
|
||||
print(f"Found unexpected use counter type {counter['type']}. Returning 1.")
|
||||
return 1
|
||||
|
||||
worker_uc_path = os.path.join(
|
||||
buildconfig.topsrcdir, "dom", "base", "UseCountersWorker.conf"
|
||||
)
|
||||
dedicated = []
|
||||
shared = []
|
||||
service = []
|
||||
for counter in read_conf(worker_uc_path):
|
||||
if counter["type"] == "method":
|
||||
name = f"{counter['interface_name']}_{counter['method_name']}".lower()
|
||||
method = f"called {counter['interface_name']}.{counter['method_name']}"
|
||||
dedicated.append((name, f"Whether a dedicated worker called {method}."))
|
||||
shared.append((name, f"Whether a shared worker called {method}."))
|
||||
service.append((name, f"Whether a service worker called {method}."))
|
||||
elif counter["type"] == "attribute":
|
||||
name = f"{counter['interface_name']}_{counter['attribute_name']}".lower()
|
||||
attr = f"{counter['interface_name']}.{counter['attribute_name']}"
|
||||
dedicated.append((name, f"Whether a dedicated worker got {attr}."))
|
||||
dedicated.append((name, f"Whether a dedicated worker set {attr}."))
|
||||
shared.append((name, f"Whether a shared worker got {attr}."))
|
||||
shared.append((name, f"Whether a shared worker set {attr}."))
|
||||
service.append((name, f"Whether a service worker got {attr}."))
|
||||
service.append((name, f"Whether a service worker set {attr}."))
|
||||
elif counter["type"] == "custom":
|
||||
dedicated.append(
|
||||
(
|
||||
to_snake_case(counter["name"]),
|
||||
f"Whether a dedicated worker {counter['desc']}.",
|
||||
)
|
||||
)
|
||||
shared.append(
|
||||
(
|
||||
to_snake_case(counter["name"]),
|
||||
f"Whether a shared worker {counter['desc']}.",
|
||||
)
|
||||
)
|
||||
service.append(
|
||||
(
|
||||
to_snake_case(counter["name"]),
|
||||
f"Whether a service worker {counter['desc']}.",
|
||||
)
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"Found unexpected worker use counter type {counter['type']}. Returning 1."
|
||||
)
|
||||
return 1
|
||||
|
||||
# nsDeprecatedOperationsList.h parsing is adapted from parse_histograms.py.
|
||||
operation_list_path = os.path.join(
|
||||
buildconfig.topsrcdir, "dom", "base", "nsDeprecatedOperationList.h"
|
||||
)
|
||||
operation_regex = re.compile("^DEPRECATED_OPERATION\\(([^)]+)\\)")
|
||||
ops_page = []
|
||||
ops_doc = []
|
||||
with open(operation_list_path) as f:
|
||||
for line in f:
|
||||
match = operation_regex.search(line)
|
||||
if not match:
|
||||
# No macro, probably whitespace or comment.
|
||||
continue
|
||||
|
||||
op = match.group(1)
|
||||
op_name = to_snake_case(op)
|
||||
ops_page.append((op_name, f"Whether a page used {op}."))
|
||||
ops_doc.append((op_name, f"Whether a document used {op}."))
|
||||
|
||||
# TODO: Theoretically, we could do this without a completed build
|
||||
# (ie, without the generated ServoCSSPropList.py) by sourcing direct from
|
||||
# servo/components/style/properties/data.py:PropertiesData(engine=gecko).
|
||||
#
|
||||
# ...but parse_histograms.py doesn't do this the hard way. Should we?
|
||||
|
||||
import runpy
|
||||
|
||||
proplist_path = os.path.join(
|
||||
buildconfig.topobjdir, "layout", "style", "ServoCSSPropList.py"
|
||||
)
|
||||
css_properties = runpy.run_path(proplist_path)["data"]
|
||||
css_page = []
|
||||
css_doc = []
|
||||
for prop in css_properties.values():
|
||||
# We prefix `prop_name` with `css_` to avoid colliding with C++ keywords
|
||||
# like `float`.
|
||||
prop_name = "css_" + to_snake_case(prop.name)
|
||||
css_page.append(
|
||||
(prop_name, f"Whether a page used the CSS property {prop.name}.")
|
||||
)
|
||||
css_doc.append(
|
||||
(prop_name, f"Whether a document used the CSS property {prop.name}.")
|
||||
)
|
||||
|
||||
# Counted unknown properties: AKA - stuff that doesn't exist, but we want
|
||||
# to count uses of anyway.
|
||||
# We _might_ decide to implement these in the future, though, so we just add
|
||||
# them to the css_page, css_doc lists directly for continuity.
|
||||
# (We do give them a different description, though)
|
||||
|
||||
unknown_proplist_path = os.path.join(
|
||||
buildconfig.topsrcdir,
|
||||
"servo",
|
||||
"components",
|
||||
"style",
|
||||
"properties",
|
||||
"counted_unknown_properties.py",
|
||||
)
|
||||
unknown_properties = runpy.run_path(unknown_proplist_path)[
|
||||
"COUNTED_UNKNOWN_PROPERTIES"
|
||||
]
|
||||
for prop in unknown_properties:
|
||||
prop_name = to_snake_case(prop)
|
||||
css_page.append(
|
||||
(
|
||||
prop_name,
|
||||
f"Whether a page used the (unknown, counted) CSS property {prop}.",
|
||||
)
|
||||
)
|
||||
css_doc.append(
|
||||
(
|
||||
prop_name,
|
||||
f"Whether a document used the (unknown, counted) CSS property {prop}.",
|
||||
)
|
||||
)
|
||||
|
||||
from mozbuild.util import FileAvoidWrite
|
||||
|
||||
# TODO: Up for discussion: organization.
|
||||
# Especially e.g. use.counter.css.page.css_float, but also: perhaps suffixes are preferred over categories?
|
||||
yaml_path = os.path.join(
|
||||
buildconfig.topsrcdir, "dom", "base", "use_counter_metrics.yaml"
|
||||
)
|
||||
with FileAvoidWrite(yaml_path) as f:
|
||||
f.write(YAML_HEADER)
|
||||
f.write(DENOMINATOR_METRICS)
|
||||
|
||||
total = (
|
||||
len(page)
|
||||
+ len(doc)
|
||||
+ len(dedicated)
|
||||
+ len(shared)
|
||||
+ len(service)
|
||||
+ len(ops_page)
|
||||
+ len(ops_doc)
|
||||
+ len(css_page)
|
||||
+ len(css_doc)
|
||||
)
|
||||
f.write(f"# Total of {total} use counter metrics (excludes denominators).\n")
|
||||
f.write(f"# Total of {len(page)} 'page' use counters.\n")
|
||||
f.write("use.counter.page:\n")
|
||||
for uc in page:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=uc[0],
|
||||
desc=uc[1],
|
||||
denominator="use.counter.top_level_content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(doc)} 'document' use counters.\n")
|
||||
f.write("use.counter.doc:\n")
|
||||
for uc in doc:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=uc[0],
|
||||
desc=uc[1],
|
||||
denominator="use.counter.content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(dedicated)} 'dedicated worker' use counters.\n")
|
||||
f.write("use.counter.worker.dedicated:\n")
|
||||
for uc in dedicated:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=uc[0],
|
||||
desc=uc[1],
|
||||
denominator="use.counter.dedicated_workers_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(shared)} 'shared worker' use counters.\n")
|
||||
f.write("use.counter.worker.shared:\n")
|
||||
for uc in shared:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=uc[0],
|
||||
desc=uc[1],
|
||||
denominator="use.counter.shared_workers_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(service)} 'service worker' use counters.\n")
|
||||
f.write("use.counter.worker.service:\n")
|
||||
for uc in service:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=uc[0],
|
||||
desc=uc[1],
|
||||
denominator="use.counter.service_workers_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(
|
||||
f"# Total of {len(ops_page)} 'deprecated operations (page)' use counters.\n"
|
||||
)
|
||||
f.write("use.counter.deprecated_ops.page:\n")
|
||||
for uc in ops_page:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=uc[0],
|
||||
desc=uc[1],
|
||||
denominator="use.counter.top_level_content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(
|
||||
f"# Total of {len(ops_doc)} 'deprecated operations (document)' use counters.\n"
|
||||
)
|
||||
f.write("use.counter.deprecated_ops.doc:\n")
|
||||
for uc in ops_doc:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=uc[0],
|
||||
desc=uc[1],
|
||||
denominator="use.counter.content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(css_page)} 'CSS (page)' use counters.\n")
|
||||
f.write("use.counter.css.page:\n")
|
||||
for uc in css_page:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=uc[0],
|
||||
desc=uc[1],
|
||||
denominator="use.counter.top_level_content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
f.write(f"# Total of {len(css_doc)} 'CSS (document)' use counters.\n")
|
||||
f.write("use.counter.css.doc:\n")
|
||||
for uc in css_doc:
|
||||
f.write(
|
||||
USE_COUNTER_TEMPLATE.format(
|
||||
name=uc[0],
|
||||
desc=uc[1],
|
||||
denominator="use.counter.content_documents_destroyed",
|
||||
)
|
||||
)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def to_snake_case(kebab_or_pascal):
|
||||
"""
|
||||
Takes `kebab_or_pascal` which is in PascalCase or kebab-case
|
||||
and conjugates it to "snake_case" (all lowercase, "_"-delimited).
|
||||
"""
|
||||
return (
|
||||
re.sub("([A-Z]+)", r"_\1", kebab_or_pascal).replace("-", "_").lower().strip("_")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -23,3 +23,23 @@ pageload:
|
|||
notification_emails:
|
||||
- perf-telemetry-alerts@mozilla.com
|
||||
- dpalmeiro@mozilla.com
|
||||
|
||||
use-counters:
|
||||
description: |
|
||||
Collects counts of uses of web platform features.
|
||||
See [Use Counters Documentation](https://firefox-source-docs.mozilla.org/dom/use-counters.html)
|
||||
for more information.
|
||||
reasons:
|
||||
app_shutdown_confirmed: |
|
||||
Submitted when we reach `ShutdownPhase::AppShutdownConfirmed`.
|
||||
(Any later and the network might have been torn down.)
|
||||
include_client_id: true
|
||||
send_if_empty: false
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1852098
|
||||
notification_emails:
|
||||
- dom-core@mozilla.com
|
||||
- chutten@mozilla.com
|
||||
- emilio@mozilla.com
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ MACH_COMMANDS = {
|
|||
"geckoview-junit": MachCommandReference(
|
||||
"testing/mochitest/mach_commands.py", ["test"]
|
||||
),
|
||||
"gen-use-counter-metrics": MachCommandReference("dom/base/mach_commands.py"),
|
||||
"generate-test-certs": MachCommandReference(
|
||||
"security/manager/tools/mach_commands.py"
|
||||
),
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
# Order is lexicographical, enforced by t/c/glean/tests/pytest/test_yaml_indices.py
|
||||
gecko_metrics = [
|
||||
"browser/base/content/metrics.yaml",
|
||||
"dom/base/use_counter_metrics.yaml",
|
||||
"dom/media/metrics.yaml",
|
||||
"dom/media/webrtc/metrics.yaml",
|
||||
"dom/metrics.yaml",
|
||||
|
|
|
|||
Loading…
Reference in a new issue