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
- *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
- *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)
@ -57,7 +57,7 @@ Below are screenshots of the provided Grafana dashboards (found in the **doc/**
### 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).
### Renaming partitions

View file

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

View file

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

View file

@ -19,6 +19,8 @@ import okhttp3.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Entities;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
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
* @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
*

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>