/*
* Copyright 2008 to the original author or authors.
*
* 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 org.rioproject.impl.system.measurable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* This class is used to help in loading and using
* <a href="http://www.hyperic.com/products/sigar.html">Hyperic SIGAR</a>.
*
* <p>This class does not explicitly include and Hyperic SIGAR classes, it uses
* reflection to access and use SIGAR. In this way if there is an issue
* including SIGAR, the distribution has no hard-coded dependencies for the
* technology.
*
* @author Dennis Reedy
*/
public final class SigarHelper {
public static final String COMPONENT = SigarHelper.class.getPackage().getName();
static Logger logger = LoggerFactory.getLogger(COMPONENT);
private static final double NOT_AVAILABLE = 0;
private Object sigarInstance;
private final Object sigarLock = new Object();
/* System cpu info method accessors */
private Method getCpuPercMethod;
private Method getSysMethod;
private Method getUserMethod;
private Method getLoadAverageMethod;
/* Process statistics */
private Method getProcList;
/* Process cpu method accessors */
private Method getPercentMethod;
private Method getProcCpuMethod;
private Method getProcCpuSysMethod;
private Method getProcCpuUserMethod;
/* Process memory usage method accessors */
private Method getSizeMethod;
private Method getProcMemMethod;
private Method getResidentMethod;
private Method getShareMethod;
/* System file system usage method accessors */
private Method getFileSystemUsageMethod;
private Method fileSystemFreeMethod;
private Method fileSystemUsedMethod;
private Method fileSystemTotalMethod;
private Method fileSystemUsedPercentMethod;
/* System memory usage method accessors */
private Method getMemMethod;
private Method getUsedMemoryMethod;
private Method getFreeMemoryMethod;
private Method getFreeMemoryPercentMethod;
private Method getUsedMemoryPercentMethod;
private Method getSystemRAMMethod;
private Method getSystemMemoryMethod;
private SigarHelper() {
try {
Class<?> sigarClass = Class.forName("org.hyperic.sigar.Sigar");
Object sigar = sigarClass.newInstance();
Class<?> sigarProxyClass = Class.forName("org.hyperic.sigar.SigarProxyCache");
Method newInstance = sigarProxyClass.getMethod("newInstance", sigarClass, int.class);
synchronized(sigarLock) {
sigarInstance = newInstance.invoke(null, sigar, 5000);
/* Try to get the pid, if this passes SIGAR is available */
try {
Method getPid = getMethod("getPid");
getPid.invoke(sigarInstance);
} catch(Exception e) {
sigarInstance = null;
}
}
} catch (Throwable e) {
logger.debug("Could not load SIGAR {}: {}", e.getClass(), e.getMessage());
}
}
/**
* Get an instance of the SigarHelper.
*
* @return An instance of the SigarHelper.
*/
public static synchronized SigarHelper getInstance() {
SigarHelper helper = new SigarHelper();
return helper.haveSigar() ? helper : null;
}
/**
* Check if SIGAR is available.
*
* @return True if SIGAR is available, false otherwise.
*/
public static boolean sigarAvailable() {
return getInstance()!=null;
}
/**
* Get the pid for the current process
*
* @return The process id (pid) for the executing process. If the pid
* cannot be obtained return -1.
*/
public long getPid() {
Long pid = (long)-1;
try {
Method getPid = getMethod("getPid");
synchronized(sigarLock) {
pid = (Long)getPid.invoke(sigarInstance);
}
} catch (Exception e) {
log("Could not get PID from SIGAR", e);
}
return pid;
}
/**
* Using the process identifier (pid) of a parent, find the matching child
* process using a bottom up approach
*
* @param ppid The parent pid
* @param sPids Array of child pids
*
* @return The matching child pid, or -1 if not found.
*/
public long matchChild(final int ppid, final String[] sPids) {
long found = -1;
long[] pids = new long[sPids.length];
for(int i=0; i<sPids.length; i++)
pids[i] = new Long(sPids[i]);
/* First check to see if the passed in ppid is in the list of child
* pids. If we have a match there is no reason to traverse the hierarchy */
for(long pid : pids) {
if(pid==ppid) {
found = pid;
break;
}
}
if(found>0)
return found;
Method getProcState = null;
StringBuilder s = new StringBuilder();
for(int i=0; i<pids.length; i++) {
if(i>0)
s.append(", ");
s.append(pids[i]);
}
System.out.println("Parent PID: ["+ppid+"], JMX pids: ["+s.toString()+"]");
try {
for(String pid: sPids) {
long lPid = new Long(pid);
if(lPid<=0)
continue;
if(getProcState==null)
getProcState = getMethod("getProcState", String.class);
Object procState;
synchronized(sigarLock) {
procState = getProcState.invoke(sigarInstance, pid);
}
Method getPpid = procState.getClass().getMethod("getPpid");
long parentPID = (Long)getPpid.invoke(procState);
System.out.println("PID=["+pid+"], PPID=["+parentPID+"]");
if(parentPID==ppid) {
System.out.println("MATCHED!!! PID DETERMINED AS: "+pid);
found = new Long(pid);
break;
} else {
long parent = matchChild(ppid, new String[]{Long.toString(parentPID)});
if(parent==ppid) {
System.out.println("Matched parent, PID is: "+parent);
found = parent;
break;
}
}
}
} catch (Exception e) {
log("Could not get PID from SIGAR", e);
}
return found;
}
public List<String> getProcessList() {
checkGetProcListMethod();
if(getProcList==null)
return null;
List<String> processList = new ArrayList<String>();
try {
long[] array = (long[])getProcList.invoke(sigarInstance);
for(long l : array) {
processList.add(Long.toString(l));
}
} catch (Exception e) {
log("Failed invoking getProcList method", e);
}
return processList;
}
/**
* Get the cpu kernel usage
*
* @return The cpu kernel use as a percentage; or 0 if not available.
*/
public double getSystemCpuPercentage() {
checkCpuPercMethod();
if(getCpuPercMethod==null)
return NOT_AVAILABLE;
if(getSysMethod==null) {
try {
getSysMethod = getCpuPercMethod.getReturnType().getMethod("getSys");
} catch (NoSuchMethodException e) {
log("Could not obtain getSys method from SIGAR", e);
return NOT_AVAILABLE;
}
}
double systemPercentage = NOT_AVAILABLE;
try {
systemPercentage = (Double)getSysMethod.invoke(getCpuPerc());
} catch (Exception e) {
log("Failed invoking getSys method", e);
}
return systemPercentage;
}
/**
* Get the cpu user usage
*
* @return The cpu user use as a percentage; or 0 if not available.
*/
public double getUserCpuPercentage() {
checkCpuPercMethod();
if(getCpuPercMethod==null)
return NOT_AVAILABLE;
if(getUserMethod==null) {
try {
getUserMethod = getCpuPercMethod.getReturnType().getMethod("getUser");
} catch (NoSuchMethodException e) {
log("Could not obtain getUser method from SIGAR", e);
return NOT_AVAILABLE;
}
}
double userPercentage = NOT_AVAILABLE;
try {
userPercentage = (Double)getUserMethod.invoke(getCpuPerc());
} catch (Exception e) {
log("Failed invoking getUser method", e);
}
return userPercentage;
}
/**
* Get the load average for the machine
*
* @return The system load averages for the past 1, 5, and 15 minutes. If
* the load average could not be obtained, return an array with a single
* element whose value is set to 0
*/
public double[] getLoadAverage() {
if(getLoadAverageMethod==null) {
try {
getLoadAverageMethod = getMethod("getLoadAverage");
} catch (NoSuchMethodException e) {
log("Could not obtain getLoadAverage method from SIGAR", e);
return new double[]{NOT_AVAILABLE};
}
}
double[] loadAverage;
try {
synchronized(sigarLock) {
loadAverage = (double[])getLoadAverageMethod.invoke(sigarInstance);
}
} catch (Exception e) {
if(logger.isDebugEnabled()) {
Throwable t;
if(e instanceof InvocationTargetException)
t = ((InvocationTargetException) e).getTargetException();
else
t = e;
logger.debug("Failed invoking getLoadAverage method, load average is not available: {}: {}",
t.getClass().getName(), t.getMessage());
}
loadAverage = new double[]{NOT_AVAILABLE};
}
return loadAverage;
}
/**
* Get the CPU utilization (percentage) for a process
*
* @param pid The process id (pid) to obtain the CPU utilization
* (percentage) for
*
* @return The CPU utilization (percentage) for a process, or 0 if not
* available
*/
public double getProcessCpuPercentage(final long pid) {
checkProcCPU();
if(getProcCpuMethod==null) {
return NOT_AVAILABLE;
}
if(getPercentMethod==null) {
Object procCpu;
try {
synchronized(sigarLock) {
procCpu = getProcCpuMethod.invoke(sigarInstance, pid);
}
} catch (Exception e) {
log("Failed invoking getProcCpu method", e);
return NOT_AVAILABLE;
}
try {
getPercentMethod = procCpu.getClass().getMethod("getPercent");
} catch (NoSuchMethodException e) {
log("Could not obtain getPercent method from SIGAR ProcCPU class", e);
return NOT_AVAILABLE;
}
}
double percent = NOT_AVAILABLE;
try {
synchronized(sigarLock) {
percent = (Double)getPercentMethod.invoke(getProcCpuMethod.invoke(sigarInstance, pid));
}
} catch (Exception e) {
log("Failed invoking getPercent method", e);
}
return percent;
}
/**
* Get the CPU user usage for a process
*
* @param pid The process id (pid) to obtain the CPU user usage
*
* @return The cpu user usage for the process; or 0 if not available.
*/
public long getProcessCpuUser(final long pid) {
checkProcCPU();
if(getProcCpuMethod==null) {
return (long)NOT_AVAILABLE;
}
if(getProcCpuUserMethod==null) {
Object procCpu;
try {
synchronized(sigarLock) {
procCpu = getProcCpuMethod.invoke(sigarInstance, pid);
}
} catch (Exception e) {
log("Failed invoking getProcCpu method", e);
return (long)NOT_AVAILABLE;
}
try {
getProcCpuUserMethod = procCpu.getClass().getMethod("getUser");
} catch (NoSuchMethodException e) {
log("Could not obtain getUser method from SIGAR ProcCPU class", e);
return (long)NOT_AVAILABLE;
}
}
long user = (long)NOT_AVAILABLE;
try {
synchronized(sigarLock) {
user = (Long)getProcCpuUserMethod.invoke(getProcCpuMethod.invoke(sigarInstance, pid));
}
} catch (Exception e) {
log("Failed invoking getUser method", e);
}
return user;
}
/**
* Get the CPU system (kernel) usage for a process
*
* @param pid The process id (pid) to obtain the CPU system (kernel) usage
*
* @return The cpu system (kernel) usage for the process; or 0 if not available.
*/
public long getProcessCpuSys(final long pid) {
checkProcCPU();
if(getProcCpuMethod==null) {
return (long)NOT_AVAILABLE;
}
if(getProcCpuSysMethod==null) {
Object procCpu;
try {
synchronized(sigarLock) {
procCpu = getProcCpuMethod.invoke(sigarInstance, pid);
}
} catch (Exception e) {
log("Failed invoking getProcCpu method", e);
return (long)NOT_AVAILABLE;
}
try {
getProcCpuSysMethod = procCpu.getClass().getMethod("getSys");
} catch (NoSuchMethodException e) {
log("Could not obtain getSys method from SIGAR ProcCPU class", e);
return (long)NOT_AVAILABLE;
}
}
long sys = (long)NOT_AVAILABLE;
try {
synchronized(sigarLock) {
sys = (Long)getProcCpuSysMethod.invoke(getProcCpuMethod.invoke(sigarInstance, pid));
}
} catch (Exception e) {
log("Failed invoking getSys method", e);
}
return sys;
}
private void checkProcCPU() {
if(getProcCpuMethod==null) {
try {
getProcCpuMethod = getMethod("getProcCpu", long.class);
} catch (NoSuchMethodException e) {
log("Could not obtain getProcCpu method from SIGAR", e);
}
}
}
/**
* Get the amount of virtual memory the process has available to it
*
* @param pid The process id (pid)
*
* @return The amount of virtual memory (in bytes) or 0 if not available
*/
public long getProcessVirtualMemorySize(final long pid) {
checkProcMemMethod();
if(getProcMemMethod==null)
return (long)NOT_AVAILABLE;
if(getSizeMethod==null) {
Object procMem = getProcMem(pid);
if(procMem==null)
return (long)NOT_AVAILABLE;
try {
getSizeMethod = procMem.getClass().getMethod("getSize");
} catch (NoSuchMethodException e) {
log("Could not obtain getSize method from SIGAR ProcMem class", e);
return (long)NOT_AVAILABLE;
}
}
long size = (long)NOT_AVAILABLE;
try {
size = (Long)getSizeMethod.invoke(getProcMem(pid));
} catch (Exception e) {
log("Failed invoking getSize method", e);
}
return size;
}
/**
* Get the amount of real memory the process has available to it
*
* @param pid The process id (pid)
*
* @return The amount of real memory (in bytes) or 0 if not available
*/
public long getProcessResidentMemory(final long pid) {
checkProcMemMethod();
if(getProcMemMethod==null)
return (long)NOT_AVAILABLE;
if(getResidentMethod==null) {
Object procMem = getProcMem(pid);
if(procMem==null)
return (long)NOT_AVAILABLE;
try {
getResidentMethod = procMem.getClass().getMethod("getResident");
} catch (NoSuchMethodException e) {
log("Could not obtain getResident method from SIGAR ProcMem class", e);
return (long)NOT_AVAILABLE;
}
}
long resident = (long)NOT_AVAILABLE;
try {
resident = (Long)getResidentMethod.invoke(getProcMem(pid));
} catch (Exception e) {
log("Failed invoking getSize method", e);
}
return resident;
}
/**
* Get the amount of shared memory the process has available to it
*
* @param pid The process id (pid)
*
* @return The amount of shared memory (in bytes) or 0 if not available
*/
public long getProcessSharedMemory(final long pid) {
checkProcMemMethod();
if(getProcMemMethod==null)
return (long)NOT_AVAILABLE;
if(getShareMethod==null) {
Object procMem = getProcMem(pid);
if(procMem==null)
return (long)NOT_AVAILABLE;
try {
getShareMethod = procMem.getClass().getMethod("getShare");
} catch (NoSuchMethodException e) {
log("Could not obtain getShare method from SIGAR ProcMem class", e);
return (long)NOT_AVAILABLE;
}
}
long shared = (long)NOT_AVAILABLE;
try {
shared = (Long)getShareMethod.invoke(getProcMem(pid));
} catch (Exception e) {
log("Failed invoking getShare method", e);
}
return shared;
}
/**
* Get the amount of available K-bytes for the file system
*
* @param fileSystem The fileSystem name
*
* @return The amount of available K-bytes for the file system, or 0 if not
* available
*/
public long getFileSystemFree(final String fileSystem) {
/*
FileSystemUsage fUse = sigar.getFileSystemUsage(File.separator);
double available = fUse.getFree()*1024;
double used = fUse.getUsed()*1024;
double total = fUse.getTotal()*1024;
*/
checkFileSysemUsageMethods(fileSystem);
if(fileSystemFreeMethod==null)
return (long)NOT_AVAILABLE;
long free = (long)NOT_AVAILABLE;
try {
free = (Long)fileSystemFreeMethod.invoke(getFileSystemUsage(fileSystem));
} catch (Exception e) {
log("Failed invoking getFree method", e);
}
return free;
}
/**
* Get the amount of used K-bytes for the file system
*
* @param fileSystem The fileSystem name
*
* @return The amount of used K-bytes for the file system, or 0 if not
* available
*/
public long getFileSystemUsed(final String fileSystem) {
checkFileSysemUsageMethods(fileSystem);
if(fileSystemUsedMethod==null)
return (long)NOT_AVAILABLE;
long used = (long)NOT_AVAILABLE;
try {
used = (Long)fileSystemUsedMethod.invoke(getFileSystemUsage(fileSystem));
} catch (Exception e) {
log("Failed invoking getUsed method", e);
}
return used;
}
/**
* Get the number of total K-bytes for the file system
*
* @param fileSystem The fileSystem name
*
* @return The number of K-bytes for the file system, or 0 if not
* available
*/
public long getFileSystemTotal(final String fileSystem) {
checkFileSysemUsageMethods(fileSystem);
if(fileSystemTotalMethod==null)
return (long)NOT_AVAILABLE;
long total = (long)NOT_AVAILABLE;
try {
total = (Long)fileSystemTotalMethod.invoke(getFileSystemUsage(fileSystem));
} catch (Exception e) {
log("Failed invoking getUsed method", e);
}
return total;
}
/**
* Get the percentage of disk used
*
* @param fileSystem The fileSystem name
*
* @return The percentage of disk used, or 0 if not available
*/
public double getFileSystemUsedPercent(final String fileSystem) {
checkFileSysemUsageMethods(fileSystem);
if(fileSystemUsedPercentMethod==null)
return NOT_AVAILABLE;
double percent = NOT_AVAILABLE;
try {
percent = (Double)fileSystemUsedPercentMethod.invoke(getFileSystemUsage(fileSystem));
} catch (Exception e) {
log("Failed invoking getUsePercent method", e);
}
return percent;
}
/**
* Get the amount of system RAM.
*
* @return Get the amount of system Random Access Memory (in MB),
* or 0 if not available
*/
public long getRam() {
checkSystemMemoryMethods();
if(getSystemRAMMethod==null)
return (long)NOT_AVAILABLE;
long ram = (long)NOT_AVAILABLE;
try {
ram = (Long)getSystemRAMMethod.invoke(getMem());
} catch (Exception e) {
log("Failed invoking getRam method", e);
}
return ram;
}
/**
* Get the amount of system memory
*
* @return The total amount of system memory (in MB), or 0 if not available
*/
public long getTotalSystemMemory() {
checkSystemMemoryMethods();
if(getSystemMemoryMethod==null)
return (long)NOT_AVAILABLE;
long totalMem = (long)NOT_AVAILABLE;
try {
totalMem = (Long)getSystemMemoryMethod.invoke(getMem());
} catch (Exception e) {
log("Failed invoking getTotal method", e);
}
return totalMem;
}
/**
* Get the percent of free system memory
*
* @return The percent of free system memory, or 0 if not available
*/
public double getFreeSystemMemoryPercent() {
checkSystemMemoryMethods();
if(getFreeMemoryPercentMethod==null)
return NOT_AVAILABLE;
double free = NOT_AVAILABLE;
try {
free = (Double)getFreeMemoryPercentMethod.invoke(getMem());
} catch (Exception e) {
log("Failed invoking getFreePercent method", e);
}
return free;
}
/**
* Get the amount of free system memory
*
* @return The amount of free system memory, or 0 if not available
*/
public long getFreeSystemMemory() {
checkSystemMemoryMethods();
if(getFreeMemoryMethod==null)
return (long)NOT_AVAILABLE;
long free = (long)NOT_AVAILABLE;
try {
free = (Long)getFreeMemoryMethod.invoke(getMem());
} catch (Exception e) {
log("Failed invoking getFreePercent method", e);
}
return free;
}
/**
* Get the percent of used system memory
*
* @return The percent of used system memory, or 0 if not available
*/
public double getUsedSystemMemoryPercent() {
checkSystemMemoryMethods();
if(getUsedMemoryPercentMethod==null)
return NOT_AVAILABLE;
double used = NOT_AVAILABLE;
try {
used = (Double)getUsedMemoryPercentMethod.invoke(getMem());
} catch (Exception e) {
log("Failed invoking getUsedPercent method", e);
}
return used;
}
/**
* Get the amount of used system memory
*
* @return The amount of used system memory (in MB), or 0 if not available
*/
public long getUsedSystemMemory() {
checkSystemMemoryMethods();
if(getUsedMemoryMethod==null)
return (long)NOT_AVAILABLE;
long used = (long)NOT_AVAILABLE;
try {
used = (Long)getUsedMemoryMethod.invoke(getMem());
} catch (Exception e) {
log("Failed invoking getUsed method", e);
}
return used;
}
private void checkGetProcListMethod() {
if(getProcList==null) {
try {
getProcList = getMethod("getProcList");
} catch (NoSuchMethodException e) {
log("Could not obtain getProcList method from SIGAR", e);
}
}
}
private void checkCpuPercMethod() {
if(getCpuPercMethod==null) {
try {
getCpuPercMethod = getMethod("getCpuPerc");
} catch (NoSuchMethodException e) {
log("Could not obtain getCpuPerc method from SIGAR", e);
}
}
}
private void checkProcMemMethod() {
if(getProcMemMethod==null) {
try {
getProcMemMethod = getMethod("getProcMem", long.class);
} catch (NoSuchMethodException e) {
log("Could not obtain getProcMem method from SIGAR", e);
}
}
}
private Object getCpuPerc() {
Object cpuPerc;
try {
synchronized(sigarLock) {
cpuPerc = getCpuPercMethod.invoke(sigarInstance);
}
} catch (Exception e) {
log("Failed invoking getCpuPerc method", e);
return null;
}
return cpuPerc;
}
private Object getProcMem(final long pid) {
Object procMem;
try {
synchronized(sigarLock) {
procMem = getProcMemMethod.invoke(sigarInstance, pid);
}
} catch (Exception e) {
log("Failed invoking getProcMem method", e);
return null;
}
return procMem;
}
private Object getFileSystemUsage(final String fileSystem) {
Object fsu;
try {
synchronized(sigarLock) {
fsu = getFileSystemUsageMethod.invoke(sigarInstance, fileSystem==null?File.separator:fileSystem);
}
} catch (Exception e) {
log("Failed invoking getFileSystemUsage method", e);
return null;
}
return fsu;
}
private void checkFileSysemUsageMethods(final String fileSystem) {
checkFileSystemUsageMethod();
if(getFileSystemUsageMethod==null)
return;
if(fileSystemFreeMethod==null) {
try {
Object fsu = getFileSystemUsage(fileSystem);
if(fsu!=null)
fileSystemFreeMethod = fsu.getClass().getMethod("getFree");
} catch (NoSuchMethodException e) {
log("Could not obtain getFree method", e);
return;
}
}
if(fileSystemUsedMethod==null) {
try {
Object fsu = getFileSystemUsage(fileSystem);
if(fsu!=null)
fileSystemUsedMethod = fsu.getClass().getMethod("getUsed");
} catch (NoSuchMethodException e) {
log("Could not obtain getUsed method", e);
return;
}
}
if(fileSystemTotalMethod==null) {
try {
Object fsu = getFileSystemUsage(fileSystem);
if(fsu!=null)
fileSystemTotalMethod = fsu.getClass().getMethod("getTotal");
} catch (NoSuchMethodException e) {
log("Could not obtain getTotal method", e);
return;
}
}
if(fileSystemUsedPercentMethod==null) {
try {
Object fsu = getFileSystemUsage(fileSystem);
if(fsu!=null)
fileSystemUsedPercentMethod = fsu.getClass().getMethod("getUsePercent");
} catch (NoSuchMethodException e) {
log("Could not obtain getUsePercent method", e);
}
}
}
private void checkFileSystemUsageMethod() {
if(getFileSystemUsageMethod==null) {
try {
getFileSystemUsageMethod = getMethod("getFileSystemUsage", String.class);
} catch (NoSuchMethodException e) {
log("Could not obtain getFileSystemUsage method from SIGAR", e);
}
}
}
private void checkSystemMemoryMethods() {
checkGetMemMethod();
if(getFreeMemoryPercentMethod==null) {
try {
Object mem = getMem();
if (mem != null)
getFreeMemoryPercentMethod = mem.getClass().getMethod("getFreePercent");
} catch (NoSuchMethodException e) {
log("Could not obtain getFreePercent method from "+
getMem().getClass().getName(), e);
}
}
if(getUsedMemoryPercentMethod==null) {
try {
Object mem = getMem();
if (mem != null)
getUsedMemoryPercentMethod = mem.getClass().getMethod("getUsedPercent");
} catch (NoSuchMethodException e) {
log("Could not obtain getUsePercent method from "+
getMem().getClass().getName(),
e);
}
}
if(getSystemRAMMethod==null) {
try {
Object mem = getMem();
if (mem != null)
getSystemRAMMethod =
mem.getClass().getMethod("getRam");
} catch (NoSuchMethodException e) {
log("Could not obtain getRam method from "+getMem().getClass().getName(), e);
}
}
if(getSystemMemoryMethod==null) {
try {
Object mem = getMem();
if (mem != null)
getSystemMemoryMethod = mem.getClass().getMethod("getTotal");
} catch (NoSuchMethodException e) {
log("Could not obtain getTotal method from "+getMem().getClass().getName(), e);
}
}
if(getUsedMemoryMethod==null) {
try {
Object mem = getMem();
if (mem != null)
getUsedMemoryMethod = mem.getClass().getMethod("getUsed");
} catch (NoSuchMethodException e) {
log("Could not obtain getTotal method from "+getMem().getClass().getName(), e);
}
}
if(getFreeMemoryMethod==null) {
try {
Object mem = getMem();
if (mem != null)
getFreeMemoryMethod = mem.getClass().getMethod("getFree");
} catch (NoSuchMethodException e) {
log("Could not obtain getFree method from "+getMem().getClass().getName(), e);
}
}
}
private void checkGetMemMethod() {
try {
if(getMemMethod==null) {
getMemMethod = getMethod("getMem");
}
} catch (NoSuchMethodException e) {
log("Could not obtain getMem method from SIGAR", e);
}
}
private Object getMem() {
Object mem;
checkGetMemMethod();
try {
synchronized(sigarLock) {
mem = getMemMethod.invoke(sigarInstance);
}
} catch (Exception e) {
log("Failed invoking getMem method", e);
return null;
}
return mem;
}
private boolean haveSigar() {
boolean have;
synchronized(sigarLock) {
have = sigarInstance!=null;
}
return have;
}
private Method getMethod(final String methodName, final Class... parameterTypes)
throws NoSuchMethodException {
Method m;
synchronized(sigarLock) {
m = sigarInstance.getClass().getMethod(methodName, parameterTypes);
}
return m;
}
private void log(final String s, final Throwable t) {
if(logger.isDebugEnabled())
logger.debug(s, t);
else
logger.warn("{}. Caused by: {}: {}", s, t.getClass().getName(), t.getMessage());
}
}