From ea7922db7cd0833ff160aa2a84c1840b6e74828d Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Wed, 13 Jan 2021 08:31:07 +0100 Subject: [PATCH 1/4] More robustness towards null metrics. --- README.md | 15 +++++++ gradle.properties | 2 +- .../biz/nellemann/hmci/Configuration.java | 14 ++++--- .../java/biz/nellemann/hmci/HmcClient.java | 40 +++++++++++++++---- .../java/biz/nellemann/hmci/InfluxClient.java | 5 ++- .../java/biz/nellemann/hmci/Insights.java | 39 +++++++++++------- .../biz/nellemann/hmci/LogicalPartition.java | 23 ++++++----- .../biz/nellemann/hmci/ManagedSystem.java | 33 +++++++-------- .../java/biz/nellemann/hmci/Measurement.java | 15 +++++++ .../java/biz/nellemann/hmci/MetaSystem.java | 15 +++++++ .../java/biz/nellemann/hmci/SystemEnergy.java | 9 +++-- .../biz/nellemann/hmci/VersionProvider.java | 1 + .../hmci/pcm/FiberChannelAdapter.java | 8 ++-- .../nellemann/hmci/pcm/GenericAdapter.java | 19 ++++----- .../hmci/pcm/GenericPhysicalAdapters.java | 6 +-- .../hmci/pcm/GenericVirtualAdapter.java | 8 ++-- .../biz/nellemann/hmci/pcm/LparProcessor.java | 6 +-- .../java/biz/nellemann/hmci/pcm/LparUtil.java | 18 ++++----- .../java/biz/nellemann/hmci/pcm/PcmData.java | 2 +- .../hmci/pcm/PhysicalProcessorPool.java | 11 ++--- .../biz/nellemann/hmci/pcm/PowerUtil.java | 1 + .../biz/nellemann/hmci/pcm/SampleInfo.java | 4 +- .../biz/nellemann/hmci/pcm/ServerMemory.java | 8 ++-- .../nellemann/hmci/pcm/ServerProcessor.java | 8 ++-- .../biz/nellemann/hmci/pcm/ServerUtil.java | 9 +++-- .../biz/nellemann/hmci/pcm/SharedAdapter.java | 20 +++++----- .../hmci/pcm/SharedProcessorPool.java | 14 +++---- .../biz/nellemann/hmci/pcm/Temperature.java | 6 +-- .../java/biz/nellemann/hmci/pcm/UtilInfo.java | 19 ++++----- .../biz/nellemann/hmci/pcm/UtilSample.java | 18 ++------- .../biz/nellemann/hmci/pcm/ViosMemory.java | 4 +- .../java/biz/nellemann/hmci/pcm/ViosUtil.java | 18 ++++----- .../hmci/pcm/VirtualEthernetAdapter.java | 37 ++++++++--------- .../hmci/pcm/VirtualFiberChannelAdapter.java | 23 ++++++----- src/main/resources/simplelogger.properties | 1 + 35 files changed, 282 insertions(+), 197 deletions(-) diff --git a/README.md b/README.md index 0ba9e31..df9e0a9 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,21 @@ Below are screenshots of the provided Grafana dashboards (found in the **doc/** - [hmci-lpars](https://bitbucket.org/mnellemann/hmci/downloads/hmci-lpars.png) +## Known problems + +### Naming collision + +You can't have partitions on different HMC's with the same name, as these cannot be distinguished when metrics are +written to InfluxDB (which uses the name is key). + +### Renaming partitions + +If you rename a partition, the metrics in InfluxDB will still be available by the old name, and new metrics will be +available by the new name of the partition. There is no easy way to migrate the old data, but you can delete it easily: + + DELETE WHERE partition = 'lpar-name'; + + ## Notes ### Start InfluxDB and Grafana at boot on RedHat 7+ diff --git a/gradle.properties b/gradle.properties index 1acfe4d..280a682 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ id = hmci group = biz.nellemann.hmci -version = 1.0.1 +version = 1.0.2 diff --git a/src/main/java/biz/nellemann/hmci/Configuration.java b/src/main/java/biz/nellemann/hmci/Configuration.java index acdb743..baa4853 100644 --- a/src/main/java/biz/nellemann/hmci/Configuration.java +++ b/src/main/java/biz/nellemann/hmci/Configuration.java @@ -10,7 +10,7 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -public class Configuration { +public final class Configuration { //private final static Logger log = LoggerFactory.getLogger(Configuration.class); @@ -25,17 +25,19 @@ public class Configuration { TomlParseResult result = Toml.parse(source); result.errors().forEach(error -> System.err.println(error.toString())); - if(result.contains("refresh")) { - refresh = result.getLong("refresh"); + if(result.contains("hmci.refresh")) { + refresh = result.getLong("hmci.refresh"); } else { - refresh = 15L; + refresh = 30L; } + System.err.println("Refresh: " + refresh); - if(result.contains("rescan")) { - rescan = result.getLong("rescan"); + if(result.contains("hmci.rescan")) { + rescan = result.getLong("hmci.rescan"); } else { rescan = 60L; } + System.err.println("Rescan: " + refresh); hmc = getHmc(result); influx = getInflux(result); diff --git a/src/main/java/biz/nellemann/hmci/HmcClient.java b/src/main/java/biz/nellemann/hmci/HmcClient.java index f27d241..9fb5b89 100644 --- a/src/main/java/biz/nellemann/hmci/HmcClient.java +++ b/src/main/java/biz/nellemann/hmci/HmcClient.java @@ -28,11 +28,14 @@ import javax.net.ssl.*; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.concurrent.TimeUnit; class HmcClient { @@ -49,6 +52,11 @@ class HmcClient { protected String authToken; private final OkHttpClient client; + // OkHttpClient timeouts + private final static int connectTimeout = 2; + private final static int writeTimeout = 3; + private final static int readTimeout = 3; + HmcClient(HmcObject configHmc) { @@ -61,7 +69,7 @@ class HmcClient { if(unsafe) { this.client = getUnsafeOkHttpClient(); } else { - this.client = new OkHttpClient(); + this.client = getSafeOkHttpClient(); } } @@ -193,7 +201,7 @@ class HmcClient { Map getLogicalPartitionsForManagedSystem(ManagedSystem system) throws Exception { URL url = new URL(String.format("%s/rest/api/uom/ManagedSystem/%s/LogicalPartition", baseUrl, system.id)); String responseBody = getResponse(url); - Map partitionMap = new HashMap(); + Map partitionMap = new HashMap<>(); // Do not try to parse empty response if(responseBody == null || responseBody.isEmpty() || responseBody.length() <= 1) { @@ -300,7 +308,8 @@ class HmcClient { /** - * Parse XML feed to get PCM Data in JSON format + * Parse XML feed to get PCM Data in JSON format. + * Does not work for older HMC (pre v9) and older Power server (pre Power 8). * @param systemEnergy a valid SystemEnergy * @return JSON string with PCM data for this SystemEnergy */ @@ -315,7 +324,7 @@ class HmcClient { // Do not try to parse empty response if(responseBody == null || responseBody.isEmpty() || responseBody.length() <= 1) { responseErrors++; - log.warn("getPcmDataForEnergy() - empty response"); + log.debug("getPcmDataForEnergy() - empty response"); return null; } @@ -379,7 +388,7 @@ class HmcClient { /** * Provide an unsafe (ignoring SSL problems) OkHttpClient * - * @return unsafe OkHttpClient + * @return OkHttpClient ignoring SSL/TLS errors */ private static OkHttpClient getUnsafeOkHttpClient() { try { @@ -387,8 +396,7 @@ class HmcClient { final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) { - } + public void checkClientTrusted(X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { @@ -411,11 +419,27 @@ class HmcClient { OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]); builder.hostnameVerifier((hostname, session) -> true); + builder.connectTimeout(connectTimeout, TimeUnit.SECONDS); + builder.writeTimeout(writeTimeout, TimeUnit.SECONDS); + builder.readTimeout(readTimeout, TimeUnit.SECONDS); return builder.build(); - } catch (Exception e) { + } catch (KeyManagementException | NoSuchAlgorithmException e) { throw new RuntimeException(e); } } + + /** + * Get OkHttpClient with our preferred timeout values. + * @return OkHttpClient + */ + private static OkHttpClient getSafeOkHttpClient() { + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.connectTimeout(connectTimeout, TimeUnit.SECONDS); + builder.writeTimeout(writeTimeout, TimeUnit.SECONDS); + builder.readTimeout(readTimeout, TimeUnit.SECONDS); + return builder.build(); + } + } diff --git a/src/main/java/biz/nellemann/hmci/InfluxClient.java b/src/main/java/biz/nellemann/hmci/InfluxClient.java index 07be409..d2a7cc1 100644 --- a/src/main/java/biz/nellemann/hmci/InfluxClient.java +++ b/src/main/java/biz/nellemann/hmci/InfluxClient.java @@ -125,7 +125,7 @@ class InfluxClient { void writeManagedSystem(ManagedSystem system) { if(system.metrics == null) { - log.warn("writeManagedSystem() - null metrics, skipping"); + log.debug("writeManagedSystem() - null metrics, skipping"); return; } @@ -242,13 +242,14 @@ class InfluxClient { /* System Energy + Not supported on older HMC (pre v8) or older Power server (pre Power 8) */ void writeSystemEnergy(SystemEnergy system) { if(system.metrics == null) { - log.warn("writeSystemEnergy() - null metrics, skipping"); + log.debug("writeSystemEnergy() - null metrics, skipping"); return; } diff --git a/src/main/java/biz/nellemann/hmci/Insights.java b/src/main/java/biz/nellemann/hmci/Insights.java index 258796f..708eaa4 100644 --- a/src/main/java/biz/nellemann/hmci/Insights.java +++ b/src/main/java/biz/nellemann/hmci/Insights.java @@ -17,6 +17,9 @@ package biz.nellemann.hmci; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + +import java.time.Duration; +import java.time.Instant; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; @@ -69,7 +72,7 @@ class Insights { // Add to list of known systems if(!systems.containsKey(systemId)) { systems.put(systemId, system); - log.info("discover() - Found ManagedSystem: " + system); + log.info(hmcId + " discover() - Found ManagedSystem: " + system); } // Get LPAR's for this system @@ -79,18 +82,18 @@ class Insights { // Add to list of known partitions if(!partitions.containsKey(partitionId)) { partitions.put(partitionId, partition); - log.info("discover() - Found LogicalPartition: " + partition); + log.info(hmcId + " discover() - Found LogicalPartition: " + partition); } }); } catch (Exception e) { - log.error("discover()", e); + log.error(hmcId + " discover() - getLogicalPartitions", e); } }); } catch(Exception e) { - log.error("discover() - " + hmcId + " error: " + e.getMessage()); + log.error(hmcId + " discover() - getManagedSystems: " + e.getMessage()); } }); @@ -176,7 +179,7 @@ class Insights { try { systems.forEach((systemId, system) -> influxClient.writeManagedSystem(system)); } catch (NullPointerException npe) { - log.warn("writeMetricsForManagedSystems() - NPE: " + npe.toString()); + log.warn("writeMetricsForManagedSystems() - NPE: " + npe.toString(), npe); } } @@ -185,7 +188,7 @@ class Insights { try { partitions.forEach((partitionId, partition) -> influxClient.writeLogicalPartition(partition)); } catch (NullPointerException npe) { - log.warn("writeMetricsForLogicalPartitions() - NPE: " + npe.toString()); + log.warn("writeMetricsForLogicalPartitions() - NPE: " + npe.toString(), npe); } } @@ -194,7 +197,7 @@ class Insights { try { systems.forEach((systemId, system) -> influxClient.writeSystemEnergy(system.energy)); } catch (NullPointerException npe) { - log.warn("writeMetricsForSystemEnergy() - NPE: " + npe.toString()); + log.warn("writeMetricsForSystemEnergy() - NPE: " + npe.toString(), npe); } } @@ -212,6 +215,7 @@ class Insights { Runtime.getRuntime().addShutdownHook(shutdownHook); do { + Instant start = Instant.now(); try { getMetricsForSystems(); getMetricsForPartitions(); @@ -222,18 +226,23 @@ class Insights { writeMetricsForSystemEnergy(); influxClient.writeBatchPoints(); - // Refresh HMC's - if (executions > configuration.rescan) { - executions = 0; - discover(); - } } catch (Exception e) { log.error("run()", e); } - executions++; - //noinspection BusyWait - sleep(configuration.refresh * 1000); + // Refresh + if (++executions > configuration.rescan) { + executions = 0; + discover(); + } + + Instant end = Instant.now(); + long timeSpend = Duration.between(start, end).getSeconds(); + log.debug("run() - duration sec: " + timeSpend); + if(timeSpend < configuration.refresh) { + //noinspection BusyWait + sleep((configuration.refresh - timeSpend) * 1000); + } } while (keepRunning.get()); diff --git a/src/main/java/biz/nellemann/hmci/LogicalPartition.java b/src/main/java/biz/nellemann/hmci/LogicalPartition.java index 9710bf2..4ae3f5f 100644 --- a/src/main/java/biz/nellemann/hmci/LogicalPartition.java +++ b/src/main/java/biz/nellemann/hmci/LogicalPartition.java @@ -50,12 +50,12 @@ class LogicalPartition extends MetaSystem { List list = new ArrayList<>(); - Map tagsMap = new HashMap(); + Map tagsMap = new HashMap<>(); tagsMap.put("system", system.name); tagsMap.put("partition", name); log.debug("getAffinityScore() - tags: " + tagsMap.toString()); - Map fieldsMap = new HashMap(); + Map fieldsMap = new HashMap<>(); fieldsMap.put("affinityScore", metrics.systemUtil.sample.lparsUtil.affinityScore); log.debug("getAffinityScore() - fields: " + fieldsMap.toString()); @@ -68,12 +68,12 @@ class LogicalPartition extends MetaSystem { List list = new ArrayList<>(); - Map tagsMap = new HashMap(); + Map tagsMap = new HashMap<>(); tagsMap.put("system", system.name); tagsMap.put("partition", name); log.debug("getMemoryMetrics() - tags: " + tagsMap.toString()); - Map fieldsMap = new HashMap(); + Map fieldsMap = new HashMap<>(); fieldsMap.put("logicalMem", metrics.systemUtil.sample.lparsUtil.memory.logicalMem); fieldsMap.put("backedPhysicalMem", metrics.systemUtil.sample.lparsUtil.memory.backedPhysicalMem); log.debug("getMemoryMetrics() - fields: " + fieldsMap.toString()); @@ -87,12 +87,12 @@ class LogicalPartition extends MetaSystem { List list = new ArrayList<>(); - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", system.name); tagsMap.put("partition", name); log.debug("getProcessorMetrics() - tags: " + tagsMap.toString()); - HashMap fieldsMap = new HashMap(); + HashMap fieldsMap = new HashMap<>(); fieldsMap.put("utilizedProcUnits", metrics.systemUtil.sample.lparsUtil.processor.utilizedProcUnits); fieldsMap.put("maxVirtualProcessors", metrics.systemUtil.sample.lparsUtil.processor.maxVirtualProcessors); fieldsMap.put("currentVirtualProcessors", metrics.systemUtil.sample.lparsUtil.processor.currentVirtualProcessors); @@ -113,10 +113,13 @@ class LogicalPartition extends MetaSystem { List getVirtualEthernetAdapterMetrics() { + //List metricsList = getListObject(metrics.systemUtil.sample.lparsUtil.network.virtualEthernetAdapters); List list = new ArrayList<>(); + + //metricsList.forEach( adapter -> { metrics.systemUtil.sample.lparsUtil.network.virtualEthernetAdapters.forEach( adapter -> { - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", system.name); tagsMap.put("partition", name); tagsMap.put("sea", adapter.sharedEthernetAdapterId); @@ -125,7 +128,7 @@ class LogicalPartition extends MetaSystem { tagsMap.put("vswitchId", adapter.vswitchId.toString()); log.debug("getVirtualEthernetAdapterMetrics() - tags: " + tagsMap.toString()); - HashMap fieldsMap = new HashMap(); + HashMap fieldsMap = new HashMap<>(); fieldsMap.put("receivedPhysicalBytes", adapter.receivedPhysicalBytes); fieldsMap.put("sentPhysicalBytes", adapter.sentPhysicalBytes); fieldsMap.put("receivedBytes", adapter.receivedBytes); @@ -144,14 +147,14 @@ class LogicalPartition extends MetaSystem { List list = new ArrayList<>(); metrics.systemUtil.sample.lparsUtil.storage.virtualFiberChannelAdapters.forEach( adapter -> { - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", system.name); tagsMap.put("partition", name); tagsMap.put("viosId", adapter.viosId.toString()); tagsMap.put("wwpn", adapter.wwpn); log.debug("getVirtualFiberChannelAdaptersMetrics() - tags: " + tagsMap.toString()); - HashMap fieldsMap = new HashMap(); + HashMap fieldsMap = new HashMap<>(); fieldsMap.put("transmittedBytes", adapter.transmittedBytes.get(0)); fieldsMap.put("writeBytes", adapter.writeBytes.get(0)); fieldsMap.put("readBytes", adapter.readBytes.get(0)); diff --git a/src/main/java/biz/nellemann/hmci/ManagedSystem.java b/src/main/java/biz/nellemann/hmci/ManagedSystem.java index 5fcb90f..fbc5d4e 100644 --- a/src/main/java/biz/nellemann/hmci/ManagedSystem.java +++ b/src/main/java/biz/nellemann/hmci/ManagedSystem.java @@ -47,6 +47,7 @@ class ManagedSystem extends MetaSystem { this.energy = new SystemEnergy(this); } + @Override public String toString() { return String.format("[%s] %s (%s-%s %s)", id, name, type, model, serialNumber); } @@ -56,11 +57,11 @@ class ManagedSystem extends MetaSystem { List list = new ArrayList<>(); - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", name); log.debug("getMemoryMetrics() - tags: " + tagsMap.toString()); - Map fieldsMap = new HashMap(); + Map fieldsMap = new HashMap<>(); fieldsMap.put("totalMem", metrics.systemUtil.sample.serverUtil.memory.totalMem); fieldsMap.put("availableMem", metrics.systemUtil.sample.serverUtil.memory.availableMem); fieldsMap.put("configurableMem", metrics.systemUtil.sample.serverUtil.memory.configurableMem); @@ -77,11 +78,11 @@ class ManagedSystem extends MetaSystem { List list = new ArrayList<>(); - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", name); log.debug("getProcessorMetrics() - tags: " + tagsMap.toString()); - HashMap fieldsMap = new HashMap(); + HashMap fieldsMap = new HashMap<>(); fieldsMap.put("totalProcUnits", metrics.systemUtil.sample.serverUtil.processor.totalProcUnits); fieldsMap.put("utilizedProcUnits", metrics.systemUtil.sample.serverUtil.processor.utilizedProcUnits); fieldsMap.put("availableProcUnits", metrics.systemUtil.sample.serverUtil.processor.availableProcUnits); @@ -98,12 +99,12 @@ class ManagedSystem extends MetaSystem { List list = new ArrayList<>(); metrics.systemUtil.sample.serverUtil.sharedProcessorPool.forEach(adapter -> { - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", name); tagsMap.put("pool", adapter.name); log.debug("getSharedProcessorPools() - tags: " + tagsMap.toString()); - HashMap fieldsMap = new HashMap(); + HashMap fieldsMap = new HashMap<>(); fieldsMap.put("assignedProcUnits", adapter.assignedProcUnits); fieldsMap.put("availableProcUnits", adapter.availableProcUnits); log.debug("getSharedProcessorPools() - fields: " + fieldsMap.toString()); @@ -121,12 +122,12 @@ class ManagedSystem extends MetaSystem { List list = new ArrayList<>(); metrics.systemUtil.sample.viosUtil.forEach(vios -> { - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", name); tagsMap.put("vios", vios.name); log.debug("getViosMemoryMetrics() - tags: " + tagsMap.toString()); - HashMap fieldsMap = new HashMap(); + HashMap fieldsMap = new HashMap<>(); Number assignedMem = getNumberMetricObject(vios.memory.assignedMem); Number utilizedMem = getNumberMetricObject(vios.memory.utilizedMem); if(assignedMem != null) { @@ -154,12 +155,12 @@ class ManagedSystem extends MetaSystem { List list = new ArrayList<>(); metrics.systemUtil.sample.viosUtil.forEach(vios -> { - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", name); tagsMap.put("vios", vios.name); log.debug("getViosProcessorMetrics() - tags: " + tagsMap.toString()); - HashMap fieldsMap = new HashMap(); + HashMap fieldsMap = new HashMap<>(); fieldsMap.put("utilizedProcUnits", vios.processor.utilizedProcUnits); fieldsMap.put("maxVirtualProcessors", vios.processor.maxVirtualProcessors); fieldsMap.put("currentVirtualProcessors", vios.processor.currentVirtualProcessors); @@ -185,14 +186,14 @@ class ManagedSystem extends MetaSystem { vios.network.sharedAdapters.forEach(adapter -> { - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", name); tagsMap.put("type", adapter.type); tagsMap.put("vios", vios.name); tagsMap.put("device", adapter.physicalLocation); log.debug("getSystemSharedAdapters() - tags: " + tagsMap.toString()); - HashMap fieldsMap = new HashMap(); + HashMap fieldsMap = new HashMap<>(); fieldsMap.put("sentBytes", adapter.sentBytes); fieldsMap.put("receivedBytes", adapter.receivedBytes); fieldsMap.put("transferredBytes", adapter.transferredBytes); @@ -215,7 +216,7 @@ class ManagedSystem extends MetaSystem { vios.storage.fiberChannelAdapters.forEach( adapter -> { - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("id", adapter.id); tagsMap.put("system", name); tagsMap.put("wwpn", adapter.wwpn); @@ -223,7 +224,7 @@ class ManagedSystem extends MetaSystem { tagsMap.put("device", adapter.physicalLocation); log.debug("getSystemFiberChannelAdapters() - tags: " + tagsMap.toString()); - HashMap fieldsMap = new HashMap(); + HashMap fieldsMap = new HashMap<>(); fieldsMap.put("writeBytes", adapter.writeBytes); fieldsMap.put("readBytes", adapter.readBytes); fieldsMap.put("transmittedBytes", adapter.transmittedBytes); @@ -312,13 +313,13 @@ class ManagedSystem extends MetaSystem { vios.network.virtualEthernetAdapters.forEach( adapter -> { - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", name); tagsMap.put("vios", vios.name); tagsMap.put("device", adapter.physicalLocation); log.debug("getSystemGenericVirtualAdapters() - tags: " + tagsMap.toString()); - HashMap fieldsMap = new HashMap(); + HashMap fieldsMap = new HashMap<>(); fieldsMap.put("sentBytes", adapter.sentBytes); fieldsMap.put("receivedBytes", adapter.receivedBytes); log.debug("getSystemGenericVirtualAdapters() - fields: " + fieldsMap.toString()); diff --git a/src/main/java/biz/nellemann/hmci/Measurement.java b/src/main/java/biz/nellemann/hmci/Measurement.java index 2c63673..3b22441 100644 --- a/src/main/java/biz/nellemann/hmci/Measurement.java +++ b/src/main/java/biz/nellemann/hmci/Measurement.java @@ -1,3 +1,18 @@ +/* + * Copyright 2020 Mark Nellemann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package biz.nellemann.hmci; import java.util.Map; diff --git a/src/main/java/biz/nellemann/hmci/MetaSystem.java b/src/main/java/biz/nellemann/hmci/MetaSystem.java index 0fc4ec9..dff72f2 100644 --- a/src/main/java/biz/nellemann/hmci/MetaSystem.java +++ b/src/main/java/biz/nellemann/hmci/MetaSystem.java @@ -28,6 +28,8 @@ import java.math.BigDecimal; import java.time.Instant; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.List; abstract class MetaSystem { @@ -128,5 +130,18 @@ abstract class MetaSystem { } } + + static ArrayList getListObject(Object obj) { + ArrayList list; + try { + list = (ArrayList) obj; + } catch (NullPointerException npe) { + log.warn("getListObject()", npe); + list = new ArrayList(); + } + + return list; + } + } diff --git a/src/main/java/biz/nellemann/hmci/SystemEnergy.java b/src/main/java/biz/nellemann/hmci/SystemEnergy.java index 5e72c59..e5bda44 100644 --- a/src/main/java/biz/nellemann/hmci/SystemEnergy.java +++ b/src/main/java/biz/nellemann/hmci/SystemEnergy.java @@ -36,6 +36,7 @@ class SystemEnergy extends MetaSystem { } + @Override public String toString() { return system.name; } @@ -45,11 +46,11 @@ class SystemEnergy extends MetaSystem { List list = new ArrayList<>(); - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", system.name); log.debug("getPowerMetrics() - tags: " + tagsMap.toString()); - Map fieldsMap = new HashMap(); + Map fieldsMap = new HashMap<>(); fieldsMap.put("powerReading", metrics.systemUtil.sample.energyUtil.powerUtil.powerReading); log.debug("getPowerMetrics() - fields: " + fieldsMap.toString()); @@ -62,11 +63,11 @@ class SystemEnergy extends MetaSystem { List list = new ArrayList<>(); - HashMap tagsMap = new HashMap(); + HashMap tagsMap = new HashMap<>(); tagsMap.put("system", system.name); log.debug("getThermalMetrics() - tags: " + tagsMap.toString()); - Map fieldsMap = new HashMap(); + Map fieldsMap = new HashMap<>(); for(Temperature t : metrics.systemUtil.sample.energyUtil.thermalUtil.cpuTemperatures) { fieldsMap.put("cpuTemperature_" + t.entityInstance, t.temperatureReading); diff --git a/src/main/java/biz/nellemann/hmci/VersionProvider.java b/src/main/java/biz/nellemann/hmci/VersionProvider.java index dcd480f..9af9148 100644 --- a/src/main/java/biz/nellemann/hmci/VersionProvider.java +++ b/src/main/java/biz/nellemann/hmci/VersionProvider.java @@ -8,6 +8,7 @@ import java.util.jar.Manifest; class VersionProvider implements CommandLine.IVersionProvider { + @Override public String[] getVersion() throws IOException { Manifest manifest = new Manifest(getClass().getResourceAsStream("/META-INF/MANIFEST.MF")); diff --git a/src/main/java/biz/nellemann/hmci/pcm/FiberChannelAdapter.java b/src/main/java/biz/nellemann/hmci/pcm/FiberChannelAdapter.java index 77902b2..c772a81 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/FiberChannelAdapter.java +++ b/src/main/java/biz/nellemann/hmci/pcm/FiberChannelAdapter.java @@ -4,10 +4,10 @@ import com.serjltt.moshi.adapters.FirstElement; public class FiberChannelAdapter { - public String id; - public String wwpn; - public String physicalLocation; - public Integer numOfPorts; + public String id = ""; + public String wwpn = ""; + public String physicalLocation = ""; + public Integer numOfPorts = 0; @FirstElement public Number numOfReads; diff --git a/src/main/java/biz/nellemann/hmci/pcm/GenericAdapter.java b/src/main/java/biz/nellemann/hmci/pcm/GenericAdapter.java index 382512e..49fec9f 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/GenericAdapter.java +++ b/src/main/java/biz/nellemann/hmci/pcm/GenericAdapter.java @@ -1,17 +1,18 @@ package biz.nellemann.hmci.pcm; +import java.util.ArrayList; import java.util.List; public class GenericAdapter { - public String id; - public String type; - public String physicalLocation; - public List receivedPackets; - public List sentPackets; - public List droppedPackets; - public List sentBytes; - public List receivedBytes; - public List transferredBytes; + public String id = ""; + public String type = ""; + public String physicalLocation = ""; + public List receivedPackets = new ArrayList<>(); + public List sentPackets = new ArrayList<>(); + public List droppedPackets = new ArrayList<>(); + public List sentBytes = new ArrayList<>(); + public List receivedBytes = new ArrayList<>(); + public List transferredBytes = new ArrayList<>(); } diff --git a/src/main/java/biz/nellemann/hmci/pcm/GenericPhysicalAdapters.java b/src/main/java/biz/nellemann/hmci/pcm/GenericPhysicalAdapters.java index a3766f3..be4a3b9 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/GenericPhysicalAdapters.java +++ b/src/main/java/biz/nellemann/hmci/pcm/GenericPhysicalAdapters.java @@ -4,9 +4,9 @@ import com.serjltt.moshi.adapters.FirstElement; public class GenericPhysicalAdapters { - public String id; - public String type; - public String physicalLocation; + public String id = ""; + public String type = ""; + public String physicalLocation = ""; @FirstElement public Number numOfReads; diff --git a/src/main/java/biz/nellemann/hmci/pcm/GenericVirtualAdapter.java b/src/main/java/biz/nellemann/hmci/pcm/GenericVirtualAdapter.java index 9fe11d6..741f093 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/GenericVirtualAdapter.java +++ b/src/main/java/biz/nellemann/hmci/pcm/GenericVirtualAdapter.java @@ -5,10 +5,10 @@ import com.serjltt.moshi.adapters.FirstElement; public class GenericVirtualAdapter { - public String id; - public String type; - public Integer viosId; - public String physicalLocation; + public String id = ""; + public String type = ""; + public Integer viosId = 0; + public String physicalLocation = ""; @FirstElement public Number numOfReads; diff --git a/src/main/java/biz/nellemann/hmci/pcm/LparProcessor.java b/src/main/java/biz/nellemann/hmci/pcm/LparProcessor.java index 5ed252a..ce1a1ae 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/LparProcessor.java +++ b/src/main/java/biz/nellemann/hmci/pcm/LparProcessor.java @@ -4,9 +4,9 @@ import com.serjltt.moshi.adapters.FirstElement; public class LparProcessor { - public Integer poolId; - public Integer weight; - public String mode; + public Integer poolId = 0; + public Integer weight = 0; + public String mode = ""; @FirstElement public Number maxVirtualProcessors; diff --git a/src/main/java/biz/nellemann/hmci/pcm/LparUtil.java b/src/main/java/biz/nellemann/hmci/pcm/LparUtil.java index 9e2f918..c50e730 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/LparUtil.java +++ b/src/main/java/biz/nellemann/hmci/pcm/LparUtil.java @@ -2,16 +2,16 @@ package biz.nellemann.hmci.pcm; public class LparUtil { - public Integer id; - public String uuid; - public String name; - public String state; - public String type; - public String osType; - public Number affinityScore; + public Integer id = 0; + public String uuid = ""; + public String name = ""; + public String state = ""; + public String type = ""; + public String osType = ""; + public Number affinityScore = 0.0f; - public LparMemory memory; - public LparProcessor processor; + public LparMemory memory = new LparMemory(); + public LparProcessor processor = new LparProcessor(); public Network network = new Network(); public Storage storage = new Storage(); diff --git a/src/main/java/biz/nellemann/hmci/pcm/PcmData.java b/src/main/java/biz/nellemann/hmci/pcm/PcmData.java index b3d6d04..345d558 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/PcmData.java +++ b/src/main/java/biz/nellemann/hmci/pcm/PcmData.java @@ -2,6 +2,6 @@ package biz.nellemann.hmci.pcm; public class PcmData { - public SystemUtil systemUtil; + public SystemUtil systemUtil = new SystemUtil(); } diff --git a/src/main/java/biz/nellemann/hmci/pcm/PhysicalProcessorPool.java b/src/main/java/biz/nellemann/hmci/pcm/PhysicalProcessorPool.java index 09082cd..9f63bea 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/PhysicalProcessorPool.java +++ b/src/main/java/biz/nellemann/hmci/pcm/PhysicalProcessorPool.java @@ -1,13 +1,14 @@ package biz.nellemann.hmci.pcm; +import java.util.ArrayList; import java.util.List; public class PhysicalProcessorPool { - public List assignedProcUnits; - public List utilizedProcUnits; - public List availableProcUnits; - public List configuredProcUnits; - public List borrowedProcUnits; + public List assignedProcUnits = new ArrayList<>(); + public List utilizedProcUnits = new ArrayList<>(); + public List availableProcUnits = new ArrayList<>(); + public List configuredProcUnits = new ArrayList<>(); + public List borrowedProcUnits = new ArrayList<>(); } diff --git a/src/main/java/biz/nellemann/hmci/pcm/PowerUtil.java b/src/main/java/biz/nellemann/hmci/pcm/PowerUtil.java index 47b094f..86261e1 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/PowerUtil.java +++ b/src/main/java/biz/nellemann/hmci/pcm/PowerUtil.java @@ -1,3 +1,4 @@ + package biz.nellemann.hmci.pcm; import com.serjltt.moshi.adapters.FirstElement; diff --git a/src/main/java/biz/nellemann/hmci/pcm/SampleInfo.java b/src/main/java/biz/nellemann/hmci/pcm/SampleInfo.java index 2665d51..80217c8 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/SampleInfo.java +++ b/src/main/java/biz/nellemann/hmci/pcm/SampleInfo.java @@ -2,7 +2,7 @@ package biz.nellemann.hmci.pcm; public class SampleInfo { - public String timeStamp; - public Integer status; + public String timeStamp = ""; + public Integer status = 0; } diff --git a/src/main/java/biz/nellemann/hmci/pcm/ServerMemory.java b/src/main/java/biz/nellemann/hmci/pcm/ServerMemory.java index cc78c83..365ded0 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/ServerMemory.java +++ b/src/main/java/biz/nellemann/hmci/pcm/ServerMemory.java @@ -5,15 +5,15 @@ import com.serjltt.moshi.adapters.FirstElement; public class ServerMemory { @FirstElement - public Number totalMem; + public Number totalMem = 0; @FirstElement - public Number availableMem; + public Number availableMem = 0; @FirstElement - public Number configurableMem; + public Number configurableMem = 0; @FirstElement - public Number assignedMemToLpars; + public Number assignedMemToLpars = 0; } diff --git a/src/main/java/biz/nellemann/hmci/pcm/ServerProcessor.java b/src/main/java/biz/nellemann/hmci/pcm/ServerProcessor.java index 47ffe57..6ed9fd0 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/ServerProcessor.java +++ b/src/main/java/biz/nellemann/hmci/pcm/ServerProcessor.java @@ -5,15 +5,15 @@ import com.serjltt.moshi.adapters.FirstElement; public class ServerProcessor { @FirstElement - public Number totalProcUnits; + public Number totalProcUnits = 0; @FirstElement - public Number utilizedProcUnits; + public Number utilizedProcUnits = 0; @FirstElement - public Number availableProcUnits; + public Number availableProcUnits = 0; @FirstElement - public Number configurableProcUnits; + public Number configurableProcUnits = 0; } diff --git a/src/main/java/biz/nellemann/hmci/pcm/ServerUtil.java b/src/main/java/biz/nellemann/hmci/pcm/ServerUtil.java index ea6778f..cf066d5 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/ServerUtil.java +++ b/src/main/java/biz/nellemann/hmci/pcm/ServerUtil.java @@ -1,12 +1,13 @@ package biz.nellemann.hmci.pcm; +import java.util.ArrayList; import java.util.List; public class ServerUtil { - public ServerProcessor processor; - public ServerMemory memory; - public PhysicalProcessorPool physicalProcessorPool; - public List sharedProcessorPool; + public ServerProcessor processor = new ServerProcessor(); + public ServerMemory memory = new ServerMemory(); + public PhysicalProcessorPool physicalProcessorPool = new PhysicalProcessorPool(); + public List sharedProcessorPool = new ArrayList<>(); } diff --git a/src/main/java/biz/nellemann/hmci/pcm/SharedAdapter.java b/src/main/java/biz/nellemann/hmci/pcm/SharedAdapter.java index 5a481e9..19ba76d 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/SharedAdapter.java +++ b/src/main/java/biz/nellemann/hmci/pcm/SharedAdapter.java @@ -4,29 +4,29 @@ import com.serjltt.moshi.adapters.FirstElement; public class SharedAdapter { - public String id; - public String type; - public String physicalLocation; + public String id = ""; + public String type = ""; + public String physicalLocation = ""; @FirstElement - public Number receivedPackets; + public Number receivedPackets = 0; @FirstElement - public Number sentPackets; + public Number sentPackets = 0; @FirstElement - public Number droppedPackets; + public Number droppedPackets = 0; @FirstElement - public Number sentBytes; + public Number sentBytes = 0; @FirstElement - public Number receivedBytes; + public Number receivedBytes = 0; @FirstElement - public Number transferredBytes; + public Number transferredBytes = 0; @FirstElement - public String bridgedAdapters; + public String bridgedAdapters = ""; } diff --git a/src/main/java/biz/nellemann/hmci/pcm/SharedProcessorPool.java b/src/main/java/biz/nellemann/hmci/pcm/SharedProcessorPool.java index 6947081..7c7e34f 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/SharedProcessorPool.java +++ b/src/main/java/biz/nellemann/hmci/pcm/SharedProcessorPool.java @@ -4,22 +4,22 @@ import com.serjltt.moshi.adapters.FirstElement; public class SharedProcessorPool { - public String id; - public String name; + public String id = ""; + public String name = ""; @FirstElement - public Number assignedProcUnits; + public Number assignedProcUnits = 0; @FirstElement - public Number utilizedProcUnits; + public Number utilizedProcUnits = 0; @FirstElement - public Number availableProcUnits; + public Number availableProcUnits = 0; @FirstElement - public Number configuredProcUnits; + public Number configuredProcUnits = 0; @FirstElement - public Number borrowedProcUnits; + public Number borrowedProcUnits = 0; } diff --git a/src/main/java/biz/nellemann/hmci/pcm/Temperature.java b/src/main/java/biz/nellemann/hmci/pcm/Temperature.java index bc0af45..70bf55c 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/Temperature.java +++ b/src/main/java/biz/nellemann/hmci/pcm/Temperature.java @@ -4,10 +4,10 @@ import com.serjltt.moshi.adapters.FirstElement; public class Temperature { - public String entityId; - public String entityInstance; + public String entityId = ""; + public String entityInstance = ""; @FirstElement - public Float temperatureReading; + public Float temperatureReading = 0.0f; } diff --git a/src/main/java/biz/nellemann/hmci/pcm/UtilInfo.java b/src/main/java/biz/nellemann/hmci/pcm/UtilInfo.java index 8a3271a..a5e44b3 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/UtilInfo.java +++ b/src/main/java/biz/nellemann/hmci/pcm/UtilInfo.java @@ -1,17 +1,18 @@ package biz.nellemann.hmci.pcm; +import java.util.ArrayList; import java.util.List; public class UtilInfo { - public String version; - public String metricType; - public Integer frequency; - public String startTimeStamp; - public String endTimeStamp; - public String mtms; - public String name; - public String uuid; - public List metricArrayOrder; + public String version = ""; + public String metricType = ""; + public Integer frequency = 0; + public String startTimeStamp = ""; + public String endTimeStamp = ""; + public String mtms = ""; + public String name = ""; + public String uuid = ""; + public List metricArrayOrder = new ArrayList<>(); } diff --git a/src/main/java/biz/nellemann/hmci/pcm/UtilSample.java b/src/main/java/biz/nellemann/hmci/pcm/UtilSample.java index 9d454f4..fea35c2 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/UtilSample.java +++ b/src/main/java/biz/nellemann/hmci/pcm/UtilSample.java @@ -7,23 +7,13 @@ import java.util.List; public class UtilSample { - public String sampleType; - public SampleInfo sampleInfo; - public ServerUtil serverUtil; + public String sampleType = ""; + public SampleInfo sampleInfo = new SampleInfo(); + public ServerUtil serverUtil = new ServerUtil(); public EnergyUtil energyUtil = new EnergyUtil(); public List viosUtil = new ArrayList<>(); @FirstElement - public LparUtil lparsUtil; - - /* - public LparUtil getLparsUtil() { - if(lparsUtil == null || lparsUtil.isEmpty()) { - return new LparUtil(); - } else { - return lparsUtil.get(0); - } - }*/ - + public LparUtil lparsUtil = new LparUtil(); } diff --git a/src/main/java/biz/nellemann/hmci/pcm/ViosMemory.java b/src/main/java/biz/nellemann/hmci/pcm/ViosMemory.java index 8643321..66f7845 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/ViosMemory.java +++ b/src/main/java/biz/nellemann/hmci/pcm/ViosMemory.java @@ -5,9 +5,9 @@ import com.serjltt.moshi.adapters.FirstElement; public class ViosMemory { @FirstElement - public Number assignedMem; + public Number assignedMem = 0; @FirstElement - public Number utilizedMem; + public Number utilizedMem = 0; } diff --git a/src/main/java/biz/nellemann/hmci/pcm/ViosUtil.java b/src/main/java/biz/nellemann/hmci/pcm/ViosUtil.java index 178b39e..ecccba4 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/ViosUtil.java +++ b/src/main/java/biz/nellemann/hmci/pcm/ViosUtil.java @@ -2,15 +2,15 @@ package biz.nellemann.hmci.pcm; public class ViosUtil { - public String id; - public String uuid; - public String name; - public String state; - public Integer affinityScore; + public String id = ""; + public String uuid = ""; + public String name = ""; + public String state = ""; + public Integer affinityScore = 0; - public ViosMemory memory; - public LparProcessor processor; - public Network network; - public Storage storage; + public ViosMemory memory = new ViosMemory(); + public LparProcessor processor = new LparProcessor(); + public Network network = new Network(); + public Storage storage = new Storage(); } diff --git a/src/main/java/biz/nellemann/hmci/pcm/VirtualEthernetAdapter.java b/src/main/java/biz/nellemann/hmci/pcm/VirtualEthernetAdapter.java index 87333d8..773d2f9 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/VirtualEthernetAdapter.java +++ b/src/main/java/biz/nellemann/hmci/pcm/VirtualEthernetAdapter.java @@ -2,49 +2,50 @@ package biz.nellemann.hmci.pcm; import com.serjltt.moshi.adapters.FirstElement; + public class VirtualEthernetAdapter { - public String physicalLocation; - public Integer vlanId; - public Integer vswitchId; - public Boolean isPortVlanId; - public Integer viosId; - public String sharedEthernetAdapterId; + public String physicalLocation = ""; + public Integer vlanId = 0; + public Integer vswitchId = 0; + public Boolean isPortVlanId = false; + public Integer viosId = 0; + public String sharedEthernetAdapterId = ""; @FirstElement - public Number receivedPackets; + public Number receivedPackets = 0; @FirstElement - public Number sentPackets; + public Number sentPackets = 0; @FirstElement - public Number droppedPackets; + public Number droppedPackets = 0; @FirstElement - public Number sentBytes; + public Number sentBytes = 0; @FirstElement - public Number receivedBytes; + public Number receivedBytes = 0; @FirstElement - public Number receivedPhysicalPackets; + public Number receivedPhysicalPackets = 0; @FirstElement - public Number sentPhysicalPackets; + public Number sentPhysicalPackets = 0; @FirstElement - public Number droppedPhysicalPackets; + public Number droppedPhysicalPackets = 0; @FirstElement - public Number sentPhysicalBytes; + public Number sentPhysicalBytes = 0; @FirstElement - public Number receivedPhysicalBytes; + public Number receivedPhysicalBytes = 0; @FirstElement - public Number transferredBytes; + public Number transferredBytes = 0; @FirstElement - public Number transferredPhysicalBytes; + public Number transferredPhysicalBytes = 0; } diff --git a/src/main/java/biz/nellemann/hmci/pcm/VirtualFiberChannelAdapter.java b/src/main/java/biz/nellemann/hmci/pcm/VirtualFiberChannelAdapter.java index 3a3066c..fd9401d 100644 --- a/src/main/java/biz/nellemann/hmci/pcm/VirtualFiberChannelAdapter.java +++ b/src/main/java/biz/nellemann/hmci/pcm/VirtualFiberChannelAdapter.java @@ -1,19 +1,20 @@ package biz.nellemann.hmci.pcm; +import java.util.ArrayList; import java.util.List; public class VirtualFiberChannelAdapter { - public String wwpn; - public String wwpn2; - public String physicalLocation; - public String physicalPortWWPN; - public Integer viosId; - public List numOfReads; - public List numOfWrites; - public List readBytes; - public List writeBytes; - public List runningSpeed; - public List transmittedBytes; + public String wwpn = ""; + public String wwpn2 = ""; + public String physicalLocation = ""; + public String physicalPortWWPN = ""; + public Integer viosId = 0; + public List numOfReads = new ArrayList<>(); + public List numOfWrites = new ArrayList<>(); + public List readBytes = new ArrayList<>(); + public List writeBytes = new ArrayList<>(); + public List runningSpeed = new ArrayList<>(); + public List transmittedBytes = new ArrayList<>(); } diff --git a/src/main/resources/simplelogger.properties b/src/main/resources/simplelogger.properties index a807e10..d13c7ee 100644 --- a/src/main/resources/simplelogger.properties +++ b/src/main/resources/simplelogger.properties @@ -3,3 +3,4 @@ org.slf4j.simpleLogger.showDateTime=true org.slf4j.simpleLogger.showShortLogName=true org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss.SSS org.slf4j.simpleLogger.levelInBrackets=true +#org.slf4j.simpleLogger.defaultLogLevel=debug From 5b4f853e24e5529879f09f46a014d868b6a787cc Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Thu, 14 Jan 2021 13:51:18 +0100 Subject: [PATCH 2/4] Move each HMC into it's own thread. --- build.gradle | 2 +- doc/hmci.toml | 15 +- gradle.properties | 2 +- .../java/biz/nellemann/hmci/Application.java | 26 ++- .../biz/nellemann/hmci/Configuration.java | 47 ++-- .../hmci/{Insights.java => HmcInstance.java} | 208 +++++++++--------- .../{HmcClient.java => HmcRestClient.java} | 47 ++-- .../java/biz/nellemann/hmci/InfluxClient.java | 6 +- .../biz/nellemann/hmci/LogicalPartition.java | 5 +- .../biz/nellemann/hmci/ManagedSystem.java | 5 +- .../java/biz/nellemann/hmci/MetaSystem.java | 18 +- ...ntTest.groovy => HmcRestClientTest.groovy} | 9 +- .../nellemann/hmci/InfluxClientTest.groovy | 6 +- .../biz/nellemann/hmci/InsightsTest.groovy | 10 - .../hmci/LogicalPartitionTest.groovy | 10 +- .../nellemann/hmci/ManagedSystemTest.groovy | 14 +- .../biz/nellemann/hmci/MetaSystemTest.groovy | 2 +- .../nellemann/hmci/SystemEnergyTest.groovy | 2 +- 18 files changed, 214 insertions(+), 220 deletions(-) rename src/main/java/biz/nellemann/hmci/{Insights.java => HmcInstance.java} (54%) rename src/main/java/biz/nellemann/hmci/{HmcClient.java => HmcRestClient.java} (94%) rename src/test/groovy/biz/nellemann/hmci/{HmcClientTest.groovy => HmcRestClientTest.groovy} (88%) delete mode 100644 src/test/groovy/biz/nellemann/hmci/InsightsTest.groovy diff --git a/build.gradle b/build.gradle index f0bdce6..a4a02b7 100644 --- a/build.gradle +++ b/build.gradle @@ -78,7 +78,7 @@ buildDeb { } jacoco { - toolVersion = "0.8.5" + toolVersion = "0.8.6" } jacocoTestReport { diff --git a/doc/hmci.toml b/doc/hmci.toml index da9e502..bc782dc 100644 --- a/doc/hmci.toml +++ b/doc/hmci.toml @@ -1,17 +1,17 @@ # HMCi Configuration # How often to query HMC's for data - in seconds -hmci.refresh = 30 +hmci.update = 25 -# Rescan HMC's for new systems and partitions - every x refresh -hmci.rescan = 60 +# Rescan HMC's for new systems and partitions - every x update +hmci.rescan = 90 # InfluxDB to save metrics [influx] -url = "http://localhost:8086" -username = "root" -password = "" -database = "hmci" + url = "http://localhost:8086" + username = "root" + password = "" + database = "hmci" # One or more HMC's to query for data and metrics [hmc] @@ -23,6 +23,7 @@ database = "hmci" password = "hmcihmci" unsafe = true # Ignore SSL cert. errors + # Example #[hmc.site2] #url = "https://10.10.20.20:12443" diff --git a/gradle.properties b/gradle.properties index 280a682..aaa63c4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ id = hmci group = biz.nellemann.hmci -version = 1.0.2 +version = 1.1.0 diff --git a/src/main/java/biz/nellemann/hmci/Application.java b/src/main/java/biz/nellemann/hmci/Application.java index ad09492..81602e2 100644 --- a/src/main/java/biz/nellemann/hmci/Application.java +++ b/src/main/java/biz/nellemann/hmci/Application.java @@ -23,6 +23,8 @@ import picocli.CommandLine.Command; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Callable; @Command(name = "hmci", @@ -45,18 +47,34 @@ public class Application implements Callable { @Override public Integer call() throws IOException { + Configuration configuration; + InfluxClient influxClient; + List threadList = new ArrayList<>(); + File file = new File(configurationFile); if(!file.exists()) { System.err.println("Error - No configuration file found at: " + file.toString()); return -1; } - Configuration configuration = new Configuration(configurationFile); - Insights insights = new Insights(configuration); try { - insights.run(); - } catch (InterruptedException e) { + configuration = new Configuration(configurationFile); + influxClient = new InfluxClient(configuration.getInflux()); + influxClient.login(); + + for(Configuration.HmcObject configHmc : configuration.getHmc()) { + Thread t = new Thread(new HmcInstance(configHmc, influxClient)); + threadList.add(t); + t.start(); + } + + for (Thread thread : threadList) { + thread.join(); + } + + } catch (InterruptedException | RuntimeException e) { log.error(e.getMessage()); + return 1; } return 0; diff --git a/src/main/java/biz/nellemann/hmci/Configuration.java b/src/main/java/biz/nellemann/hmci/Configuration.java index baa4853..bf18ff0 100644 --- a/src/main/java/biz/nellemann/hmci/Configuration.java +++ b/src/main/java/biz/nellemann/hmci/Configuration.java @@ -14,10 +14,11 @@ public final class Configuration { //private final static Logger log = LoggerFactory.getLogger(Configuration.class); - final public Long refresh; - final public Long rescan; - final public InfluxObject influx; - final public List hmc; + final private Long update; + final private Long rescan; + + final private InfluxObject influx; + final private List hmcList; Configuration(String configurationFile) throws IOException { @@ -25,27 +26,25 @@ public final class Configuration { TomlParseResult result = Toml.parse(source); result.errors().forEach(error -> System.err.println(error.toString())); - if(result.contains("hmci.refresh")) { - refresh = result.getLong("hmci.refresh"); + if(result.contains("hmci.update")) { + update = result.getLong("hmci.update"); } else { - refresh = 30L; + update = 30L; } - System.err.println("Refresh: " + refresh); if(result.contains("hmci.rescan")) { rescan = result.getLong("hmci.rescan"); } else { rescan = 60L; } - System.err.println("Rescan: " + refresh); - hmc = getHmc(result); - influx = getInflux(result); + hmcList = parseConfigurationForHmc(result); + influx = parseConfigurationForInflux(result); } - List getHmc(TomlParseResult result) { + private List parseConfigurationForHmc(TomlParseResult result) { ArrayList list = new ArrayList<>(); @@ -58,6 +57,8 @@ public final class Configuration { HmcObject c = new HmcObject(); c.name = key; + c.update = update; + c.rescan = rescan; if(hmcTable.contains(key+".url")) { c.url = hmcTable.getString(key+".url"); @@ -85,7 +86,7 @@ public final class Configuration { } - InfluxObject getInflux(TomlParseResult result) { + private InfluxObject parseConfigurationForInflux(TomlParseResult result) { InfluxObject c = new InfluxObject(); @@ -113,7 +114,17 @@ public final class Configuration { return c; } + + public List getHmc() { + return hmcList; + } + + + public InfluxObject getInflux() { + return influx; + } + static class InfluxObject { String url = "http://localhost:8086"; @@ -136,7 +147,7 @@ public final class Configuration { return validated; } - // TODO: Fixme + // TODO: Implement validation void validate() { validated = true; } @@ -155,16 +166,20 @@ public final class Configuration { String username; String password; Boolean unsafe = false; + Long update = 30L; + Long rescan = 60L; private boolean validated = false; HmcObject() { } - HmcObject(String name, String url, String username, String password, Boolean unsafe) { + HmcObject(String name, String url, String username, String password, Boolean unsafe, Long update, Long rescan) { this.url = url; this.username = username; this.password = password; this.unsafe = unsafe; + this.update = update; + this.rescan = rescan; } @@ -172,7 +187,7 @@ public final class Configuration { return validated; } - // TODO: Fixme + // TODO: Implement validation void validate() { validated = true; } diff --git a/src/main/java/biz/nellemann/hmci/Insights.java b/src/main/java/biz/nellemann/hmci/HmcInstance.java similarity index 54% rename from src/main/java/biz/nellemann/hmci/Insights.java rename to src/main/java/biz/nellemann/hmci/HmcInstance.java index 708eaa4..aad3d67 100644 --- a/src/main/java/biz/nellemann/hmci/Insights.java +++ b/src/main/java/biz/nellemann/hmci/HmcInstance.java @@ -15,6 +15,7 @@ */ package biz.nellemann.hmci; +import biz.nellemann.hmci.Configuration.HmcObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,79 +25,122 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import static java.lang.Thread.*; +import static java.lang.Thread.sleep; -class Insights { +class HmcInstance implements Runnable { - private final static Logger log = LoggerFactory.getLogger(Insights.class); + private final static Logger log = LoggerFactory.getLogger(HmcInstance.class); - final Configuration configuration; + private final String hmcId; + private final Long updateValue; + private final Long rescanValue; + private final Map systems = new HashMap<>(); + private final Map partitions = new HashMap<>(); - InfluxClient influxClient; - final Map hmcClients = new HashMap<>(); - final Map systems = new HashMap<>(); - final Map partitions = new HashMap<>(); + private final HmcRestClient hmcRestClient; + private final InfluxClient influxClient; + private final AtomicBoolean keepRunning = new AtomicBoolean(true); - Insights(Configuration configuration) { - this.configuration = configuration; - try { - influxClient = new InfluxClient(configuration.influx); - influxClient.login(); - } catch (Exception e) { - System.exit(1); - } + HmcInstance(HmcObject configHmc, InfluxClient influxClient) { + this.hmcId = configHmc.name; + this.updateValue = configHmc.update; + this.rescanValue = configHmc.rescan; + this.influxClient = influxClient; + hmcRestClient = new HmcRestClient(configHmc.url, configHmc.username, configHmc.password, configHmc.unsafe); + log.debug(String.format("HmcInstance() - id: %s, update: %s, refresh %s", hmcId, updateValue, rescanValue)); + } + + + @Override + public String toString() { + return hmcId; + } + + + @Override + public void run() { + + log.debug("run() - " + hmcId); + int executions = 0; - // Initial scan discover(); + + do { + Instant instantStart = Instant.now(); + try { + getMetricsForSystems(); + getMetricsForPartitions(); + getMetricsForEnergy(); + + writeMetricsForManagedSystems(); + writeMetricsForLogicalPartitions(); + writeMetricsForSystemEnergy(); + influxClient.writeBatchPoints(); + + // Refresh + if (++executions > rescanValue) { + executions = 0; + discover(); + } + + } catch (Exception e) { + log.error("run()", e); + } + + Instant instantEnd = Instant.now(); + long timeSpend = Duration.between(instantStart, instantEnd).getSeconds(); + log.debug("run() - duration sec: " + timeSpend); + if(timeSpend < updateValue) { + try { + log.debug("run() - sleep sec: " + (updateValue - timeSpend)); + //noinspection BusyWait + sleep((updateValue - timeSpend) * 1000); + } catch (InterruptedException e) { + log.error("run() - sleep interrupted", e); + } + } + + } while (keepRunning.get()); + } void discover() { - configuration.hmc.forEach( configHmc -> { - if(!hmcClients.containsKey(configHmc.name)) { - HmcClient hmcClient = new HmcClient(configHmc); - hmcClients.put(configHmc.name, hmcClient); - log.info("discover() - Adding HMC: " + hmcClient); - } - }); + log.debug("discover() - " + hmcId); - hmcClients.forEach(( hmcId, hmcClient) -> { + try { + hmcRestClient.logoff(); + hmcRestClient.login(); + hmcRestClient.getManagedSystems().forEach((systemId, system) -> { - try { - hmcClient.logoff(); - hmcClient.login(); - hmcClient.getManagedSystems().forEach((systemId, system) -> { + // Add to list of known systems + if(!systems.containsKey(systemId)) { + systems.put(systemId, system); + log.info("discover() - Found ManagedSystem: " + system + " @" + hmcId); + } - // Add to list of known systems - if(!systems.containsKey(systemId)) { - systems.put(systemId, system); - log.info(hmcId + " discover() - Found ManagedSystem: " + system); - } + // Get LPAR's for this system + try { + hmcRestClient.getLogicalPartitionsForManagedSystem(system).forEach((partitionId, partition) -> { - // Get LPAR's for this system - try { - hmcClient.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); + } - // Add to list of known partitions - if(!partitions.containsKey(partitionId)) { - partitions.put(partitionId, partition); - log.info(hmcId + " discover() - Found LogicalPartition: " + partition); - } + }); + } catch (Exception e) { + log.error("discover() - getLogicalPartitions", e); + } - }); - } catch (Exception e) { - log.error(hmcId + " discover() - getLogicalPartitions", e); - } + }); - }); - - } catch(Exception e) { - log.error(hmcId + " discover() - getManagedSystems: " + e.getMessage()); - } - - }); + } catch(Exception e) { + log.error("discover() - getManagedSystems: " + e.getMessage()); + } } @@ -105,12 +149,10 @@ class Insights { systems.forEach((systemId, system) -> { - HmcClient hmcClient = hmcClients.get(system.hmcId); - // Get and process metrics for this system String tmpJsonString = null; try { - tmpJsonString = hmcClient.getPcmDataForManagedSystem(system); + tmpJsonString = hmcRestClient.getPcmDataForManagedSystem(system); } catch (Exception e) { log.error("getMetricsForSystems()", e); } @@ -131,12 +173,10 @@ class Insights { // Get LPAR's for this system partitions.forEach((partitionId, partition) -> { - HmcClient hmcClient = hmcClients.get(partition.system.hmcId); - // Get and process metrics for this partition String tmpJsonString2 = null; try { - tmpJsonString2 = hmcClient.getPcmDataForLogicalPartition(partition); + tmpJsonString2 = hmcRestClient.getPcmDataForLogicalPartition(partition); } catch (Exception e) { log.error("getMetricsForPartitions() - getPcmDataForLogicalPartition", e); } @@ -156,12 +196,10 @@ class Insights { systems.forEach((systemId, system) -> { - HmcClient hmcClient = hmcClients.get(system.hmcId); - // Get and process metrics for this system String tmpJsonString = null; try { - tmpJsonString = hmcClient.getPcmDataForEnergy(system.energy); + tmpJsonString = hmcRestClient.getPcmDataForEnergy(system.energy); } catch (Exception e) { log.error("getMetricsForEnergy()", e); } @@ -202,50 +240,4 @@ class Insights { } - void run() throws InterruptedException { - - log.debug("run()"); - int executions = 0; - AtomicBoolean keepRunning = new AtomicBoolean(true); - - Thread shutdownHook = new Thread(() -> { - keepRunning.set(false); - System.out.println("Stopping HMCi, please wait ..."); - }); - Runtime.getRuntime().addShutdownHook(shutdownHook); - - do { - Instant start = Instant.now(); - try { - getMetricsForSystems(); - getMetricsForPartitions(); - getMetricsForEnergy(); - - writeMetricsForManagedSystems(); - writeMetricsForLogicalPartitions(); - writeMetricsForSystemEnergy(); - influxClient.writeBatchPoints(); - - } catch (Exception e) { - log.error("run()", e); - } - - // Refresh - if (++executions > configuration.rescan) { - executions = 0; - discover(); - } - - Instant end = Instant.now(); - long timeSpend = Duration.between(start, end).getSeconds(); - log.debug("run() - duration sec: " + timeSpend); - if(timeSpend < configuration.refresh) { - //noinspection BusyWait - sleep((configuration.refresh - timeSpend) * 1000); - } - - } while (keepRunning.get()); - - } - } diff --git a/src/main/java/biz/nellemann/hmci/HmcClient.java b/src/main/java/biz/nellemann/hmci/HmcRestClient.java similarity index 94% rename from src/main/java/biz/nellemann/hmci/HmcClient.java rename to src/main/java/biz/nellemann/hmci/HmcRestClient.java index 9fb5b89..636ab23 100644 --- a/src/main/java/biz/nellemann/hmci/HmcClient.java +++ b/src/main/java/biz/nellemann/hmci/HmcRestClient.java @@ -15,7 +15,6 @@ */ package biz.nellemann.hmci; -import biz.nellemann.hmci.Configuration.HmcObject; import okhttp3.*; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -37,34 +36,32 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; -class HmcClient { - private final static Logger log = LoggerFactory.getLogger(HmcClient.class); +public class HmcRestClient { + + private final static Logger log = LoggerFactory.getLogger(HmcRestClient.class); private final MediaType MEDIA_TYPE_IBM_XML_LOGIN = MediaType.parse("application/vnd.ibm.powervm.web+xml; type=LogonRequest"); - private final String hmcId; - private final String baseUrl; - private final String username; - private final String password; - protected Integer responseErrors = 0; protected String authToken; private final OkHttpClient client; // OkHttpClient timeouts - private final static int connectTimeout = 2; - private final static int writeTimeout = 3; - private final static int readTimeout = 3; + private final static int CONNECT_TIMEOUT = 2; + private final static int WRITE_TIMEOUT = 3; + private final static int READ_TIMEOUT = 3; + + private final String baseUrl; + private final String username; + private final String password; - HmcClient(HmcObject configHmc) { + HmcRestClient(String url, String username, String password, Boolean unsafe) { - this.hmcId = configHmc.name; - this.baseUrl = configHmc.url; - this.username = configHmc.username; - this.password = configHmc.password; - Boolean unsafe = configHmc.unsafe; + this.baseUrl = url; + this.username = username; + this.password = password; if(unsafe) { this.client = getUnsafeOkHttpClient(); @@ -74,9 +71,10 @@ class HmcClient { } + @Override public String toString() { - return hmcId + " (" + baseUrl + ")"; + return baseUrl; } @@ -173,7 +171,6 @@ class HmcClient { Elements managedSystems = doc.select("ManagedSystem|ManagedSystem"); // doc.select("img[src$=.png]"); for(Element el : managedSystems) { ManagedSystem system = new ManagedSystem( - hmcId, el.select("Metadata > Atom > AtomID").text(), el.select("SystemName").text(), el.select("MachineTypeModelAndSerialNumber > MachineType").text(), @@ -419,9 +416,9 @@ class HmcClient { OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]); builder.hostnameVerifier((hostname, session) -> true); - builder.connectTimeout(connectTimeout, TimeUnit.SECONDS); - builder.writeTimeout(writeTimeout, TimeUnit.SECONDS); - builder.readTimeout(readTimeout, TimeUnit.SECONDS); + builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS); + builder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS); + builder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS); return builder.build(); } catch (KeyManagementException | NoSuchAlgorithmException e) { @@ -436,9 +433,9 @@ class HmcClient { */ private static OkHttpClient getSafeOkHttpClient() { OkHttpClient.Builder builder = new OkHttpClient.Builder(); - builder.connectTimeout(connectTimeout, TimeUnit.SECONDS); - builder.writeTimeout(writeTimeout, TimeUnit.SECONDS); - builder.readTimeout(readTimeout, TimeUnit.SECONDS); + builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS); + builder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS); + builder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS); return builder.build(); } diff --git a/src/main/java/biz/nellemann/hmci/InfluxClient.java b/src/main/java/biz/nellemann/hmci/InfluxClient.java index d2a7cc1..ededbae 100644 --- a/src/main/java/biz/nellemann/hmci/InfluxClient.java +++ b/src/main/java/biz/nellemann/hmci/InfluxClient.java @@ -53,7 +53,7 @@ class InfluxClient { } - synchronized void login() throws Exception { + synchronized void login() throws RuntimeException, InterruptedException { if(influxDB != null) { return; @@ -76,10 +76,10 @@ class InfluxClient { connected = true; } catch(Exception e) { - sleep(15*1000); + sleep(15 * 1000); if(errors++ > 3) { log.error("login() error, giving up - " + e.getMessage()); - throw new Exception(e); + throw new RuntimeException(e); } else { log.warn("login() error, retrying - " + e.getMessage()); } diff --git a/src/main/java/biz/nellemann/hmci/LogicalPartition.java b/src/main/java/biz/nellemann/hmci/LogicalPartition.java index 4ae3f5f..803799c 100644 --- a/src/main/java/biz/nellemann/hmci/LogicalPartition.java +++ b/src/main/java/biz/nellemann/hmci/LogicalPartition.java @@ -41,6 +41,7 @@ class LogicalPartition extends MetaSystem { } + @Override public String toString() { return String.format("[%s] %s (%s)", id, name, type); } @@ -113,10 +114,8 @@ class LogicalPartition extends MetaSystem { List getVirtualEthernetAdapterMetrics() { - //List metricsList = getListObject(metrics.systemUtil.sample.lparsUtil.network.virtualEthernetAdapters); List list = new ArrayList<>(); - - //metricsList.forEach( adapter -> { + metrics.systemUtil.sample.lparsUtil.network.virtualEthernetAdapters.forEach( adapter -> { HashMap tagsMap = new HashMap<>(); diff --git a/src/main/java/biz/nellemann/hmci/ManagedSystem.java b/src/main/java/biz/nellemann/hmci/ManagedSystem.java index fbc5d4e..daf7a0f 100644 --- a/src/main/java/biz/nellemann/hmci/ManagedSystem.java +++ b/src/main/java/biz/nellemann/hmci/ManagedSystem.java @@ -27,7 +27,7 @@ class ManagedSystem extends MetaSystem { private final static Logger log = LoggerFactory.getLogger(ManagedSystem.class); - public final String hmcId; + //public final String hmcId; public final String id; public final String name; public final String type; @@ -37,8 +37,7 @@ class ManagedSystem extends MetaSystem { public final SystemEnergy energy; - ManagedSystem(String hmcId, String id, String name, String type, String model, String serialNumber) { - this.hmcId = hmcId; + ManagedSystem(String id, String name, String type, String model, String serialNumber) { this.id = id; this.name = name; this.type = type; diff --git a/src/main/java/biz/nellemann/hmci/MetaSystem.java b/src/main/java/biz/nellemann/hmci/MetaSystem.java index dff72f2..feaa37e 100644 --- a/src/main/java/biz/nellemann/hmci/MetaSystem.java +++ b/src/main/java/biz/nellemann/hmci/MetaSystem.java @@ -21,6 +21,7 @@ import com.squareup.moshi.FromJson; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.Moshi; import com.squareup.moshi.ToJson; +import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,8 +29,6 @@ import java.math.BigDecimal; import java.time.Instant; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; -import java.util.ArrayList; -import java.util.List; abstract class MetaSystem { @@ -54,7 +53,7 @@ abstract class MetaSystem { try { metrics = jsonAdapter.nullSafe().fromJson(json); - } catch(Exception e) { + } catch(IOException e) { log.warn("processMetrics() error", e); } //System.out.println(jsonAdapter.toJson(metrics)); @@ -130,18 +129,5 @@ abstract class MetaSystem { } } - - static ArrayList getListObject(Object obj) { - ArrayList list; - try { - list = (ArrayList) obj; - } catch (NullPointerException npe) { - log.warn("getListObject()", npe); - list = new ArrayList(); - } - - return list; - } - } diff --git a/src/test/groovy/biz/nellemann/hmci/HmcClientTest.groovy b/src/test/groovy/biz/nellemann/hmci/HmcRestClientTest.groovy similarity index 88% rename from src/test/groovy/biz/nellemann/hmci/HmcClientTest.groovy rename to src/test/groovy/biz/nellemann/hmci/HmcRestClientTest.groovy index 2414dec..2f8f08c 100644 --- a/src/test/groovy/biz/nellemann/hmci/HmcClientTest.groovy +++ b/src/test/groovy/biz/nellemann/hmci/HmcRestClientTest.groovy @@ -4,16 +4,15 @@ import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import spock.lang.Specification -class HmcClientTest extends Specification { +class HmcRestClientTest extends Specification { - HmcClient hmc + HmcRestClient hmc MockWebServer mockServer = new MockWebServer() def setup() { mockServer.start() - Configuration.HmcObject configHmc = new Configuration.HmcObject("site1", mockServer.url("/").toString(), "testUser", "testPassword", true); - hmc = new HmcClient(configHmc) + hmc = new HmcRestClient(mockServer.url("/").toString(), "testUser", "testPassword", true) hmc.authToken = "blaBla" } @@ -57,7 +56,7 @@ class HmcClientTest extends Specification { mockServer.enqueue(new MockResponse().setBody(testXml)) when: - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") Map partitions = hmc.getLogicalPartitionsForManagedSystem(system) then: diff --git a/src/test/groovy/biz/nellemann/hmci/InfluxClientTest.groovy b/src/test/groovy/biz/nellemann/hmci/InfluxClientTest.groovy index fd7f6c7..3f97f01 100644 --- a/src/test/groovy/biz/nellemann/hmci/InfluxClientTest.groovy +++ b/src/test/groovy/biz/nellemann/hmci/InfluxClientTest.groovy @@ -17,7 +17,6 @@ class InfluxClientTest extends Specification { influxClient.logoff() } - @Ignore void "write ManagedSystem data to influx"() { setup: @@ -25,7 +24,7 @@ class InfluxClientTest extends Specification { def testJson = testFile.getText('UTF-8') when: - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "TestSystem", "TestType", "TestModel", "Test s/n") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "TestSystem", "TestType", "TestModel", "Test s/n") system.processMetrics(testJson) influxClient.writeManagedSystem(system) @@ -34,7 +33,6 @@ class InfluxClientTest extends Specification { } - @Ignore void "write LogicalPartition data to influx"() { setup: @@ -42,7 +40,7 @@ class InfluxClientTest extends Specification { def testJson = testFile.getText('UTF-8') when: - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "TestSystem", "TestType", "TestModel", "Test s/n") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "TestSystem", "TestType", "TestModel", "Test s/n") LogicalPartition lpar = new LogicalPartition("2DE05DB6-8AD5-448F-8327-0F488D287E82", "9Flash01", "OS400", system) lpar.processMetrics(testJson) diff --git a/src/test/groovy/biz/nellemann/hmci/InsightsTest.groovy b/src/test/groovy/biz/nellemann/hmci/InsightsTest.groovy deleted file mode 100644 index 241827a..0000000 --- a/src/test/groovy/biz/nellemann/hmci/InsightsTest.groovy +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This Spock specification was generated by the Gradle 'init' task. - */ -package biz.nellemann.hmci - -import spock.lang.Specification - -class InsightsTest extends Specification { - -} diff --git a/src/test/groovy/biz/nellemann/hmci/LogicalPartitionTest.groovy b/src/test/groovy/biz/nellemann/hmci/LogicalPartitionTest.groovy index 9089ee7..0b08cac 100644 --- a/src/test/groovy/biz/nellemann/hmci/LogicalPartitionTest.groovy +++ b/src/test/groovy/biz/nellemann/hmci/LogicalPartitionTest.groovy @@ -12,7 +12,7 @@ class LogicalPartitionTest extends Specification { def testJson = testFile.getText('UTF-8') when: - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") LogicalPartition lpar = new LogicalPartition("2DE05DB6-8AD5-448F-8327-0F488D287E82", "9Flash01", "OS400", system) lpar.processMetrics(testJson) @@ -29,7 +29,7 @@ class LogicalPartitionTest extends Specification { setup: def testFile = new File(getClass().getResource('/pcm-data-logical-partition.json').toURI()) def testJson = testFile.getText('UTF-8') - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") LogicalPartition lpar = new LogicalPartition("2DE05DB6-8AD5-448F-8327-0F488D287E82", "9Flash01", "OS400", system) when: @@ -48,7 +48,7 @@ class LogicalPartitionTest extends Specification { setup: def testFile = new File(getClass().getResource('/pcm-data-logical-partition.json').toURI()) def testJson = testFile.getText('UTF-8') - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") LogicalPartition lpar = new LogicalPartition("2DE05DB6-8AD5-448F-8327-0F488D287E82", "9Flash01", "OS400", system) when: @@ -67,7 +67,7 @@ class LogicalPartitionTest extends Specification { setup: def testFile = new File(getClass().getResource('/pcm-data-logical-partition.json').toURI()) def testJson = testFile.getText('UTF-8') - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") LogicalPartition lpar = new LogicalPartition("2DE05DB6-8AD5-448F-8327-0F488D287E82", "9Flash01", "OS400", system) when: @@ -85,7 +85,7 @@ class LogicalPartitionTest extends Specification { setup: def testFile = new File(getClass().getResource('/pcm-data-logical-partition.json').toURI()) def testJson = testFile.getText('UTF-8') - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") LogicalPartition lpar = new LogicalPartition("2DE05DB6-8AD5-448F-8327-0F488D287E82", "9Flash01", "OS400", system) when: diff --git a/src/test/groovy/biz/nellemann/hmci/ManagedSystemTest.groovy b/src/test/groovy/biz/nellemann/hmci/ManagedSystemTest.groovy index d1b4ee2..cf12150 100644 --- a/src/test/groovy/biz/nellemann/hmci/ManagedSystemTest.groovy +++ b/src/test/groovy/biz/nellemann/hmci/ManagedSystemTest.groovy @@ -11,7 +11,7 @@ class ManagedSystemTest extends Specification { def testJson = testFile.getText('UTF-8') when: - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") system.processMetrics(testJson) then: @@ -30,7 +30,7 @@ class ManagedSystemTest extends Specification { setup: def testFile = new File(getClass().getResource('/pcm-data-managed-system.json').toURI()) def testJson = testFile.getText('UTF-8') - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") when: system.processMetrics(testJson) @@ -46,7 +46,7 @@ class ManagedSystemTest extends Specification { setup: def testFile = new File(getClass().getResource('/pcm-data-managed-system.json').toURI()) def testJson = testFile.getText('UTF-8') - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") when: system.processMetrics(testJson) @@ -62,7 +62,7 @@ class ManagedSystemTest extends Specification { setup: def testFile = new File(getClass().getResource('/pcm-data-managed-system.json').toURI()) def testJson = testFile.getText('UTF-8') - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") when: system.processMetrics(testJson) @@ -77,7 +77,7 @@ class ManagedSystemTest extends Specification { setup: def testFile = new File(getClass().getResource('/pcm-data-managed-system.json').toURI()) def testJson = testFile.getText('UTF-8') - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") when: system.processMetrics(testJson) @@ -93,7 +93,7 @@ class ManagedSystemTest extends Specification { setup: def testFile = new File(getClass().getResource('/pcm-data-managed-system.json').toURI()) def testJson = testFile.getText('UTF-8') - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") when: system.processMetrics(testJson) @@ -111,7 +111,7 @@ class ManagedSystemTest extends Specification { setup: def testFile = new File(getClass().getResource('/pcm-data-managed-system.json').toURI()) def testJson = testFile.getText('UTF-8') - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") when: system.processMetrics(testJson) diff --git a/src/test/groovy/biz/nellemann/hmci/MetaSystemTest.groovy b/src/test/groovy/biz/nellemann/hmci/MetaSystemTest.groovy index e53e79e..c914777 100644 --- a/src/test/groovy/biz/nellemann/hmci/MetaSystemTest.groovy +++ b/src/test/groovy/biz/nellemann/hmci/MetaSystemTest.groovy @@ -13,7 +13,7 @@ class MetaSystemTest extends Specification { def testJson = testFile.getText('UTF-8') when: - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") system.processMetrics(testJson) Instant instant = system.getTimestamp() diff --git a/src/test/groovy/biz/nellemann/hmci/SystemEnergyTest.groovy b/src/test/groovy/biz/nellemann/hmci/SystemEnergyTest.groovy index 42edb26..541e5bc 100644 --- a/src/test/groovy/biz/nellemann/hmci/SystemEnergyTest.groovy +++ b/src/test/groovy/biz/nellemann/hmci/SystemEnergyTest.groovy @@ -11,7 +11,7 @@ class SystemEnergyTest extends Specification { def testJson = testFile.getText('UTF-8') when: - ManagedSystem system = new ManagedSystem("site1", "e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") + ManagedSystem system = new ManagedSystem("e09834d1-c930-3883-bdad-405d8e26e166", "Test Name","Test Type", "Test Model", "Test S/N") system.energy.processMetrics(testJson) then: From 2d67d24a6107679cc072431da9e555d32c4b39d6 Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Thu, 14 Jan 2021 13:58:40 +0100 Subject: [PATCH 3/4] Add some more information about. --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index df9e0a9..7f40f03 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ # HMC Insights -**HMCi** is a utility that collects metrics from one or more *IBM Power HMC* systems. The metric data is processed and saved into an InfluxDB time-series database. Grafana is used to visualize the metrics from InfluxDB. +**HMCi** is a utility that collects metrics from one or more *IBM Power HMC* systems. The metric data is processed and saved into an InfluxDB time-series database. Grafana can be used to visualize the metrics from InfluxDB. -Metrics includes *Managed Systems* (the physical Power servers) and *Logical Partitions* (the virtualized servers) running AIX, Linux and IBM-i (AS/400). +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 ![architecture](https://bitbucket.org/mnellemann/hmci/downloads/HMCi.png) @@ -30,7 +34,7 @@ Install InfluxDB on an *LPAR* or other server, which is network accessible by th ### HMCi Installation Instructions -- Ensure you have correct date/time and NTPd running to keep it accurate! +- Ensure you have **correct date/time** and NTPd running to keep it accurate! - The only requirement for **hmci** is the Java runtime, version 8 (or later) - Install **HMCi** from [downloads](https://bitbucket.org/mnellemann/hmci/downloads/) (rpm, deb or jar) or build from source - Copy the *doc/hmci.toml* configuration example into */etc/hmci.toml* and edit the configuration to suit your environment. The location of the configuration file can be changed with a flag when running hmci. @@ -54,7 +58,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 -written to InfluxDB (which uses the name is key). +written to InfluxDB (which uses the name as key). ### Renaming partitions From b8db4a786ac5364a673223d373f6dad509fef35b Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Thu, 14 Jan 2021 14:22:42 +0100 Subject: [PATCH 4/4] Disable automatic influx batch writes. --- src/main/java/biz/nellemann/hmci/InfluxClient.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/biz/nellemann/hmci/InfluxClient.java b/src/main/java/biz/nellemann/hmci/InfluxClient.java index ededbae..32d6ba2 100644 --- a/src/main/java/biz/nellemann/hmci/InfluxClient.java +++ b/src/main/java/biz/nellemann/hmci/InfluxClient.java @@ -36,6 +36,10 @@ class InfluxClient { private final static Logger log = LoggerFactory.getLogger(InfluxClient.class); + private static final int BATCH_ACTIONS_LIMIT = 5000; + private static final int BATCH_INTERVAL_DURATION = 1000; + + final private String url; final private String username; final private String password; @@ -67,14 +71,8 @@ class InfluxClient { log.debug("Connecting to InfluxDB - " + url); influxDB = InfluxDBFactory.connect(url, username, password); createDatabase(); - - // Enable batch writes to get better performance. - BatchOptions options = BatchOptions.DEFAULTS.actions(1000).flushDuration(5000).precision(TimeUnit.SECONDS); - influxDB.enableBatch(options); batchPoints = BatchPoints.database(database).precision(TimeUnit.SECONDS).build(); - connected = true; - } catch(Exception e) { sleep(15 * 1000); if(errors++ > 3) { @@ -107,7 +105,7 @@ class InfluxClient { synchronized void writeBatchPoints() throws Exception { log.debug("writeBatchPoints()"); try { - influxDB.write(batchPoints); + influxDB.writeWithRetry(batchPoints); } catch(Exception e) { log.error("writeBatchPoints() error - " + e.getMessage()); logoff();