forked from mirrors/gecko-dev
Bug 1888703 - add a mach command to create a legacy event definition from a glean one r=chutten
Differential Revision: https://phabricator.services.mozilla.com/D206281
This commit is contained in:
parent
bd0eb2d02a
commit
5c3cf2d4f7
3 changed files with 224 additions and 0 deletions
|
|
@ -92,6 +92,9 @@ MACH_COMMANDS = {
|
|||
"environment": MachCommandReference("python/mozbuild/mozbuild/mach_commands.py"),
|
||||
"eslint": MachCommandReference("tools/lint/mach_commands.py"),
|
||||
"esmify": MachCommandReference("tools/esmify/mach_commands.py"),
|
||||
"event-into-legacy": MachCommandReference(
|
||||
"toolkit/components/glean/build_scripts/mach_commands.py"
|
||||
),
|
||||
"fetch-condprofile": MachCommandReference("testing/condprofile/mach_commands.py"),
|
||||
"file-info": MachCommandReference(
|
||||
"python/mozbuild/mozbuild/frontend/mach_commands.py"
|
||||
|
|
|
|||
|
|
@ -235,3 +235,47 @@ def update_glean(command_context, version):
|
|||
"""
|
||||
|
||||
print(textwrap.dedent(instructions))
|
||||
|
||||
|
||||
@Command(
|
||||
"event-into-legacy",
|
||||
category="misc",
|
||||
description="Create a Legacy Telemetry compatible event definition from an existing Glean Event metric.",
|
||||
)
|
||||
@CommandArgument(
|
||||
"--append",
|
||||
"-a",
|
||||
action="store_true",
|
||||
help="Append to toolkit/components/telemetry/Events.yaml (note: verify and make any necessary modifications before landing).",
|
||||
)
|
||||
@CommandArgument("event", default=None, nargs="?", type=str, help="Event name.")
|
||||
def event_into_legacy(command_context, event=None, append=False):
|
||||
# Get the metrics_index's list of metrics indices
|
||||
# by loading the index as a module.
|
||||
import sys
|
||||
from os import path
|
||||
|
||||
sys.path.append(path.join(path.dirname(__file__), path.pardir))
|
||||
|
||||
from metrics_index import metrics_yamls
|
||||
|
||||
sys.path.append(path.dirname(__file__))
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from translate_events import translate_event
|
||||
|
||||
legacy_yaml_path = path.join(
|
||||
Path(command_context.topsrcdir),
|
||||
"toolkit",
|
||||
"components",
|
||||
"telemetry",
|
||||
"Events.yaml",
|
||||
)
|
||||
|
||||
return translate_event(
|
||||
event,
|
||||
append,
|
||||
[Path(command_context.topsrcdir) / x for x in metrics_yamls],
|
||||
legacy_yaml_path,
|
||||
)
|
||||
|
|
|
|||
177
toolkit/components/glean/build_scripts/translate_events.py
Normal file
177
toolkit/components/glean/build_scripts/translate_events.py
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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/.
|
||||
|
||||
"""
|
||||
Create a Legacy Telemetry event definition for the provided, named Glean event metric.
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
from os import path
|
||||
from pathlib import Path
|
||||
from typing import Sequence
|
||||
|
||||
import yaml
|
||||
from glean_parser import parser, util
|
||||
|
||||
TC_ROOT_PATH = path.abspath(path.join(path.dirname(__file__), path.pardir, path.pardir))
|
||||
sys.path.append(TC_ROOT_PATH)
|
||||
# The parsers live in a subdirectory of "build_scripts", account for that.
|
||||
# NOTE: if the parsers are moved, this logic will need to be updated.
|
||||
sys.path.append(path.join(TC_ROOT_PATH, "telemetry", "build_scripts"))
|
||||
|
||||
from mozparsers.parse_events import convert_to_cpp_identifier # noqa: E402
|
||||
|
||||
bug_number_pattern = re.compile(r"\d+")
|
||||
|
||||
|
||||
class IndentingDumper(yaml.Dumper):
|
||||
def increase_indent(self, flow=False, indentless=False):
|
||||
return super(IndentingDumper, self).increase_indent(flow, False)
|
||||
|
||||
|
||||
def get_bug_number_from_url(url: str) -> int:
|
||||
bug = bug_number_pattern.search(url)
|
||||
# Python lacks a safe cast, so we will return 1 if we fail to bubble up.
|
||||
if bug is not None:
|
||||
try:
|
||||
bug = int(bug[0])
|
||||
except TypeError:
|
||||
print(f"Failed to parse {bug[0]} to an integer")
|
||||
return 1
|
||||
return bug
|
||||
print(f"Failed to find a valid bug in the url {url}")
|
||||
return 1
|
||||
|
||||
|
||||
def create_legacy_mirror_def(category_name: str, metric_name: str, event_objects: list):
|
||||
event_cpp_enum = convert_to_cpp_identifier(category_name, "_") + "_"
|
||||
event_cpp_enum += convert_to_cpp_identifier(metric_name, ".") + "_"
|
||||
event_cpp_enum += convert_to_cpp_identifier(event_objects[0], ".")
|
||||
|
||||
print(
|
||||
f"""The Glean event {category_name}.{metric_name} has generated the {event_cpp_enum} Legacy Telemetry event. To link Glean to Legacy, please include in {category_name}.{metric_name}'s definition the following property:
|
||||
telemetry_mirror: {event_cpp_enum}
|
||||
See https://firefox-source-docs.mozilla.org/toolkit/components/glean/user/gifft.html#the-telemetry-mirror-property-in-metrics-yaml
|
||||
for more information.
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def translate_event(
|
||||
event_category_and_name: str,
|
||||
append: bool,
|
||||
metrics_files: Sequence[Path],
|
||||
legacy_yaml_file: Path,
|
||||
) -> int:
|
||||
"""
|
||||
Commandline helper for translating Glean events to Legacy.
|
||||
|
||||
:param event_name: the event to look for
|
||||
:param metrics_files: List of Path objects to load metrics from.
|
||||
:return: Non-zero if there were any errors.
|
||||
"""
|
||||
|
||||
# Event objects are a Legacy Telemetry event field that is rarely used. We
|
||||
# always broadcast into a single pre-defined object.
|
||||
event_objects = ["events"]
|
||||
|
||||
if event_category_and_name is not None:
|
||||
*event_category, event_name = event_category_and_name.rsplit(".", maxsplit=1)
|
||||
else:
|
||||
print("Please provide an event (in category.metricName format) to translate.")
|
||||
return 1
|
||||
|
||||
if len(event_category) > 0:
|
||||
event_category = util.snake_case(event_category[0])
|
||||
event_name = util.snake_case(event_name)
|
||||
else:
|
||||
print(
|
||||
f"Your event '{event_category_and_name}' did not conform to the a.category.a_metric_name format."
|
||||
)
|
||||
return 1
|
||||
|
||||
metrics_files = util.ensure_list(metrics_files)
|
||||
|
||||
# Accept any value of expires.
|
||||
parser_options = {
|
||||
"allow_reserved": True,
|
||||
"custom_is_expired": lambda expires: False,
|
||||
"custom_validate_expires": lambda expires: True,
|
||||
}
|
||||
all_objects = parser.parse_objects(metrics_files, parser_options)
|
||||
|
||||
if util.report_validation_errors(all_objects):
|
||||
return 1
|
||||
|
||||
for category_name, metrics in all_objects.value.items():
|
||||
for metric in metrics.values():
|
||||
metric_name = util.snake_case(metric.name)
|
||||
category_name = util.snake_case(category_name)
|
||||
|
||||
if metric_name != event_name or category_name != event_category:
|
||||
continue
|
||||
|
||||
if metric.type != "event":
|
||||
print(
|
||||
f"Metric {event_category_and_name} was found, but was a {metric.type} metric, not an event metric."
|
||||
)
|
||||
return 1
|
||||
|
||||
bugs_list = [get_bug_number_from_url(m) for m in metric.bugs]
|
||||
# Bail out if there was a parse error (error printed in get_bug_number_from_url)
|
||||
if 1 in bugs_list:
|
||||
return 1
|
||||
|
||||
metric_dict = {
|
||||
"objects": event_objects,
|
||||
"description": str(metric.description).strip(),
|
||||
"bug_numbers": bugs_list,
|
||||
"notification_emails": metric.notification_emails,
|
||||
"expiry_version": str(metric.expires),
|
||||
"products": ["firefox"],
|
||||
"record_in_processes": ["all"],
|
||||
}
|
||||
|
||||
if len(metric.extra_keys.items()) > 0:
|
||||
# Convert extra keys into a nested dictionary that YAML can understand
|
||||
extra_keys = {}
|
||||
for extra_key_pair in metric.extra_keys.items():
|
||||
description = (
|
||||
extra_key_pair[1]["description"].replace("\n", " ").strip()
|
||||
)
|
||||
extra_keys[extra_key_pair[0]] = description
|
||||
|
||||
metric_dict["extra_keys"] = extra_keys
|
||||
|
||||
metric_dict = {metric_name: metric_dict}
|
||||
metric_dict = {category_name: metric_dict}
|
||||
|
||||
metric_yaml = yaml.dump(
|
||||
metric_dict,
|
||||
default_flow_style=False,
|
||||
width=78,
|
||||
indent=2,
|
||||
Dumper=IndentingDumper,
|
||||
)
|
||||
|
||||
if append:
|
||||
with open(legacy_yaml_file, "a") as file:
|
||||
print("", file=file)
|
||||
print(metric_yaml, file=file)
|
||||
print(
|
||||
f"Apended {event_category_and_name} to the Legacy Events.yaml file. Please confirm the details by opening"
|
||||
)
|
||||
print(legacy_yaml_file)
|
||||
print("and checking that all fields are correct.")
|
||||
|
||||
create_legacy_mirror_def(event_name, category_name, event_objects)
|
||||
return 0
|
||||
|
||||
print(metric_yaml)
|
||||
create_legacy_mirror_def(event_name, category_name, event_objects)
|
||||
|
||||
return 0
|
||||
Loading…
Reference in a new issue