Bug 1222549 - Add build-metrics submission to perfherder. r=wlach,jlund draft
authorChris Manchester <cmanchester@mozilla.com>
Thu, 12 Nov 2015 13:20:14 -0800
changeset 308521 68f359f7832cf0710463ac95d609f750552c41b3
parent 308473 3cc3b1968524248450c465c4ea2ee5596ffa65f2
child 511177 9d3d5be05144e2bca9e57641c36e86b606b6a5c9
push id7487
push usercmanchester@mozilla.com
push dateThu, 12 Nov 2015 21:20:45 +0000
reviewerswlach, jlund
bugs1222549
milestone45.0a1
Bug 1222549 - Add build-metrics submission to perfherder. r=wlach,jlund This adds "basic" build time metrics to data already submitted to perfherder from mozharness: the overall build time, and the duration of each build step as a subtest.
testing/mozharness/mozharness/base/python.py
testing/mozharness/mozharness/mozilla/building/buildbase.py
--- a/testing/mozharness/mozharness/base/python.py
+++ b/testing/mozharness/mozharness/base/python.py
@@ -576,16 +576,17 @@ class InfluxRecordingMixin(object):
     mozharness are recorded in the 'mozharness' table.
     """
 
     @PreScriptRun
     def influxdb_recording_init(self):
         self.recording = False
         self.post = None
         self.posturl = None
+        self.build_metrics_summary = None
         self.res_props = self.config.get('build_resources_path') % self.query_abs_dirs()
         self.info("build_resources.json path: %s" % self.res_props)
         if self.res_props:
             self.rmtree(self.res_props)
 
         try:
             site_packages_path = self.query_python_site_packages_path()
             if site_packages_path not in sys.path:
@@ -722,31 +723,46 @@ class InfluxRecordingMixin(object):
                     # Mach step properties
                     "name",
                     "start",
                     "end",
                     "duration",
                     "cpu_percent",
                 ],
             }
+
             # The io and cpu_times fields aren't static - they may vary based
             # on the specific platform being measured. Mach records the field
             # names, which we use as the column names here.
             data['columns'].extend(resources['io_fields'])
             data['columns'].extend(resources['cpu_times_fields'])
             iolen = len(resources['io_fields'])
             cpulen = len(resources['cpu_times_fields'])
 
+            if 'duration' in resources:
+                self.build_metrics_summary = {
+                    'name': 'build times',
+                    'value': resources['duration'],
+                    'subtests': [],
+                }
+
             # The top-level data has the overall resource usage, which we record
             # under the name 'TOTAL' to separate it from the individual tiers.
             data['points'].append(self._get_resource_usage(resources, 'TOTAL', iolen, cpulen))
 
             # Each tier also has the same resource stats as the top-level.
             for tier in resources['tiers']:
                 data['points'].append(self._get_resource_usage(tier, tier['name'], iolen, cpulen))
+                if 'duration' not in tier:
+                    self.build_metrics_summary = None
+                elif self.build_metrics_summary:
+                    self.build_metrics_summary['subtests'].append({
+                        'name': tier['name'],
+                        'value': tier.get('duration'),
+                    })
 
             self.record_influx_stat([data])
 
     def record_influx_stat(self, json_data):
         try:
             r = self.post(self.posturl, data=json.dumps(json_data), timeout=5)
             if r.status_code != 200:
                 self.warning("Failed to log stats. Return code = %i, stats = %s" % (r.status_code, json_data))
--- a/testing/mozharness/mozharness/mozilla/building/buildbase.py
+++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py
@@ -1638,23 +1638,35 @@ or run without that action (ie: --no-{ac
                     name, filesize))
                 if any(name.endswith(extension) for extension in ['apk',
                                                                   'dmg',
                                                                   'bz2',
                                                                   'zip']):
                     installer_size = filesize
                 else:
                     size_measurements.append({'name': name, 'value': filesize})
+
+        perfherder_data = {
+            "framework": {
+                "name": "build_metrics"
+            },
+            "suites": [],
+        }
         if installer_size or size_measurements:
-            self.info('PERFHERDER_DATA: %s' % (json.dumps({
-                "framework": {"name": "build_metrics"},
-                "suites": [{"name": "installer size",
-                            "value": installer_size,
-                            "subtests": size_measurements}]
-            })))
+            perfherder_data["suites"].append({
+                "name": "installer size",
+                "value": installer_size,
+                "subtests": size_measurements
+            })
+        if (hasattr(self, "build_metrics_summary") and
+            self.build_metrics_summary):
+            perfherder_data["suites"].append(self.build_metrics_summary)
+
+        if perfherder_data["suites"]:
+            self.info('PERFHERDER_DATA: %s' % json.dumps(perfherder_data))
 
     def _set_file_properties(self, file_name, find_dir, prop_type,
                              error_level=ERROR):
         c = self.config
         dirs = self.query_abs_dirs()
 
         # windows fix. even bash -c loses two single slashes.
         find_dir = find_dir.replace('\\', '\\\\\\\\')