API Endpoints for screenly/balena-prometheus-exporter

Routes Defined in the Codebase

In the screenly/balena-prometheus-exporter project, the routes primarily revolve around REST API calls made to the Balena Cloud API to gather metrics related to the fleets the user has access to. The key interactions with the API are encapsulated within methods of the BalenaCollector class defined in main.py. The following sections detail those method routes, their purposes, and example invocations.

1. Retrieving Fleets

The method get_balena_fleets is responsible for fetching all fleets that the user can access. The method constructs a GET request to a specified Balena API endpoint:

def get_balena_fleets(self):
"""
Get all the fleets that the user has access to
and return all corresponding fleet IDs
"""

fleets = [] headers = { "Authorization": f"Bearer {BALENA_TOKEN}", "Content-Type": "application/json", }

response = requests.get( "https://api.balena-cloud.com/v6/application?$filter=is_directly_accessible_by__user/any(dau:1 eq 1)", headers=headers, )

if not response.ok: print("Error: {}".format(response.text)) sys.exit(1)

for fleet in response.json()["d"]: fleets.append((fleet["id"]))

return fleets

The endpoint used is:

GET https://api.balena-cloud.com/v6/application?$filter=is_directly_accessible_by__user/any(dau:1 eq 1)

This retrieves all applications (fleets) accessible to the user as defined by the API rules.

2. Retrieving Fleet Metrics

The metric retrieval for a specific fleet is handled by the get_fleet_metrics method. It constructs a GET request for a fleet’s specific metrics, including the count of online devices:

def get_fleet_metrics(self, fleet_id):
headers = {
"Authorization": f"Bearer {BALENA_TOKEN}",
"Content-Type": "application/json",
}

response = requests.get( f"https://api.balena-cloud.com/v6/application({fleet_id})?$expand=owns__device/$count($filter=is_online eq true)", headers=headers, )

if not response.ok: print("Error: {}".format(response.text)) sys.exit(1)

device_online_count = response.json()["d"][0]["owns__device"] fleet_name = response.json()["d"][0]["app_name"]

return fleet_name, device_online_count

The specific API endpoint used here is:

GET https://api.balena-cloud.com/v6/application({fleet_id})?$expand=owns__device/$count($filter=is_online eq true)

This route will return the fleet’s name and the count of devices that are currently online.

3. Collecting Metrics

The collect method assembles the data collected from the above methods into a format suitable for Prometheus scraping:

def collect(self):
gauge = GaugeMetricFamily(
"balena_devices_online", "Devices by status", labels=["fleet_name"]
)

for fleet_id in self.get_balena_fleets(): fleet_name, device_online_count = self.get_fleet_metrics(str(fleet_id)) gauge.add_metric([fleet_name], float(device_online_count))

return [gauge]

While this method does not directly hit an API route, it utilizes the metrics collected from the aforementioned routes to prepare the data for Prometheus.

4. Main Function

The main function orchestrates the execution of the program and starts the HTTP server for Prometheus to scrape data:

def main():
if not BALENA_TOKEN:
print("Please set the BALENA_TOKEN environment variable")
sys.exit(1)

start_http_server(8000) REGISTRY.register(BalenaCollector()) while True: time.sleep(int(CRAWL_INTERVAL))

This function initializes the server on port 8000, allowing for Prometheus to scrape metrics.

References

  • main.py
  • The structure and functionality of get_balena_fleets, get_fleet_metrics, and collect methods outline the specific API interactions with Balena relevant to this project.