about summary refs log tree commit diff
path: root/src/ci
diff options
context:
space:
mode:
authorJakub Beránek <berykubik@gmail.com>2024-09-26 13:44:06 +0200
committerJakub Beránek <berykubik@gmail.com>2024-09-27 11:39:52 +0200
commitc1c0bd7a251865e82b1e8d0292451f78f19f22a8 (patch)
treeb10f19f00b6ac91634e6917ef43cc5ea2985ab27 /src/ci
parent76ed7a1fa40c3f54d3fd3f834e12bf9c932d0146 (diff)
Upload average CPU consumption of CI jobs to DataDog
Diffstat (limited to 'src/ci')
-rwxr-xr-xsrc/ci/scripts/upload-artifacts.sh2
-rw-r--r--src/ci/scripts/upload-build-metrics.py81
2 files changed, 82 insertions, 1 deletions
diff --git a/src/ci/scripts/upload-artifacts.sh b/src/ci/scripts/upload-artifacts.sh
index 61c187fa77c..129ede636f3 100755
--- a/src/ci/scripts/upload-artifacts.sh
+++ b/src/ci/scripts/upload-artifacts.sh
@@ -23,7 +23,7 @@ if [[ "${DEPLOY-0}" -eq "1" ]] || [[ "${DEPLOY_ALT-0}" -eq "1" ]]; then
 fi
 
 # CPU usage statistics.
-mv build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv"
+cp build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv"
 
 # Build metrics generated by x.py.
 mv "${build_dir}/metrics.json" "${upload_dir}/metrics-${CI_JOB_NAME}.json"
diff --git a/src/ci/scripts/upload-build-metrics.py b/src/ci/scripts/upload-build-metrics.py
new file mode 100644
index 00000000000..a95e0949d70
--- /dev/null
+++ b/src/ci/scripts/upload-build-metrics.py
@@ -0,0 +1,81 @@
+"""
+This script postprocesses data gathered during a CI run, computes certain metrics
+from them, and uploads these metrics to DataDog.
+
+This script is expected to be executed from within a GitHub Actions job.
+
+It expects the following environment variables:
+- DATADOG_SITE: path to the DataDog API endpoint
+- DATADOG_API_KEY: DataDog API token
+- DD_GITHUB_JOB_NAME: Name of the current GitHub Actions job
+
+And it also expects the presence of a binary called `datadog-ci` to be in PATH.
+It can be installed with `npm install -g @datadog/datadog-ci`.
+
+Usage:
+```bash
+$ python3 upload-build-metrics.py <path-to-CPU-usage-CSV>
+```
+
+`path-to-CPU-usage-CSV` is a path to a CSV generated by the `src/ci/cpu-usage-over-time.py` script.
+"""
+import argparse
+import csv
+import os
+import subprocess
+import sys
+from pathlib import Path
+from typing import List
+
+
+def load_cpu_usage(path: Path) -> List[float]:
+    usage = []
+    with open(path) as f:
+        reader = csv.reader(f, delimiter=',')
+        for row in reader:
+            # The log might contain incomplete rows or some Python exception
+            if len(row) == 2:
+                try:
+                    idle = float(row[1])
+                    usage.append(100.0 - idle)
+                except ValueError:
+                    pass
+    return usage
+
+
+def upload_datadog_measure(name: str, value: float):
+    """
+    Uploads a single numeric metric for the current GitHub Actions job to DataDog.
+    """
+    print(f"Metric {name}: {value:.4f}")
+
+    datadog_cmd = "datadog-ci"
+    if os.getenv("GITHUB_ACTIONS") is not None and sys.platform.lower().startswith("win"):
+        # Due to weird interaction of MSYS2 and Python, we need to use an absolute path,
+        # and also specify the ".cmd" at the end. See https://github.com/rust-lang/rust/pull/125771.
+        datadog_cmd = "C:\\npm\\prefix\\datadog-ci.cmd"
+
+    subprocess.run([
+        datadog_cmd,
+        "measure",
+        "--level", "job",
+        "--measures", f"{name}:{value}"
+    ],
+        check=False
+    )
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(
+        prog="DataDog metric uploader"
+    )
+    parser.add_argument("cpu-usage-history-csv")
+    args = parser.parse_args()
+
+    build_usage_csv = vars(args)["cpu-usage-history-csv"]
+    usage_timeseries = load_cpu_usage(Path(build_usage_csv))
+    if len(usage_timeseries) > 0:
+        avg_cpu_usage = sum(usage_timeseries) / len(usage_timeseries)
+    else:
+        avg_cpu_usage = 0
+    upload_datadog_measure("avg-cpu-usage", avg_cpu_usage)