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)