Skip to content

Commit 3b9aa72

Browse files
committed
re-implement
1 parent 10b6262 commit 3b9aa72

File tree

3 files changed

+75
-44
lines changed

3 files changed

+75
-44
lines changed
Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,47 @@
11
from prometheus_client.core import GaugeMetricFamily, REGISTRY
22
from prometheus_client.registry import Collector
3-
import random
3+
import time
4+
import logging
45
from util import instances_per_hypervisor
6+
import openstack
7+
8+
logger = logging.getLogger(__name__)
59

610
class InstancesPerHypervisorCollector(Collector):
7-
cloud = None
8-
def __init__(self, cloud):
9-
self.cloud = cloud
11+
def __init__(self, cloud_name):
12+
super().__init__()
13+
self.cloud_name = cloud_name
14+
self.metrics = []
15+
self.last_update = 0
16+
self.cache_time = 60
17+
18+
def _fetch_metrics(self):
19+
try:
20+
new_metrics = instances_per_hypervisor.export_metrics(self.cloud_name)
21+
self.metrics = new_metrics
22+
self.last_update = time.time()
23+
logger.info(f"Updated metrics with {len(new_metrics)} hypervisors")
24+
25+
except Exception as e:
26+
logger.error(f"Error updating metrics: {str(e)}")
27+
raise
1028

1129
def collect(self):
12-
instances_per_hypervisor_gauge = GaugeMetricFamily('openstack_peepo_exporter_instances_per_hypervisor', 'Number of instances per hypervisor', labels=['hypervisor_name', 'hypervisor_id'])
13-
metrics = instances_per_hypervisor.export_metrics(self.cloud)
14-
print(f"data: {metrics}")
15-
for metric in metrics:
16-
instances_per_hypervisor_gauge.add_metric([metric['hypervisor_name'], metric['hypervisor_id']], metric['instance_count'])
17-
yield instances_per_hypervisor_gauge
30+
if time.time() - self.last_update > self.cache_time:
31+
self._fetch_metrics()
32+
33+
gauge = GaugeMetricFamily(
34+
'openstack_peepo_exporter_instances_per_hypervisor',
35+
'Number of instances per hypervisor',
36+
labels=['hypervisor_name', 'hypervisor_id']
37+
)
38+
39+
for metric in self.metrics:
40+
gauge.add_metric(
41+
[metric['hypervisor_name'], metric['hypervisor_id']],
42+
metric['instance_count']
43+
)
44+
45+
yield gauge
46+
1847

src/main.py

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,39 @@
1-
from prometheus_client import generate_latest, CollectorRegistry, CONTENT_TYPE_LATEST
1+
from prometheus_client import generate_latest, CollectorRegistry, CONTENT_TYPE_LATEST, start_http_server, REGISTRY
2+
import argparse, uvicorn, time, logging
23
from collectors.instances_per_hypervisor import InstancesPerHypervisorCollector
3-
from fastapi import FastAPI, Response
4-
import argparse, uvicorn
54

6-
def create_app(cloud_name: str):
7-
registry = CollectorRegistry()
8-
registry.register(InstancesPerHypervisorCollector(cloud_name))
9-
10-
app = FastAPI(debug=True, redirect_slashes=False)
11-
12-
@app.get("/metrics")
13-
async def metrics(response: Response):
14-
response.headers['Content-Type'] = CONTENT_TYPE_LATEST
15-
data = generate_latest(registry)
16-
return Response(content=data.decode('utf-8'), media_type=CONTENT_TYPE_LATEST)
17-
18-
return app
5+
# Configure logging
6+
logging.basicConfig(
7+
level=logging.INFO,
8+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
9+
)
10+
logger = logging.getLogger(__name__)
1911

2012
if __name__ == "__main__":
21-
parser = argparse.ArgumentParser(
22-
description="Export metrics for a given cloud."
23-
)
24-
parser.add_argument(
25-
"--cloud", required=True, help="The name of the cloud."
26-
)
27-
args = parser.parse_args()
28-
29-
# Create the app with the provided cloud name
30-
app = create_app(args.cloud)
31-
32-
uvicorn.run(app, host="0.0.0.0", port=8000)
13+
try:
14+
parser = argparse.ArgumentParser(
15+
description="Export metrics for a given cloud."
16+
)
17+
parser.add_argument(
18+
"--cloud", required=True, help="The name of the cloud."
19+
)
20+
args = parser.parse_args()
21+
22+
# Register the collector
23+
registry = CollectorRegistry()
24+
registry.register(InstancesPerHypervisorCollector(args.cloud))
25+
26+
# Start the metrics server
27+
start_http_server(8000, registry=registry)
28+
logger.info("Exporter running at http://localhost:8000")
29+
30+
# Keep the main thread alive
31+
try:
32+
while True:
33+
time.sleep(1)
34+
except KeyboardInterrupt:
35+
logger.info("\nShutting down...")
36+
except Exception as e:
37+
logger.error(f"Failed to start exporter: {str(e)}")
38+
raise
3339

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
import openstack
22

33
def export_metrics(cloud_name: str):
4-
5-
# Initialize connection (assumes clouds.yaml is configured)
4+
print(f"exporting metrics for {cloud_name}")
65
conn = openstack.connect(cloud=cloud_name)
76

8-
# Dictionary to store instance counts per hypervisor
97
instance_counts = []
108

11-
# Iterate over all resource providers
129
for rp in conn.placement.resource_providers():
10+
print(f"rp: {rp}")
1311
hypervisor_id = rp.id
1412
hypervisor_name = rp.name
1513

16-
# Get allocations for this resource provider
1714
allocations = conn.placement.get(f'/resource_providers/{rp.id}/allocations').json()
1815
instance_count = len(allocations.get('allocations', {}))
1916
data = {
@@ -25,6 +22,5 @@ def export_metrics(cloud_name: str):
2522

2623
print(f"Hypervisor: {hypervisor_name}, Instances: {instance_count}")
2724

28-
# Return the dictionary containing hypervisor instance counts
2925
return instance_counts
3026

0 commit comments

Comments
 (0)