Skip to content

Commit

Permalink
Upload average CPU consumption of CI jobs to DataDog
Browse files Browse the repository at this point in the history
  • Loading branch information
Kobzol committed Jul 3, 2024
1 parent 7d97c59 commit 95db961
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ jobs:
# erroring about invalid credentials instead.
if: github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1'

- name: upload job metrics to DataDog
if: needs.calculate_matrix.outputs.run_type != 'pr'
env:
DATADOG_SITE: datadoghq.com
DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }}
DD_GITHUB_JOB_NAME: ${{ matrix.name }}
run: |
npm install -g @datadog/datadog-ci
python3 src/ci/scripts/upload-build-metrics.py build/cpu-usage.csv
# This job isused to tell bors the final status of the build, as there is no practical way to detect
# when a workflow is successful listening to webhooks only in our current bors implementation (homu).
outcome:
Expand Down
72 changes: 72 additions & 0 deletions src/ci/scripts/upload-build-metrics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
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 subprocess
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}")
subprocess.run([
"datadog-ci",
"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)

0 comments on commit 95db961

Please sign in to comment.