Skip to content

Instantly share code, notes, and snippets.

@asvinours
Created December 19, 2021 22:10
Show Gist options
  • Select an option

  • Save asvinours/c3a5ae4c1d1e4c183b01be6fa1a1c694 to your computer and use it in GitHub Desktop.

Select an option

Save asvinours/c3a5ae4c1d1e4c183b01be6fa1a1c694 to your computer and use it in GitHub Desktop.
Export Checkly result stats to table format
#!/usr/bin/python3
# Checkly API reference: https://www.checklyhq.com/docs/api
import datetime
import dateutil.parser as dp
import time
import numpy as np
import requests
from tabulate import tabulate
BASE_URL = "https://api.checklyhq.com/v1"
headers = {
'Authorization': 'Bearer <API KEY>',
'X-Checkly-Account': '<ACCOUNT ID>',
}
today = datetime.date.today()
weekago = today - datetime.timedelta(7)
r = requests.get(
f"{BASE_URL}/check-groups/<GROUP ID>/checks",
headers=headers,
)
checks = {}
for check in r.json():
checks[check['id']] = check['name']
check_results = []
query_interval = 43200
for check_id, check_name in checks.items():
print(f"retrieving check results for {check_name}")
start_epoch = int(weekago.strftime("%s"))
while True:
print(f"Start date: {start_epoch}")
r = requests.get(
f"{BASE_URL}/check-results/{check_id}",
headers=headers,
params={
"hasFailures": False,
"from": start_epoch,
"to": start_epoch + query_interval,
"limit": 100,
}
)
crs = [chk for chk in r.json() if isinstance(chk, dict)]
check_results.extend(crs)
start_epoch = int(start_epoch) + query_interval + 1
if start_epoch >= int(time.time()):
print(f"no more check results for {check_name}, break.")
break
response_times = {}
computed_stats = {}
for result in check_results:
if result['hasFailures']:
continue
name = checks[result['checkId']]
region = result['runLocation']
response_times.setdefault(name, dict())
response_times[name].setdefault(region, {
"response_time": [],
"fcp": [],
"ttfb": [],
})
computed_stats.setdefault(region, dict())
computed_stats[region].setdefault(name, dict())
page = result['browserCheckResult']['pages'][0]
web_vitals = page['webVitals']
response_times[name][region]["response_time"].append(int(result['responseTime']))
response_times[name][region]["fcp"].append(int(web_vitals['FCP']['value']))
response_times[name][region]["ttfb"].append(int(web_vitals['TTFB']['value']))
check_count = len(response_times[name][region]["response_time"])
computed_stats[region][name]["count"] = check_count
for stat in ["response_time", "fcp", "ttfb"]:
average = round(np.average(response_times[name][region][stat]) / 1000.0, 4)
computed_stats[region][name][f"{stat}_average"] = average
for perct in [75, 90, 95]:
percentile = round(np.percentile(response_times[name][region][stat], perct) / 1000.0, 4)
computed_stats[region][name][f"{stat}_p{perct}"] = percentile
for region, data in computed_stats.items():
print(f"Region: {region}")
headers = [["Name"] + list(v.keys()) for k, v in data.items()][0]
print(tabulate([[k] + list(v.values()) for k, v in data.items()], headers=headers))
Region: ca-central-1
Name count response_time_average response_time_p75 response_time_p90 response_time_p95 fcp_average fcp_p75 fcp_p90 fcp_p95 ttfb_average ttfb_p75 ttfb_p90 ttfb_p95
--------------------- ------- ----------------------- ------------------- ------------------- ------------------- ------------- --------- --------- --------- -------------- ---------- ---------- ----------
my_check_name #1 94 5.2564 5.208 5.36 5.8505 0.6177 0.6302 0.7077 0.761 0.4453 0.455 0.5079 0.5492
my_check_name #2 216 5.2233 5.3108 5.731 6.1382 0.8465 0.836 1.068 1.651 0.6946 0.683 0.923 1.533
my_check_name #3 218 5.1883 5.3048 5.5646 5.7523 0.5233 0.5498 0.6101 0.654 0.3858 0.409 0.468 0.524
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment