/*
* Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.tsdr.collectors.cmc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Optional;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class SigarCpuDataCollector extends CpuDataCollector {
private static final Logger LOG = LoggerFactory.getLogger(SigarCpuDataCollector.class);
private Object sigar;
private URLClassLoader sigarLoader;
public SigarCpuDataCollector() throws SigarNotPresentException {
final Optional<Object> sigarOp = getSigar();
if (sigarOp.isPresent()) {
sigar = sigarOp.get();
}
}
/*
* There is a problem with the Karaf/OSGI/Config Subsystem class loader and Sigar.
* Sigar cannot be instantiated due to "java.lang.NoClassDefFoundError: Could not initialize class org.hyperic.sigar.Sigar"
* Hence i had to revert to using a dedicated class loader and reflection to use the
* functionality in the module.
*/
private Optional<Object> getSigar() throws SigarNotPresentException {
try {
final File sigarFile = new File("./system/org/fusesource/sigar/1.6.4/sigar-1.6.4.jar");
final URL sigarUrl = sigarFile.toURI().toURL();
return instantiateSigar(sigarUrl);
} catch (final MalformedURLException e) {
// this should never happen as the URL is hard coded and cannot be malformed
throw new SigarNotPresentException(e);
}
}
private Optional<Object> instantiateSigar(final URL sigarUrl) throws SigarNotPresentException {
LOG.debug("Instantiating Sigar object");
sigarLoader = new URLClassLoader(new URL[] {sigarUrl});
try {
return Optional.of(sigarLoader.loadClass("org.hyperic.sigar.Sigar").newInstance());
} catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new SigarNotPresentException(e);
}
}
@Override
public Optional<Double> getControllerCpu() {
LOG.debug("Getting controller CPU data");
try{
Method pidM = sigar.getClass().getMethod("getPid", (Class<?>[])null);
long pid = (Long)pidM.invoke(sigar, (Object[])null);
Method cpuM = sigar.getClass().getMethod("getProcCpu", long.class);
Object procCPU = cpuM.invoke(sigar, pid);
Method procM = procCPU.getClass().getMethod("getPercent",(Class<?>[])null);
return Optional.of((double) procM.invoke(procCPU, (Object[])null));
}catch(final NoSuchMethodException | InvocationTargetException | IllegalAccessException err){
LOG.error("Failed to get Controller CPU, Sigar library is probably not installed...", err);
}
return Optional.empty();
}
@Override
public Optional<Double> getMachineCpu() {
LOG.debug("Getting machine CPU data");
try {
Method cpuM = sigar.getClass().getMethod("getCpuPerc", (Class<?>[])null);
Object cpu = cpuM.invoke(sigar, (Object[])null);
Method combineM = cpu.getClass().getMethod("getCombined",(Class<?>[])null);
return Optional.of((double) combineM.invoke(cpu, (Object[])null));
} catch (final NoSuchMethodException | InvocationTargetException | IllegalAccessException err) {
LOG.error("Failed to get Machine CPU, Sigar library is probably not installed...", err);
}
return Optional.empty();
}
@Override
public void close() throws Exception {
sigarLoader.close();
}
}