Option to enable power and thermal readings through the HCM REST API.

This commit is contained in:
Mark Nellemann 2021-01-28 19:53:45 +01:00
parent b93b560fd9
commit 98044859ae
5 changed files with 140 additions and 11 deletions

View file

@ -6,7 +6,7 @@ Metrics includes:
- *Managed Systems* - the physical Power servers - *Managed Systems* - the physical Power servers
- *Logical Partitions* - the virtualized servers running AIX, Linux and IBM-i (AS/400) - *Logical Partitions* - the virtualized servers running AIX, Linux and IBM-i (AS/400)
- *Virtual I/O Servers* - the i/o partition(s) taking care of network and storage - *Virtual I/O Servers* - the i/o partition(s) taking care of network and storage
- *Energy* - power consumption and temperatures - *Energy* - power consumption and temperatures (needs to be enabled and not available for E880, E980)
![architecture](https://bitbucket.org/mnellemann/hmci/downloads/HMCi.png) ![architecture](https://bitbucket.org/mnellemann/hmci/downloads/HMCi.png)
@ -57,7 +57,7 @@ Below are screenshots of the provided Grafana dashboards (found in the **doc/**
### Naming collision ### Naming collision
You can't have partitions on different HMC's with the same name, as these cannot be distinguished when metrics are You can't have partitions (or Virtual I/O Servers) on different Systems with the same name, as these cannot be distinguished when metrics are
written to InfluxDB (which uses the name as key). written to InfluxDB (which uses the name as key).
### Renaming partitions ### Renaming partitions

View file

@ -2,6 +2,8 @@
Description=HMC Insights Service Description=HMC Insights Service
[Service] [Service]
#User=nobody
#Group=nogroup
TimeoutStartSec=0 TimeoutStartSec=0
Restart=always Restart=always
ExecStart=/opt/hmci/bin/hmci ExecStart=/opt/hmci/bin/hmci

View file

@ -110,6 +110,8 @@ class HmcInstance implements Runnable {
log.debug("discover() - " + hmcId); log.debug("discover() - " + hmcId);
Map<String, LogicalPartition> tmpPartitions = new HashMap<>();
try { try {
hmcRestClient.logoff(); hmcRestClient.logoff();
hmcRestClient.login(); hmcRestClient.login();
@ -119,19 +121,16 @@ class HmcInstance implements Runnable {
if(!systems.containsKey(systemId)) { if(!systems.containsKey(systemId)) {
systems.put(systemId, system); systems.put(systemId, system);
log.info("discover() - Found ManagedSystem: " + system + " @" + hmcId); log.info("discover() - Found ManagedSystem: " + system + " @" + hmcId);
hmcRestClient.enableEnergyMonitoring(system);
} }
// Get LPAR's for this system // Get LPAR's for this system
try { try {
hmcRestClient.getLogicalPartitionsForManagedSystem(system).forEach((partitionId, partition) -> { hmcRestClient.getLogicalPartitionsForManagedSystem(system).forEach(tmpPartitions::put);
if(!tmpPartitions.isEmpty()) {
// Add to list of known partitions partitions.clear();
if(!partitions.containsKey(partitionId)) { tmpPartitions.forEach(partitions::put);
partitions.put(partitionId, partition);
log.info("discover() - Found LogicalPartition: " + partition + " @" + hmcId);
} }
});
} catch (Exception e) { } catch (Exception e) {
log.warn("discover() - getLogicalPartitions", e); log.warn("discover() - getLogicalPartitions", e);
} }
@ -142,6 +141,7 @@ class HmcInstance implements Runnable {
log.warn("discover() - getManagedSystems: " + e.getMessage()); log.warn("discover() - getManagedSystems: " + e.getMessage());
} }
} }

View file

@ -19,6 +19,8 @@ import okhttp3.*;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.nodes.Entities;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -347,6 +349,54 @@ public class HmcRestClient {
} }
void enableEnergyMonitoring(ManagedSystem system) {
log.debug("enableEnergyMonitoring() - " + system.id);
try {
URL url = new URL(String.format("%s/rest/api/pcm/ManagedSystem/%s/preferences", baseUrl, system.id));
String responseBody = getResponse(url);
String jsonBody = null;
// Do not try to parse empty response
if(responseBody == null || responseBody.isEmpty() || responseBody.length() <= 1) {
responseErrors++;
log.warn("enableEnergyMonitoring() - empty response");
return;
}
Document doc = Jsoup.parse(responseBody, "", Parser.xmlParser());
doc.outputSettings().escapeMode(Entities.EscapeMode.xhtml);
doc.outputSettings().prettyPrint(false);
doc.outputSettings().charset("US-ASCII");
Element entry = doc.select("feed > entry").first();
Element link1 = entry.select("EnergyMonitoringCapable").first();
Element link2 = entry.select("EnergyMonitorEnabled").first();
if(link1.text().equals("true")) {
log.debug("enableEnergyMonitoring() - EnergyMonitoringCapable == true");
if(link2.text().equals("false")) {
//log.warn("enableEnergyMonitoring() - EnergyMonitorEnabled == false");
link2.text("true");
Document content = Jsoup.parse(doc.select("Content").first().html(), "", Parser.xmlParser());
content.outputSettings().escapeMode(Entities.EscapeMode.xhtml);
content.outputSettings().prettyPrint(false);
content.outputSettings().charset("UTF-8");
String updateXml = content.outerHtml();
sendPostRequest(url, updateXml);
}
} else {
log.warn("enableEnergyMonitoring() - EnergyMonitoringCapable == false");
}
} catch (Exception e) {
log.warn("enableEnergyMonitoring() - Exception: " + e.getMessage());
}
}
/** /**
* Return a Response from the HMC * Return a Response from the HMC
* @param url to get Response from * @param url to get Response from
@ -385,6 +435,41 @@ public class HmcRestClient {
public String sendPostRequest(URL url, String payload) throws Exception {
log.debug("sendPostRequest() - " + url.toString());
RequestBody requestBody;
if(payload != null) {
//log.debug("sendPostRequest() - payload: " + payload);
requestBody = RequestBody.create(payload, MediaType.get("application/xml"));
} else {
requestBody = RequestBody.create("", null);
}
Request request = new Request.Builder()
.url(url)
//.addHeader("Content-Type", "application/xml")
.addHeader("content-type", "application/xml")
.addHeader("X-API-Session", authToken)
.post(requestBody).build();
Response response = client.newCall(request).execute();
String body = Objects.requireNonNull(response.body()).string();
if (!response.isSuccessful()) {
response.close();
log.warn(body);
log.error("sendPostRequest() - Unexpected response: " + response.code());
throw new IOException("sendPostRequest() - Unexpected response: " + response.code());
}
log.debug("sendPostRequest() - response: " + body);
return body;
}
/** /**
* Provide an unsafe (ignoring SSL problems) OkHttpClient * Provide an unsafe (ignoring SSL problems) OkHttpClient
* *

View file

@ -0,0 +1,42 @@
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:ns2="http://a9.com/-/spec/opensearch/1.1/" xmlns:ns3="http://www.w3.org/1999/xhtml">
<id>d93d97ab-757a-38ed-afe7-013c51cf60c9</id>
<title type="text">Performance and Capacity Monitoring Preferences</title>
<subtitle type="text"/>
<link rel="self" href="https://10.32.64.40:12443/rest/api/pcm/ManagedSystem/d93d97ab-757a-38ed-afe7-013c51cf60c9/preferences"/>
<generator uri="IBM Power Systems Management Console" version="1"/>
<entry>
<id>e40c41c0-4aff-472d-85f2-715e11ed1a74</id>
<updated>2021-01-28T13:13:23.636+01:00</updated>
<title type="text">Performance and Capacity Monitoring Preferences</title>
<published>2021-01-28T13:13:23.636+01:00</published>
<author>
<name>IBM Power Systems Management Console</name>
</author>
<content type="application/xml">
<ManagedSystemPcmPreference:ManagedSystemPcmPreference xmlns:ManagedSystemPcmPreference="http://www.ibm.com/xmlns/systems/power/firmware/pcm/mc/2012_10/" xmlns="http://www.ibm.com/xmlns/systems/power/firmware/pcm/mc/2012_10/" xmlns:ns2="http://www.w3.org/XML/1998/namespace/k2" schemaVersion="V1_5_3">
<Metadata>
<Atom>
<AtomID>d93d97ab-757a-38ed-afe7-013c51cf60c9</AtomID>
<AtomCreated>1611836003635</AtomCreated>
</Atom>
</Metadata>
<SystemName kxe="false" kb="ROR">P750-8408-E8D-SN211D04V</SystemName>
<MachineTypeModelSerialNumber kb="ROR" kxe="false" schemaVersion="V1_5_3">
<Metadata>
<Atom/>
</Metadata>
<MachineType kb="ROR" kxe="false">8408</MachineType>
<Model kxe="false" kb="ROR">E8D</Model>
<SerialNumber kxe="false" kb="ROR">211D04V</SerialNumber>
</MachineTypeModelSerialNumber>
<EnergyMonitoringCapable kxe="false" kb="ROO">false</EnergyMonitoringCapable>
<LongTermMonitorEnabled kb="UOD" kxe="false">true</LongTermMonitorEnabled>
<AggregationEnabled kxe="false" kb="UOD">true</AggregationEnabled>
<ShortTermMonitorEnabled kb="UOD" kxe="false">false</ShortTermMonitorEnabled>
<ComputeLTMEnabled ksv="V1_1_0" kxe="false" kb="UOD">true</ComputeLTMEnabled>
<EnergyMonitorEnabled kb="UOD" kxe="false">false</EnergyMonitorEnabled>
<AssociatedManagedSystem kxe="false" kb="ROO" href="https://127.0.0.1:13443/rest/api/uom/ManagedSystem/d93d97ab-757a-38ed-afe7-013c51cf60c9" rel="related"/>
</ManagedSystemPcmPreference:ManagedSystemPcmPreference>
</content>
</entry>
</feed>