eu.stratosphere.nephele.profiling.impl.InstanceProfiler Maven / Gradle / Ivy
/***********************************************************************************************************************
* Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
*
* 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 eu.stratosphere.nephele.profiling.impl;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import eu.stratosphere.nephele.instance.InstanceConnectionInfo;
import eu.stratosphere.nephele.profiling.ProfilingException;
import eu.stratosphere.nephele.profiling.impl.types.InternalInstanceProfilingData;
import eu.stratosphere.util.StringUtils;
public class InstanceProfiler {
static final String PROC_MEMINFO = "/proc/meminfo";
static final String PROC_STAT = "/proc/stat";
static final String PROC_NET_DEV = "/proc/net/dev";
private static final String LOOPBACK_INTERFACE_NAME = "lo";
private static final Pattern CPU_PATTERN = Pattern
.compile("^cpu\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+).+$");
private static final Pattern NETWORK_PATTERN = Pattern
.compile("^\\s*(\\w+):\\s*(\\d+)\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+\\d+\\s+(\\d+).+$");
private static final Pattern MEMORY_PATTERN = Pattern.compile("^\\w+:\\s*(\\d+)\\s+kB$");
private static final int PERCENT = 100;
private final InstanceConnectionInfo instanceConnectionInfo;
private long lastTimestamp = 0;
// CPU related variables
private long lastCpuUser = 0;
private long lastCpuNice = 0;
private long lastCpuSys = 0;
private long lastCpuIdle = 0;
private long lastCpuIOWait = 0;
private long lastCpuIrq = 0;
private long lastCpuSoftirq = 0;
// Network related variables
private long lastReceivedBytes = 0;
private long lastTramsmittedBytes = 0;
private long firstTimestamp;
public InstanceProfiler(InstanceConnectionInfo instanceConnectionInfo)
throws ProfilingException {
this.instanceConnectionInfo = instanceConnectionInfo;
this.firstTimestamp = System.currentTimeMillis();
// Initialize counters by calling generateProfilingData once and ignore the return value
generateProfilingData(this.firstTimestamp);
}
InternalInstanceProfilingData generateProfilingData(long timestamp) throws ProfilingException {
final long profilingInterval = timestamp - lastTimestamp;
final InternalInstanceProfilingData profilingData = new InternalInstanceProfilingData(
this.instanceConnectionInfo, (int) profilingInterval);
updateCPUUtilization(profilingData);
updateMemoryUtilization(profilingData);
updateNetworkUtilization(profilingData);
// Update timestamp
this.lastTimestamp = timestamp;
return profilingData;
}
private void updateMemoryUtilization(InternalInstanceProfilingData profilingData) throws ProfilingException {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(PROC_MEMINFO));
long freeMemory = 0;
long totalMemory = 0;
long bufferedMemory = 0;
long cachedMemory = 0;
long cachedSwapMemory = 0;
int count = 0;
String output;
while ((output = in.readLine()) != null) {
switch (count) {
case 0: // Total memory
totalMemory = extractMemoryValue(output);
break;
case 1: // Free memory
freeMemory = extractMemoryValue(output);
break;
case 2: // Buffers
bufferedMemory = extractMemoryValue(output);
break;
case 3: // Cache
cachedMemory = extractMemoryValue(output);
break;
case 4:
cachedSwapMemory = extractMemoryValue(output);
break;
default:
break;
}
++count;
}
profilingData.setTotalMemory(totalMemory);
profilingData.setFreeMemory(freeMemory);
profilingData.setBufferedMemory(bufferedMemory);
profilingData.setCachedMemory(cachedMemory);
profilingData.setCachedSwapMemory(cachedSwapMemory);
} catch (IOException ioe) {
throw new ProfilingException("Error while reading network utilization: "
+ StringUtils.stringifyException(ioe));
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
}
private long extractMemoryValue(String line) throws ProfilingException {
final Matcher matcher = MEMORY_PATTERN.matcher(line);
if (!matcher.matches()) {
throw new ProfilingException("Cannot extract memory data for profiling from line " + line);
}
return Long.parseLong(matcher.group(1));
}
private void updateNetworkUtilization(InternalInstanceProfilingData profilingData) throws ProfilingException {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(PROC_NET_DEV));
long receivedSum = 0;
long transmittedSum = 0;
String output;
while ((output = in.readLine()) != null) {
final Matcher networkMatcher = NETWORK_PATTERN.matcher(output);
if (!networkMatcher.matches()) {
continue;
}
/*
* Extract information according to
* http://linuxdevcenter.com/pub/a/linux/2000/11/16/LinuxAdmin.html
*/
if (LOOPBACK_INTERFACE_NAME.equals(networkMatcher.group(1))) {
continue;
}
receivedSum += Long.parseLong(networkMatcher.group(2));
transmittedSum += Long.parseLong(networkMatcher.group(3));
}
in.close();
in = null;
profilingData.setReceivedBytes(receivedSum - this.lastReceivedBytes);
profilingData.setTransmittedBytes(transmittedSum - this.lastTramsmittedBytes);
// Store values for next call
this.lastReceivedBytes = receivedSum;
this.lastTramsmittedBytes = transmittedSum;
} catch (IOException ioe) {
throw new ProfilingException("Error while reading network utilization: "
+ StringUtils.stringifyException(ioe));
} catch (NumberFormatException nfe) {
throw new ProfilingException("Error while reading network utilization: "
+ StringUtils.stringifyException(nfe));
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
}
private void updateCPUUtilization(InternalInstanceProfilingData profilingData) throws ProfilingException {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(PROC_STAT));
final String output = in.readLine();
if (output == null) {
throw new ProfilingException("Cannot read CPU utilization, return value is null");
}
in.close();
in = null;
final Matcher cpuMatcher = CPU_PATTERN.matcher(output);
if (!cpuMatcher.matches()) {
throw new ProfilingException("Cannot extract CPU utilization from output \"" + output + "\"");
}
/*
* Extract the information from the read line according to
* http://www.linuxhowtos.org/System/procstat.htm
*/
final long cpuUser = Long.parseLong(cpuMatcher.group(1));
final long cpuNice = Long.parseLong(cpuMatcher.group(2));
final long cpuSys = Long.parseLong(cpuMatcher.group(3));
final long cpuIdle = Long.parseLong(cpuMatcher.group(4));
final long cpuIOWait = Long.parseLong(cpuMatcher.group(5));
final long cpuIrq = Long.parseLong(cpuMatcher.group(6));
final long cpuSoftirq = Long.parseLong(cpuMatcher.group(7));
// Calculate deltas
final long deltaCpuUser = cpuUser - this.lastCpuUser;
final long deltaCpuNice = cpuNice - this.lastCpuNice;
final long deltaCpuSys = cpuSys - this.lastCpuSys;
final long deltaCpuIdle = cpuIdle - this.lastCpuIdle;
final long deltaCpuIOWait = cpuIOWait - this.lastCpuIOWait;
final long deltaCpuIrq = cpuIrq - this.lastCpuIrq;
final long deltaCpuSoftirq = cpuSoftirq - this.lastCpuSoftirq;
final long deltaSum = deltaCpuUser + deltaCpuNice + deltaCpuSys + deltaCpuIdle + deltaCpuIOWait
+ deltaCpuIrq + deltaCpuSoftirq;
// TODO: Fix deltaSum = 0 situation
// Set the percentage values for the profiling data object
/*
* profilingData.setIdleCPU((int)((deltaCpuIdle*PERCENT)/deltaSum));
* profilingData.setUserCPU((int)((deltaCpuUser*PERCENT)/deltaSum));
* profilingData.setSystemCPU((int)((deltaCpuSys*PERCENT)/deltaSum));
* profilingData.setIoWaitCPU((int)((deltaCpuIOWait*PERCENT)/deltaSum));
* profilingData.setHardIrqCPU((int)((deltaCpuIrq*PERCENT)/deltaSum));
* profilingData.setSoftIrqCPU((int)((deltaCpuSoftirq*PERCENT)/deltaSum));
*/
// TODO: bad quick fix
if (deltaSum > 0) {
profilingData.setIdleCPU((int) ((deltaCpuIdle * PERCENT) / deltaSum));
profilingData.setUserCPU((int) ((deltaCpuUser * PERCENT) / deltaSum));
profilingData.setSystemCPU((int) ((deltaCpuSys * PERCENT) / deltaSum));
profilingData.setIoWaitCPU((int) ((deltaCpuIOWait * PERCENT) / deltaSum));
profilingData.setHardIrqCPU((int) ((deltaCpuIrq * PERCENT) / deltaSum));
profilingData.setSoftIrqCPU((int) ((deltaCpuSoftirq * PERCENT) / deltaSum));
} else {
profilingData.setIdleCPU((int) (deltaCpuIdle));
profilingData.setUserCPU((int) (deltaCpuUser));
profilingData.setSystemCPU((int) (deltaCpuSys));
profilingData.setIoWaitCPU((int) (deltaCpuIOWait));
profilingData.setHardIrqCPU((int) (deltaCpuIrq));
profilingData.setSoftIrqCPU((int) (deltaCpuSoftirq));
}
// Store values for next call
this.lastCpuUser = cpuUser;
this.lastCpuNice = cpuNice;
this.lastCpuSys = cpuSys;
this.lastCpuIdle = cpuIdle;
this.lastCpuIOWait = cpuIOWait;
this.lastCpuIrq = cpuIrq;
this.lastCpuSoftirq = cpuSoftirq;
} catch (IOException ioe) {
throw new ProfilingException("Error while reading CPU utilization: " + StringUtils.stringifyException(ioe));
} catch (NumberFormatException nfe) {
throw new ProfilingException("Error while reading CPU utilization: " + StringUtils.stringifyException(nfe));
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
}
/**
* @return InternalInstanceProfilingData ProfilingData for the instance from execution-start to currentTime
* @throws ProfilingException
*/
public InternalInstanceProfilingData generateCheckpointProfilingData() throws ProfilingException {
final long profilingInterval = System.currentTimeMillis() - this.firstTimestamp;
final InternalInstanceProfilingData profilingData = new InternalInstanceProfilingData(
this.instanceConnectionInfo, (int) profilingInterval);
updateCPUUtilization(profilingData);
updateMemoryUtilization(profilingData);
updateNetworkUtilization(profilingData);
return profilingData;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy