tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

glean_utils.py (3672B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 import enum
      6 import json
      7 import sys
      8 from os import path
      9 
     10 ROOT_PATH = path.abspath(
     11    path.join(
     12        path.dirname(__file__),
     13        path.pardir,
     14        path.pardir,
     15        path.pardir,
     16        path.pardir,
     17        path.pardir,
     18    )
     19 )
     20 
     21 # The jog module dependency is in a different folder, so we add it to our path.
     22 GLEAN_BUILD_SCRIPTS_PATH = path.join(
     23    ROOT_PATH, "toolkit", "components", "glean", "build_scripts", "glean_parser_ext"
     24 )
     25 sys.path.append(GLEAN_BUILD_SCRIPTS_PATH)
     26 
     27 import jog
     28 from glean_parser.metrics import Rate
     29 
     30 
     31 def output_file_with_key(objs, output_fd, options={}):
     32    """
     33    Given a tree of objects, output them to the file-like object `output_fd`
     34    in a format similar to runtime-metrics-sample.json.
     35 
     36    :param objs: A tree of objects (metrics and pings) as returned from
     37                 `parser.parse_objects`.
     38    :param output_fd: Writeable file to write the output to.
     39    :param options: options dictionary, presently unused.
     40    """
     41    jog.ensure_jog_support_for_args()
     42 
     43    # Initialize the output structure
     44    output_data = {"metrics": {}, "pings": {}}
     45 
     46    # Process pings
     47    if "pings" in objs:
     48        pings = objs["pings"]
     49        for ping_name, ping in pings.items():
     50            ping_data = {}
     51            for arg in jog.known_ping_args:
     52                if hasattr(ping, arg):
     53                    key = arg
     54                    value = getattr(ping, arg)
     55                    ping_data[key] = value
     56            output_data["pings"][ping_name] = ping_data
     57 
     58    def encode(value):
     59        if isinstance(value, enum.Enum):
     60            return value.name
     61        if isinstance(value, Rate):  # `numerators` for an external Denominator metric
     62            args = []
     63            for arg_name in jog.common_metric_data_args[:-1]:
     64                args.append(getattr(value, arg_name))
     65            args.append(None)
     66            return args
     67        return json.dumps(value)
     68 
     69    # Process metrics
     70    for category, metrics in objs.items():
     71        if category in ["pings", "tags"]:
     72            continue
     73 
     74        output_data["metrics"][category] = {}
     75        for metric_name, metric in metrics.items():
     76            metric_data = {
     77                "type": metric.typename,
     78                "description": getattr(metric, "description", ""),
     79                "lifetime": getattr(metric, "lifetime", "ping").name.lower(),
     80                "pings": getattr(metric, "send_in_pings", []),
     81                "disabled": getattr(metric, "disabled", False),
     82            }
     83 
     84            # Add extra arguments if they exist
     85            extra_args = {}
     86            for arg in jog.known_extra_args:
     87                if hasattr(metric, arg):
     88                    if arg == "extra_keys":
     89                        # For extra_keys, just list the key names and rename to allowed_extra_keys
     90                        extra_args["allowed_extra_keys"] = list(
     91                            getattr(metric, arg).keys()
     92                        )
     93                    else:
     94                        extra_args[arg] = getattr(metric, arg)
     95 
     96            # Add metadata if it exists
     97            for meta in jog.known_metadata:
     98                if meta in metric.metadata:
     99                    extra_args[meta] = metric.metadata.get(meta)
    100 
    101            if extra_args:
    102                metric_data["extraArgs"] = extra_args
    103 
    104            output_data["metrics"][category][metric_name] = metric_data
    105 
    106    json.dump(output_data, output_fd, sort_keys=True, default=encode, indent=2)