aboutsummaryrefslogtreecommitdiff
path: root/pgo_tools/monitor_pgo_profiles.py
diff options
context:
space:
mode:
Diffstat (limited to 'pgo_tools/monitor_pgo_profiles.py')
-rwxr-xr-xpgo_tools/monitor_pgo_profiles.py173
1 files changed, 90 insertions, 83 deletions
diff --git a/pgo_tools/monitor_pgo_profiles.py b/pgo_tools/monitor_pgo_profiles.py
index 5c17423b..2c54ee80 100755
--- a/pgo_tools/monitor_pgo_profiles.py
+++ b/pgo_tools/monitor_pgo_profiles.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
+# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -12,105 +12,112 @@ import subprocess
import sys
from typing import List, NamedTuple, Optional, Tuple
-PGO_BUILDBOT_LINK = ('https://ci.chromium.org/p/chromeos/builders/toolchain/'
- 'pgo-generate-llvm-next-orchestrator')
+
+PGO_BUILDBOT_LINK = (
+ "https://ci.chromium.org/p/chromeos/builders/toolchain/"
+ "pgo-generate-llvm-next-orchestrator"
+)
class ProfdataInfo(NamedTuple):
- """Data about an llvm profdata in our gs:// bucket."""
- date: datetime.datetime
- location: str
+ """Data about an llvm profdata in our gs:// bucket."""
+
+ date: datetime.datetime
+ location: str
def parse_date(date: str) -> datetime.datetime:
- time_format = '%Y-%m-%dT%H:%M:%SZ'
- if not date.endswith('Z'):
- time_format += '%z'
- return datetime.datetime.strptime(date, time_format)
+ time_format = "%Y-%m-%dT%H:%M:%SZ"
+ if not date.endswith("Z"):
+ time_format += "%z"
+ return datetime.datetime.strptime(date, time_format)
def fetch_most_recent_profdata(arch: str) -> ProfdataInfo:
- result = subprocess.run(
- [
- 'gsutil.py',
- 'ls',
- '-l',
- f'gs://chromeos-toolchain-artifacts/llvm-pgo/{arch}/'
- '*.profdata.tar.xz',
- ],
- check=True,
- stdout=subprocess.PIPE,
- encoding='utf-8',
- )
-
- # Each line will be a profdata; the last one is a summary, so drop it.
- infos = []
- for rec in result.stdout.strip().splitlines()[:-1]:
- _size, date, url = rec.strip().split()
- infos.append(ProfdataInfo(date=parse_date(date), location=url))
- return max(infos)
+ result = subprocess.run(
+ [
+ "gsutil.py",
+ "ls",
+ "-l",
+ f"gs://chromeos-toolchain-artifacts/llvm-pgo/{arch}/"
+ "*.profdata.tar.xz",
+ ],
+ check=True,
+ stdout=subprocess.PIPE,
+ encoding="utf-8",
+ )
+
+ # Each line will be a profdata; the last one is a summary, so drop it.
+ infos = []
+ for rec in result.stdout.strip().splitlines()[:-1]:
+ _size, date, url = rec.strip().split()
+ infos.append(ProfdataInfo(date=parse_date(date), location=url))
+ return max(infos)
def compose_complaint(
out_of_date_profiles: List[Tuple[datetime.datetime, ProfdataInfo]]
) -> Optional[str]:
- if not out_of_date_profiles:
- return None
+ if not out_of_date_profiles:
+ return None
- if len(out_of_date_profiles) == 1:
- body_lines = ['1 profile is out of date:']
- else:
- body_lines = [f'{len(out_of_date_profiles)} profiles are out of date:']
+ if len(out_of_date_profiles) == 1:
+ body_lines = ["1 profile is out of date:"]
+ else:
+ body_lines = [f"{len(out_of_date_profiles)} profiles are out of date:"]
- for arch, profdata_info in out_of_date_profiles:
- body_lines.append(
- f'- {arch} (most recent profile was from {profdata_info.date} at '
- f'{profdata_info.location!r})')
+ for arch, profdata_info in out_of_date_profiles:
+ body_lines.append(
+ f"- {arch} (most recent profile was from {profdata_info.date} at "
+ f"{profdata_info.location!r})"
+ )
- body_lines.append('\n')
- body_lines.append(
- 'PTAL to see if the llvm-pgo-generate bots are functioning normally. '
- f'Their status can be found at {PGO_BUILDBOT_LINK}.')
- return '\n'.join(body_lines)
+ body_lines.append("\n")
+ body_lines.append(
+ "PTAL to see if the llvm-pgo-generate bots are functioning normally. "
+ f"Their status can be found at {PGO_BUILDBOT_LINK}."
+ )
+ return "\n".join(body_lines)
def main() -> None:
- logging.basicConfig(level=logging.INFO)
-
- parser = argparse.ArgumentParser(
- description=__doc__,
- formatter_class=argparse.RawDescriptionHelpFormatter)
- parser.add_argument(
- '--max_age_days',
- # These builders run ~weekly. If we fail to generate two in a row,
- # something's probably wrong.
- default=15,
- type=int,
- help='How old to let profiles get before complaining, in days',
- )
- args = parser.parse_args()
-
- now = datetime.datetime.now()
- logging.info('Start time is %r', now)
-
- max_age = datetime.timedelta(days=args.max_age_days)
- out_of_date_profiles = []
- for arch in ('arm', 'arm64', 'amd64'):
- logging.info('Fetching most recent profdata for %r', arch)
- most_recent = fetch_most_recent_profdata(arch)
- logging.info('Most recent profdata for %r is %r', arch, most_recent)
-
- age = now - most_recent.date
- if age >= max_age:
- out_of_date_profiles.append((arch, most_recent))
-
- complaint = compose_complaint(out_of_date_profiles)
- if complaint:
- logging.error('%s', complaint)
- sys.exit(1)
-
- logging.info('Nothing seems wrong')
-
-
-if __name__ == '__main__':
- sys.exit(main())
+ logging.basicConfig(level=logging.INFO)
+
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--max_age_days",
+ # These builders run ~weekly. If we fail to generate two in a row,
+ # something's probably wrong.
+ default=15,
+ type=int,
+ help="How old to let profiles get before complaining, in days",
+ )
+ args = parser.parse_args()
+
+ now = datetime.datetime.now()
+ logging.info("Start time is %r", now)
+
+ max_age = datetime.timedelta(days=args.max_age_days)
+ out_of_date_profiles = []
+ for arch in ("arm", "arm64", "amd64"):
+ logging.info("Fetching most recent profdata for %r", arch)
+ most_recent = fetch_most_recent_profdata(arch)
+ logging.info("Most recent profdata for %r is %r", arch, most_recent)
+
+ age = now - most_recent.date
+ if age >= max_age:
+ out_of_date_profiles.append((arch, most_recent))
+
+ complaint = compose_complaint(out_of_date_profiles)
+ if complaint:
+ logging.error("%s", complaint)
+ sys.exit(1)
+
+ logging.info("Nothing seems wrong")
+
+
+if __name__ == "__main__":
+ sys.exit(main())