|
|
|
@@ -20,6 +20,7 @@ class HostConfig:
|
|
|
|
fqdn: str
|
|
|
|
fqdn: str
|
|
|
|
username: str
|
|
|
|
username: str
|
|
|
|
password: str
|
|
|
|
password: str
|
|
|
|
|
|
|
|
systemid: list[str] | None = None
|
|
|
|
max_retries: int = 1
|
|
|
|
max_retries: int = 1
|
|
|
|
backoff: int = 2
|
|
|
|
backoff: int = 2
|
|
|
|
cool_down: int = 120 # seconds to wait after too many failures
|
|
|
|
cool_down: int = 120 # seconds to wait after too many failures
|
|
|
|
@@ -241,12 +242,19 @@ async def get_power_data(session, host: HostConfig):
|
|
|
|
if not chassis_member_url:
|
|
|
|
if not chassis_member_url:
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Get Chassis ID from url ("/redfish/v1/Chassis/1" -> 1)
|
|
|
|
|
|
|
|
chassis_id = chassis_member_url.split("/")[-1]
|
|
|
|
|
|
|
|
# Check if the chassis id is in config (had problem with chassis "NVMe")
|
|
|
|
|
|
|
|
if hasattr(host, 'systemid') and host.systemid:
|
|
|
|
|
|
|
|
if chassis_id not in host.systemid:
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
member_url = f"https://{host.fqdn}{chassis_member_url}"
|
|
|
|
member_url = f"https://{host.fqdn}{chassis_member_url}"
|
|
|
|
member_data = await fetch_with_retry(session, host, member_url)
|
|
|
|
member_data = await fetch_with_retry(session, host, member_url)
|
|
|
|
if not member_data:
|
|
|
|
if not member_data:
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
# PowerSubsystem extrahieren
|
|
|
|
# PowerSubsystem url
|
|
|
|
power_subsystem_url = member_data.get("PowerSubsystem", {}).get("@odata.id")
|
|
|
|
power_subsystem_url = member_data.get("PowerSubsystem", {}).get("@odata.id")
|
|
|
|
if not power_subsystem_url:
|
|
|
|
if not power_subsystem_url:
|
|
|
|
logging.warning("No PowerSubsystem found for %s", host.fqdn)
|
|
|
|
logging.warning("No PowerSubsystem found for %s", host.fqdn)
|
|
|
|
@@ -265,7 +273,6 @@ async def get_power_data(session, host: HostConfig):
|
|
|
|
power_supplies_url = power_subsystem_data.get("PowerSupplies", {}).get(
|
|
|
|
power_supplies_url = power_subsystem_data.get("PowerSupplies", {}).get(
|
|
|
|
"@odata.id"
|
|
|
|
"@odata.id"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if not power_supplies_url:
|
|
|
|
if not power_supplies_url:
|
|
|
|
logging.warning("No PowerSupplies found for %s", host.fqdn)
|
|
|
|
logging.warning("No PowerSupplies found for %s", host.fqdn)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
@@ -299,28 +306,21 @@ async def get_power_data(session, host: HostConfig):
|
|
|
|
metrics_data = await fetch_with_retry(session, host, metrics_url)
|
|
|
|
metrics_data = await fetch_with_retry(session, host, metrics_url)
|
|
|
|
if not metrics_data:
|
|
|
|
if not metrics_data:
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
pretty = json.dumps(metrics_data, indent=4, sort_keys=True)
|
|
|
|
|
|
|
|
print(pretty)
|
|
|
|
|
|
|
|
exit(100)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Get Metrics from data
|
|
|
|
# Get Metrics from data
|
|
|
|
line_input_v = metrics_data.get("LineInputVoltage")
|
|
|
|
line_input_v = metrics_data.get("InputVoltage", {}).get("Reading")
|
|
|
|
watts_input = metrics_data.get("PowerInputWatts")
|
|
|
|
watts_input = metrics_data.get("InputPowerWatts", {}).get("Reading")
|
|
|
|
|
|
|
|
amps_input = metrics_data.get("InputCurrentAmps", {}).get("Reading")
|
|
|
|
serial = psu_data.get("SerialNumber")
|
|
|
|
serial = psu_data.get("SerialNumber")
|
|
|
|
# Calculate Amps
|
|
|
|
# Calculate Amps
|
|
|
|
amps = (
|
|
|
|
|
|
|
|
round(watts_input / line_input_v, 2)
|
|
|
|
|
|
|
|
if line_input_v and watts_input
|
|
|
|
|
|
|
|
else None
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
if line_input_v is not None:
|
|
|
|
if line_input_v is not None:
|
|
|
|
voltage_gauge.labels(host=host.fqdn, psu_serial=serial).set(
|
|
|
|
voltage_gauge.labels(host=host.fqdn, psu_serial=serial).set(
|
|
|
|
line_input_v
|
|
|
|
line_input_v
|
|
|
|
)
|
|
|
|
)
|
|
|
|
if watts_input is not None:
|
|
|
|
if watts_input is not None:
|
|
|
|
watts_gauge.labels(host=host.fqdn, psu_serial=serial).set(watts_input)
|
|
|
|
watts_gauge.labels(host=host.fqdn, psu_serial=serial).set(watts_input)
|
|
|
|
if amps is not None:
|
|
|
|
if amps_input is not None:
|
|
|
|
amps_gauge.labels(host=host.fqdn, psu_serial=serial).set(amps)
|
|
|
|
amps_gauge.labels(host=host.fqdn, psu_serial=serial).set(amps_input)
|
|
|
|
|
|
|
|
|
|
|
|
REQUEST_LATENCY.labels(host=host.fqdn).observe(time.monotonic() - start)
|
|
|
|
REQUEST_LATENCY.labels(host=host.fqdn).observe(time.monotonic() - start)
|
|
|
|
|
|
|
|
|
|
|
|
@@ -356,6 +356,7 @@ async def run_exporter(config, stop_event):
|
|
|
|
port = config.get("port", 8000)
|
|
|
|
port = config.get("port", 8000)
|
|
|
|
default_username = config.get("username")
|
|
|
|
default_username = config.get("username")
|
|
|
|
default_password = config.get("password")
|
|
|
|
default_password = config.get("password")
|
|
|
|
|
|
|
|
default_systemid = config.get("systemid")
|
|
|
|
hosts = config["hosts"]
|
|
|
|
hosts = config["hosts"]
|
|
|
|
interval = config.get("interval", 10)
|
|
|
|
interval = config.get("interval", 10)
|
|
|
|
|
|
|
|
|
|
|
|
@@ -371,6 +372,7 @@ async def run_exporter(config, stop_event):
|
|
|
|
fqdn=host_entry["fqdn"],
|
|
|
|
fqdn=host_entry["fqdn"],
|
|
|
|
username=host_entry.get("username", default_username),
|
|
|
|
username=host_entry.get("username", default_username),
|
|
|
|
password=host_entry.get("password", default_password),
|
|
|
|
password=host_entry.get("password", default_password),
|
|
|
|
|
|
|
|
systemid=host_entry.get("systemid", default_systemid),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
hc = HostConfig(
|
|
|
|
hc = HostConfig(
|
|
|
|
|