381 lines
15 KiB
Java
381 lines
15 KiB
Java
/*
|
|
* Copyright 2020 Mark Nellemann <mark.nellemann@gmail.com>
|
|
*
|
|
* 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 biz.nellemann.hmci.Configuration.InfluxObject;
|
|
import org.influxdb.InfluxDB;
|
|
import org.influxdb.InfluxDBException;
|
|
import org.influxdb.InfluxDBFactory;
|
|
import org.influxdb.dto.BatchPoints;
|
|
import org.influxdb.dto.Point;
|
|
import org.influxdb.dto.Query;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.time.Instant;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import static java.lang.Thread.sleep;
|
|
|
|
class InfluxClient {
|
|
|
|
private final static Logger log = LoggerFactory.getLogger(InfluxClient.class);
|
|
|
|
final private String url;
|
|
final private String username;
|
|
final private String password;
|
|
final private String database;
|
|
|
|
private InfluxDB influxDB;
|
|
private BatchPoints batchPoints;
|
|
private int errorCounter = 0;
|
|
|
|
|
|
InfluxClient(InfluxObject config) {
|
|
this.url = config.url;
|
|
this.username = config.username;
|
|
this.password = config.password;
|
|
this.database = config.database;
|
|
}
|
|
|
|
|
|
synchronized void login() throws RuntimeException, InterruptedException {
|
|
|
|
if(influxDB != null) {
|
|
return;
|
|
}
|
|
|
|
boolean connected = false;
|
|
int loginErrors = 0;
|
|
|
|
do {
|
|
try {
|
|
log.debug("Connecting to InfluxDB - {}", url);
|
|
influxDB = InfluxDBFactory.connect(url, username, password).setDatabase(database);
|
|
batchPoints = BatchPoints.database(database).precision(TimeUnit.SECONDS).build();
|
|
connected = true;
|
|
} catch(Exception e) {
|
|
sleep(15 * 1000);
|
|
if(loginErrors++ > 3) {
|
|
log.error("login() - error, giving up: {}", e.getMessage());
|
|
throw new RuntimeException(e);
|
|
} else {
|
|
log.warn("login() - error, retrying: {}", e.getMessage());
|
|
}
|
|
}
|
|
} while(!connected);
|
|
|
|
}
|
|
|
|
|
|
synchronized void logoff() {
|
|
if(influxDB != null) {
|
|
influxDB.close();
|
|
}
|
|
influxDB = null;
|
|
}
|
|
|
|
|
|
synchronized void writeBatchPoints() throws Exception {
|
|
log.trace("writeBatchPoints()");
|
|
try {
|
|
influxDB.writeWithRetry(batchPoints);
|
|
} catch (InfluxDBException.DatabaseNotFoundException e) {
|
|
log.error("writeBatchPoints() - database \"{}\" not found/created: can't write data", database);
|
|
} catch(Exception e) {
|
|
e.printStackTrace();
|
|
log.warn("writeBatchPoints() {}", e.getMessage());
|
|
if(++errorCounter > 5) {
|
|
errorCounter = 0;
|
|
logoff();
|
|
login();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
Managed System
|
|
*/
|
|
|
|
|
|
void writeManagedSystem(ManagedSystem system) {
|
|
|
|
if(system.metrics == null) {
|
|
log.trace("writeManagedSystem() - null metrics, skipping: {}", system.name);
|
|
return;
|
|
}
|
|
|
|
Instant timestamp = system.getTimestamp();
|
|
if(timestamp == null) {
|
|
log.warn("writeManagedSystem() - no timestamp, skipping: {}", system.name);
|
|
return;
|
|
}
|
|
|
|
getSystemDetails(system, timestamp).forEach( it -> batchPoints.point(it) );
|
|
getSystemProcessor(system, timestamp).forEach( it -> batchPoints.point(it) );
|
|
getSystemPhysicalProcessorPool(system, timestamp).forEach( it -> batchPoints.point(it) );
|
|
getSystemSharedProcessorPools(system, timestamp).forEach( it -> batchPoints.point(it) );
|
|
getSystemMemory(system, timestamp).forEach( it -> batchPoints.point(it) );
|
|
|
|
getSystemViosDetails(system, timestamp).forEach(it -> batchPoints.point(it) );
|
|
getSystemViosProcessor(system, timestamp).forEach( it -> batchPoints.point(it) );
|
|
getSystemViosMemory(system, timestamp).forEach( it -> batchPoints.point(it) );
|
|
|
|
getSystemViosNetworkLpars(system, timestamp).forEach(it -> batchPoints.point(it) );
|
|
getSystemViosNetworkGenericAdapters(system, timestamp).forEach(it -> batchPoints.point(it) );
|
|
getSystemViosNetworkSharedAdapters(system, timestamp).forEach(it -> batchPoints.point(it) );
|
|
getSystemViosNetworkVirtualAdapters(system, timestamp).forEach(it -> batchPoints.point(it) );
|
|
|
|
getSystemViosStorageLpars(system, timestamp).forEach(it -> batchPoints.point(it) );
|
|
getSystemViosFiberChannelAdapters(system, timestamp).forEach(it -> batchPoints.point(it) );
|
|
getSystemViosStoragePhysicalAdapters(system, timestamp).forEach(it -> batchPoints.point(it) );
|
|
getSystemViosStorageVirtualAdapters(system, timestamp).forEach(it -> batchPoints.point(it) );
|
|
|
|
}
|
|
|
|
|
|
// TODO: server_details
|
|
|
|
private static List<Point> getSystemDetails(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getDetails();
|
|
return processMeasurementMap(metrics, timestamp, "server_details");
|
|
}
|
|
|
|
private static List<Point> getSystemProcessor(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getProcessorMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "server_processor");
|
|
}
|
|
|
|
private static List<Point> getSystemPhysicalProcessorPool (ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getPhysicalProcessorPool();
|
|
return processMeasurementMap(metrics, timestamp, "server_physicalProcessorPool");
|
|
}
|
|
|
|
private static List<Point> getSystemSharedProcessorPools(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getSharedProcessorPools();
|
|
return processMeasurementMap(metrics, timestamp, "server_sharedProcessorPool");
|
|
}
|
|
|
|
private static List<Point> getSystemMemory(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getMemoryMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "server_memory");
|
|
}
|
|
|
|
private static List<Point> getSystemViosDetails(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosDetails();
|
|
return processMeasurementMap(metrics, timestamp, "vios_details");
|
|
}
|
|
|
|
private static List<Point> getSystemViosProcessor(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosProcessorMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "vios_processor");
|
|
}
|
|
|
|
private static List<Point> getSystemViosMemory(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosMemoryMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "vios_memory");
|
|
}
|
|
|
|
private static List<Point> getSystemViosNetworkLpars(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosNetworkLpars();
|
|
return processMeasurementMap(metrics, timestamp, "vios_network_lpars");
|
|
}
|
|
|
|
private static List<Point> getSystemViosNetworkVirtualAdapters(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosNetworkVirtualAdapters();
|
|
return processMeasurementMap(metrics, timestamp, "vios_network_virtual");
|
|
}
|
|
|
|
private static List<Point> getSystemViosNetworkSharedAdapters(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosNetworkSharedAdapters();
|
|
return processMeasurementMap(metrics, timestamp, "vios_network_shared");
|
|
}
|
|
|
|
private static List<Point> getSystemViosNetworkGenericAdapters(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosNetworkGenericAdapters();
|
|
return processMeasurementMap(metrics, timestamp, "vios_network_generic");
|
|
}
|
|
|
|
|
|
private static List<Point> getSystemViosStorageLpars(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosStorageLpars();
|
|
return processMeasurementMap(metrics, timestamp, "vios_storage_lpars");
|
|
}
|
|
|
|
private static List<Point> getSystemViosFiberChannelAdapters(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosStorageFiberChannelAdapters();
|
|
return processMeasurementMap(metrics, timestamp, "vios_storage_FC");
|
|
}
|
|
|
|
private static List<Point> getSystemViosSharedStoragePools(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosStorageSharedStoragePools();
|
|
return processMeasurementMap(metrics, timestamp, "vios_storage_SSP");
|
|
}
|
|
|
|
private static List<Point> getSystemViosStoragePhysicalAdapters(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosStoragePhysicalAdapters();
|
|
return processMeasurementMap(metrics, timestamp, "vios_storage_physical");
|
|
}
|
|
|
|
private static List<Point> getSystemViosStorageVirtualAdapters(ManagedSystem system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getViosStorageVirtualAdapters();
|
|
return processMeasurementMap(metrics, timestamp, "vios_storage_vFC");
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
Logical Partitions
|
|
*/
|
|
|
|
void writeLogicalPartition(LogicalPartition partition) {
|
|
|
|
if(partition.metrics == null) {
|
|
log.warn("writeLogicalPartition() - null metrics, skipping: {}", partition.name);
|
|
return;
|
|
}
|
|
|
|
Instant timestamp = partition.getTimestamp();
|
|
if(timestamp == null) {
|
|
log.warn("writeLogicalPartition() - no timestamp, skipping: {}", partition.name);
|
|
return;
|
|
}
|
|
|
|
getPartitionDetails(partition, timestamp).forEach( it -> batchPoints.point(it));
|
|
getPartitionMemory(partition, timestamp).forEach( it -> batchPoints.point(it));
|
|
getPartitionProcessor(partition, timestamp).forEach( it -> batchPoints.point(it));
|
|
getPartitionNetworkVirtual(partition, timestamp).forEach(it -> batchPoints.point(it));
|
|
getPartitionStorageVirtualGeneric(partition, timestamp).forEach(it -> batchPoints.point(it));
|
|
getPartitionStorageVirtualFibreChannel(partition, timestamp).forEach(it -> batchPoints.point(it));
|
|
|
|
}
|
|
|
|
private static List<Point> getPartitionDetails(LogicalPartition partition, Instant timestamp) {
|
|
List<Measurement> metrics = partition.getDetails();
|
|
return processMeasurementMap(metrics, timestamp, "lpar_details");
|
|
}
|
|
|
|
private static List<Point> getPartitionProcessor(LogicalPartition partition, Instant timestamp) {
|
|
List<Measurement> metrics = partition.getProcessorMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "lpar_processor");
|
|
}
|
|
|
|
private static List<Point> getPartitionMemory(LogicalPartition partition, Instant timestamp) {
|
|
List<Measurement> metrics = partition.getMemoryMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "lpar_memory");
|
|
}
|
|
|
|
private static List<Point> getPartitionNetworkVirtual(LogicalPartition partition, Instant timestamp) {
|
|
List<Measurement> metrics = partition.getVirtualEthernetAdapterMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "lpar_net_virtual"); // Not 'network'
|
|
}
|
|
|
|
// TODO: lpar_net_sriov
|
|
|
|
private static List<Point> getPartitionStorageVirtualGeneric(LogicalPartition partition, Instant timestamp) {
|
|
List<Measurement> metrics = partition.getVirtualGenericAdapterMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "lpar_storage_virtual");
|
|
}
|
|
|
|
private static List<Point> getPartitionStorageVirtualFibreChannel(LogicalPartition partition, Instant timestamp) {
|
|
List<Measurement> metrics = partition.getVirtualFibreChannelAdapterMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "lpar_storage_vFC");
|
|
}
|
|
|
|
|
|
/*
|
|
System Energy
|
|
Not supported on older HMC (pre v8) or older Power server (pre Power 8)
|
|
*/
|
|
|
|
|
|
void writeSystemEnergy(SystemEnergy systemEnergy) {
|
|
|
|
if(systemEnergy.metrics == null) {
|
|
log.trace("writeSystemEnergy() - null metrics, skipping: {}", systemEnergy.system.name);
|
|
return;
|
|
}
|
|
|
|
Instant timestamp = systemEnergy.getTimestamp();
|
|
if(timestamp == null) {
|
|
log.warn("writeSystemEnergy() - no timestamp, skipping: {}", systemEnergy.system.name);
|
|
return;
|
|
}
|
|
|
|
getSystemEnergyPower(systemEnergy, timestamp).forEach(it -> batchPoints.point(it) );
|
|
getSystemEnergyTemperature(systemEnergy, timestamp).forEach(it -> batchPoints.point(it) );
|
|
}
|
|
|
|
private static List<Point> getSystemEnergyPower(SystemEnergy system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getPowerMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "server_energy_power");
|
|
}
|
|
|
|
private static List<Point> getSystemEnergyTemperature(SystemEnergy system, Instant timestamp) {
|
|
List<Measurement> metrics = system.getThermalMetrics();
|
|
return processMeasurementMap(metrics, timestamp, "server_energy_thermal");
|
|
}
|
|
|
|
|
|
/*
|
|
Shared
|
|
*/
|
|
|
|
private static List<Point> processMeasurementMap(List<Measurement> measurements, Instant timestamp, String measurement) {
|
|
|
|
List<Point> listOfPoints = new ArrayList<>();
|
|
measurements.forEach( m -> {
|
|
|
|
Point.Builder builder = Point.measurement(measurement)
|
|
.time(timestamp.toEpochMilli(), TimeUnit.MILLISECONDS);
|
|
|
|
// Iterate fields
|
|
m.fields.forEach((fieldName, fieldValue) -> {
|
|
|
|
log.trace("processMeasurementMap() {} - fieldName: {}, fieldValue: {}", measurement, fieldName, fieldValue);
|
|
if(fieldValue instanceof Number) {
|
|
Number num = (Number) fieldValue;
|
|
builder.addField(fieldName, num);
|
|
} else if(fieldValue instanceof Boolean) {
|
|
Boolean bol = (Boolean) fieldValue;
|
|
builder.addField(fieldName, bol);
|
|
} else {
|
|
String str = (String) fieldValue;
|
|
builder.addField(fieldName, str);
|
|
}
|
|
});
|
|
|
|
// Iterate tags
|
|
m.tags.forEach((tagName, tagValue) -> {
|
|
log.trace("processMeasurementMap() {} - tagName: {}, tagValue: {}", measurement, tagName, tagValue);
|
|
builder.tag(tagName, tagValue);
|
|
});
|
|
|
|
listOfPoints.add(builder.build());
|
|
|
|
});
|
|
|
|
return listOfPoints;
|
|
}
|
|
|
|
|
|
}
|