|
@@ -25,9 +25,11 @@ import java.io.InputStreamReader;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
import java.math.BigInteger;
|
|
import java.math.BigInteger;
|
|
import java.nio.charset.Charset;
|
|
import java.nio.charset.Charset;
|
|
|
|
+import java.util.HashSet;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
+import com.google.common.annotations.VisibleForTesting;
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.LogFactory;
|
|
import org.apache.commons.logging.LogFactory;
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
@@ -58,41 +60,48 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
private static final String INACTIVE_STRING = "Inactive";
|
|
private static final String INACTIVE_STRING = "Inactive";
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Patterns for parsing /proc/cpuinfo
|
|
|
|
|
|
+ * Patterns for parsing /proc/cpuinfo.
|
|
*/
|
|
*/
|
|
private static final String PROCFS_CPUINFO = "/proc/cpuinfo";
|
|
private static final String PROCFS_CPUINFO = "/proc/cpuinfo";
|
|
private static final Pattern PROCESSOR_FORMAT =
|
|
private static final Pattern PROCESSOR_FORMAT =
|
|
Pattern.compile("^processor[ \t]:[ \t]*([0-9]*)");
|
|
Pattern.compile("^processor[ \t]:[ \t]*([0-9]*)");
|
|
private static final Pattern FREQUENCY_FORMAT =
|
|
private static final Pattern FREQUENCY_FORMAT =
|
|
Pattern.compile("^cpu MHz[ \t]*:[ \t]*([0-9.]*)");
|
|
Pattern.compile("^cpu MHz[ \t]*:[ \t]*([0-9.]*)");
|
|
|
|
+ private static final Pattern PHYSICAL_ID_FORMAT =
|
|
|
|
+ Pattern.compile("^physical id[ \t]*:[ \t]*([0-9]*)");
|
|
|
|
+ private static final Pattern CORE_ID_FORMAT =
|
|
|
|
+ Pattern.compile("^core id[ \t]*:[ \t]*([0-9]*)");
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Pattern for parsing /proc/stat
|
|
|
|
|
|
+ * Pattern for parsing /proc/stat.
|
|
*/
|
|
*/
|
|
private static final String PROCFS_STAT = "/proc/stat";
|
|
private static final String PROCFS_STAT = "/proc/stat";
|
|
private static final Pattern CPU_TIME_FORMAT =
|
|
private static final Pattern CPU_TIME_FORMAT =
|
|
- Pattern.compile("^cpu[ \t]*([0-9]*)" +
|
|
|
|
|
|
+ Pattern.compile("^cpu[ \t]*([0-9]*)" +
|
|
"[ \t]*([0-9]*)[ \t]*([0-9]*)[ \t].*");
|
|
"[ \t]*([0-9]*)[ \t]*([0-9]*)[ \t].*");
|
|
private CpuTimeTracker cpuTimeTracker;
|
|
private CpuTimeTracker cpuTimeTracker;
|
|
|
|
|
|
private String procfsMemFile;
|
|
private String procfsMemFile;
|
|
private String procfsCpuFile;
|
|
private String procfsCpuFile;
|
|
private String procfsStatFile;
|
|
private String procfsStatFile;
|
|
- long jiffyLengthInMillis;
|
|
|
|
|
|
+ private long jiffyLengthInMillis;
|
|
|
|
|
|
private long ramSize = 0;
|
|
private long ramSize = 0;
|
|
private long swapSize = 0;
|
|
private long swapSize = 0;
|
|
private long ramSizeFree = 0; // free ram space on the machine (kB)
|
|
private long ramSizeFree = 0; // free ram space on the machine (kB)
|
|
private long swapSizeFree = 0; // free swap space on the machine (kB)
|
|
private long swapSizeFree = 0; // free swap space on the machine (kB)
|
|
private long inactiveSize = 0; // inactive cache memory (kB)
|
|
private long inactiveSize = 0; // inactive cache memory (kB)
|
|
- private int numProcessors = 0; // number of processors on the system
|
|
|
|
|
|
+ /* number of logical processors on the system. */
|
|
|
|
+ private int numProcessors = 0;
|
|
|
|
+ /* number of physical cores on the system. */
|
|
|
|
+ private int numCores = 0;
|
|
private long cpuFrequency = 0L; // CPU frequency on the system (kHz)
|
|
private long cpuFrequency = 0L; // CPU frequency on the system (kHz)
|
|
|
|
|
|
- boolean readMemInfoFile = false;
|
|
|
|
- boolean readCpuInfoFile = false;
|
|
|
|
|
|
+ private boolean readMemInfoFile = false;
|
|
|
|
+ private boolean readCpuInfoFile = false;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Get current time
|
|
|
|
|
|
+ * Get current time.
|
|
* @return Unix time stamp in millisecond
|
|
* @return Unix time stamp in millisecond
|
|
*/
|
|
*/
|
|
long getCurrentTime() {
|
|
long getCurrentTime() {
|
|
@@ -106,7 +115,7 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
|
|
|
|
/**
|
|
/**
|
|
* Constructor which allows assigning the /proc/ directories. This will be
|
|
* Constructor which allows assigning the /proc/ directories. This will be
|
|
- * used only in unit tests
|
|
|
|
|
|
+ * used only in unit tests.
|
|
* @param procfsMemFile fake file for /proc/meminfo
|
|
* @param procfsMemFile fake file for /proc/meminfo
|
|
* @param procfsCpuFile fake file for /proc/cpuinfo
|
|
* @param procfsCpuFile fake file for /proc/cpuinfo
|
|
* @param procfsStatFile fake file for /proc/stat
|
|
* @param procfsStatFile fake file for /proc/stat
|
|
@@ -124,14 +133,14 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Read /proc/meminfo, parse and compute memory information only once
|
|
|
|
|
|
+ * Read /proc/meminfo, parse and compute memory information only once.
|
|
*/
|
|
*/
|
|
private void readProcMemInfoFile() {
|
|
private void readProcMemInfoFile() {
|
|
readProcMemInfoFile(false);
|
|
readProcMemInfoFile(false);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Read /proc/meminfo, parse and compute memory information
|
|
|
|
|
|
+ * Read /proc/meminfo, parse and compute memory information.
|
|
* @param readAgain if false, read only on the first time
|
|
* @param readAgain if false, read only on the first time
|
|
*/
|
|
*/
|
|
private void readProcMemInfoFile(boolean readAgain) {
|
|
private void readProcMemInfoFile(boolean readAgain) {
|
|
@@ -141,18 +150,20 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
}
|
|
}
|
|
|
|
|
|
// Read "/proc/memInfo" file
|
|
// Read "/proc/memInfo" file
|
|
- BufferedReader in = null;
|
|
|
|
- InputStreamReader fReader = null;
|
|
|
|
|
|
+ BufferedReader in;
|
|
|
|
+ InputStreamReader fReader;
|
|
try {
|
|
try {
|
|
fReader = new InputStreamReader(
|
|
fReader = new InputStreamReader(
|
|
new FileInputStream(procfsMemFile), Charset.forName("UTF-8"));
|
|
new FileInputStream(procfsMemFile), Charset.forName("UTF-8"));
|
|
in = new BufferedReader(fReader);
|
|
in = new BufferedReader(fReader);
|
|
} catch (FileNotFoundException f) {
|
|
} catch (FileNotFoundException f) {
|
|
// shouldn't happen....
|
|
// shouldn't happen....
|
|
|
|
+ LOG.warn("Couldn't read " + procfsMemFile
|
|
|
|
+ + "; can't determine memory settings");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- Matcher mat = null;
|
|
|
|
|
|
+ Matcher mat;
|
|
|
|
|
|
try {
|
|
try {
|
|
String str = in.readLine();
|
|
String str = in.readLine();
|
|
@@ -193,27 +204,31 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Read /proc/cpuinfo, parse and calculate CPU information
|
|
|
|
|
|
+ * Read /proc/cpuinfo, parse and calculate CPU information.
|
|
*/
|
|
*/
|
|
private void readProcCpuInfoFile() {
|
|
private void readProcCpuInfoFile() {
|
|
// This directory needs to be read only once
|
|
// This directory needs to be read only once
|
|
if (readCpuInfoFile) {
|
|
if (readCpuInfoFile) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ HashSet<String> coreIdSet = new HashSet<>();
|
|
// Read "/proc/cpuinfo" file
|
|
// Read "/proc/cpuinfo" file
|
|
- BufferedReader in = null;
|
|
|
|
- InputStreamReader fReader = null;
|
|
|
|
|
|
+ BufferedReader in;
|
|
|
|
+ InputStreamReader fReader;
|
|
try {
|
|
try {
|
|
fReader = new InputStreamReader(
|
|
fReader = new InputStreamReader(
|
|
new FileInputStream(procfsCpuFile), Charset.forName("UTF-8"));
|
|
new FileInputStream(procfsCpuFile), Charset.forName("UTF-8"));
|
|
in = new BufferedReader(fReader);
|
|
in = new BufferedReader(fReader);
|
|
} catch (FileNotFoundException f) {
|
|
} catch (FileNotFoundException f) {
|
|
// shouldn't happen....
|
|
// shouldn't happen....
|
|
|
|
+ LOG.warn("Couldn't read " + procfsCpuFile + "; can't determine cpu info");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- Matcher mat = null;
|
|
|
|
|
|
+ Matcher mat;
|
|
try {
|
|
try {
|
|
numProcessors = 0;
|
|
numProcessors = 0;
|
|
|
|
+ numCores = 1;
|
|
|
|
+ String currentPhysicalId = "";
|
|
String str = in.readLine();
|
|
String str = in.readLine();
|
|
while (str != null) {
|
|
while (str != null) {
|
|
mat = PROCESSOR_FORMAT.matcher(str);
|
|
mat = PROCESSOR_FORMAT.matcher(str);
|
|
@@ -224,6 +239,15 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
if (mat.find()) {
|
|
if (mat.find()) {
|
|
cpuFrequency = (long)(Double.parseDouble(mat.group(1)) * 1000); // kHz
|
|
cpuFrequency = (long)(Double.parseDouble(mat.group(1)) * 1000); // kHz
|
|
}
|
|
}
|
|
|
|
+ mat = PHYSICAL_ID_FORMAT.matcher(str);
|
|
|
|
+ if (mat.find()) {
|
|
|
|
+ currentPhysicalId = str;
|
|
|
|
+ }
|
|
|
|
+ mat = CORE_ID_FORMAT.matcher(str);
|
|
|
|
+ if (mat.find()) {
|
|
|
|
+ coreIdSet.add(currentPhysicalId + " " + str);
|
|
|
|
+ numCores = coreIdSet.size();
|
|
|
|
+ }
|
|
str = in.readLine();
|
|
str = in.readLine();
|
|
}
|
|
}
|
|
} catch (IOException io) {
|
|
} catch (IOException io) {
|
|
@@ -245,12 +269,12 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Read /proc/stat file, parse and calculate cumulative CPU
|
|
|
|
|
|
+ * Read /proc/stat file, parse and calculate cumulative CPU.
|
|
*/
|
|
*/
|
|
private void readProcStatFile() {
|
|
private void readProcStatFile() {
|
|
// Read "/proc/stat" file
|
|
// Read "/proc/stat" file
|
|
- BufferedReader in = null;
|
|
|
|
- InputStreamReader fReader = null;
|
|
|
|
|
|
+ BufferedReader in;
|
|
|
|
+ InputStreamReader fReader;
|
|
try {
|
|
try {
|
|
fReader = new InputStreamReader(
|
|
fReader = new InputStreamReader(
|
|
new FileInputStream(procfsStatFile), Charset.forName("UTF-8"));
|
|
new FileInputStream(procfsStatFile), Charset.forName("UTF-8"));
|
|
@@ -260,7 +284,7 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- Matcher mat = null;
|
|
|
|
|
|
+ Matcher mat;
|
|
try {
|
|
try {
|
|
String str = in.readLine();
|
|
String str = in.readLine();
|
|
while (str != null) {
|
|
while (str != null) {
|
|
@@ -328,6 +352,13 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
return numProcessors;
|
|
return numProcessors;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /** {@inheritDoc} */
|
|
|
|
+ @Override
|
|
|
|
+ public int getNumCores() {
|
|
|
|
+ readProcCpuInfoFile();
|
|
|
|
+ return numCores;
|
|
|
|
+ }
|
|
|
|
+
|
|
/** {@inheritDoc} */
|
|
/** {@inheritDoc} */
|
|
@Override
|
|
@Override
|
|
public long getCpuFrequency() {
|
|
public long getCpuFrequency() {
|
|
@@ -354,9 +385,9 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Test the {@link LinuxResourceCalculatorPlugin}
|
|
|
|
|
|
+ * Test the {@link LinuxResourceCalculatorPlugin}.
|
|
*
|
|
*
|
|
- * @param args
|
|
|
|
|
|
+ * @param args - arguments to this calculator test
|
|
*/
|
|
*/
|
|
public static void main(String[] args) {
|
|
public static void main(String[] args) {
|
|
LinuxResourceCalculatorPlugin plugin = new LinuxResourceCalculatorPlugin();
|
|
LinuxResourceCalculatorPlugin plugin = new LinuxResourceCalculatorPlugin();
|
|
@@ -380,4 +411,13 @@ public class LinuxResourceCalculatorPlugin extends ResourceCalculatorPlugin {
|
|
}
|
|
}
|
|
System.out.println("CPU usage % : " + plugin.getCpuUsage());
|
|
System.out.println("CPU usage % : " + plugin.getCpuUsage());
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ @VisibleForTesting
|
|
|
|
+ void setReadCpuInfoFile(boolean readCpuInfoFileValue) {
|
|
|
|
+ this.readCpuInfoFile = readCpuInfoFileValue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public long getJiffyLengthInMillis() {
|
|
|
|
+ return this.jiffyLengthInMillis;
|
|
|
|
+ }
|
|
}
|
|
}
|