pax_global_header 0000666 0000000 0000000 00000000064 11672477122 0014523 g ustar 00root root 0000000 0000000 52 comment=80f12d088a43fee2fb09732cd7e1bab15cd45456
jenkinsci-extras-memory-monitor-b9edd8f/ 0000775 0000000 0000000 00000000000 11672477122 0020566 5 ustar 00root root 0000000 0000000 jenkinsci-extras-memory-monitor-b9edd8f/pom.xml 0000664 0000000 0000000 00000004613 11672477122 0022107 0 ustar 00root root 0000000 0000000
org.jenkins-ci
jenkins
1.21
4.0.0
memory-monitor
1.7
memory-monitor
Code for monitoring memory/swap usage
maven-jar-plugin
org.jvnet.hudson.MemoryMonitor
maven-assembly-plugin
jar-with-dependencies
org.jvnet.hudson.MemoryMonitor
attached
package
net.java.dev.jna
jna
3.0.3-patch-1
junit
junit
3.8.1
test
MIT License
http://jenkins-ci.org/mit-license
scm:git:git://github.com/jenkinsci/extras-memory-monitor.git
scm:git:git@github.com:jenkinsci/extras-memory-monitor.git
https://github.com/jenkinsci/extras-memory-monitor
m.g.o-public
http://maven.glassfish.org/content/groups/public/
jenkinsci-extras-memory-monitor-b9edd8f/src/ 0000775 0000000 0000000 00000000000 11672477122 0021355 5 ustar 00root root 0000000 0000000 jenkinsci-extras-memory-monitor-b9edd8f/src/main/ 0000775 0000000 0000000 00000000000 11672477122 0022301 5 ustar 00root root 0000000 0000000 jenkinsci-extras-memory-monitor-b9edd8f/src/main/java/ 0000775 0000000 0000000 00000000000 11672477122 0023222 5 ustar 00root root 0000000 0000000 jenkinsci-extras-memory-monitor-b9edd8f/src/main/java/org/ 0000775 0000000 0000000 00000000000 11672477122 0024011 5 ustar 00root root 0000000 0000000 jenkinsci-extras-memory-monitor-b9edd8f/src/main/java/org/jvnet/ 0000775 0000000 0000000 00000000000 11672477122 0025137 5 ustar 00root root 0000000 0000000 jenkinsci-extras-memory-monitor-b9edd8f/src/main/java/org/jvnet/hudson/ 0000775 0000000 0000000 00000000000 11672477122 0026437 5 ustar 00root root 0000000 0000000 AbstractMemoryMonitorImpl.java 0000664 0000000 0000000 00000003733 11672477122 0034357 0 ustar 00root root 0000000 0000000 jenkinsci-extras-memory-monitor-b9edd8f/src/main/java/org/jvnet/hudson /*
* The MIT License
*
* Copyright (c) 2008-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi,
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jvnet.hudson;
/**
* @author Kohsuke Kawaguchi
*/
abstract class AbstractMemoryMonitorImpl extends MemoryMonitor {
protected long parse(String token) {
token = token.toLowerCase().trim();
long multiplier = 1;
if(token.endsWith("b"))
token = cutTail(token);
if(token.endsWith("k")) {
multiplier = 1024L;
token = cutTail(token);
}
if(token.endsWith("m")) {
multiplier = 1024L*1024;
token = cutTail(token);
}
if(token.endsWith("g")) {
multiplier = 1024L*1024*1024;
token = cutTail(token);
}
return (long)(Float.parseFloat(token)*multiplier);
}
protected String cutTail(String token) {
return token.substring(0,token.length()-1);
}
}
jenkinsci-extras-memory-monitor-b9edd8f/src/main/java/org/jvnet/hudson/MemoryMonitor.java 0000664 0000000 0000000 00000007007 11672477122 0032126 0 ustar 00root root 0000000 0000000 /*
* The MIT License
*
* Copyright (c) 2008-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi,
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jvnet.hudson;
import java.io.File;
import java.io.IOException;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Encapsulates how to compute {@link MemoryUsage}.
*
* @author Kohsuke Kawaguchi
*/
public abstract class MemoryMonitor {
/**
* Obtains the memory usage statistics.
*
* @return
* always non-null object.
* @throws IOException
* If the computation fails for some reason.
*/
public abstract MemoryUsage monitor() throws IOException;
/**
* Obtains the {@link MemoryMonitor} implementation suitable
* for the current platform.
*
* @throws IOException
* if no applicable implementation is found.
*/
public static MemoryMonitor get() throws IOException {
if(INSTANCE==null)
INSTANCE = obtain();
return INSTANCE;
}
private static MemoryMonitor obtain() throws IOException {
if(File.pathSeparatorChar==';')
return new Windows();
if(new File("/proc/meminfo").exists())
return new ProcMemInfo(); // Linux has this. Exactly since when, I don't know.
// is 'top' available? if so, use it
try {
Top top = new Top();
top.monitor();
return top;
} catch (Throwable _) {
// fall through next
}
// Solaris?
try {
Solaris solaris = new Solaris();
solaris.monitor();
return solaris;
} catch(Throwable _) {
// next
}
throw new IOException(String.format("No suitable implementation found: os.name=%s os.arch=%s sun.arch.data.model=%s",
System.getProperty("os.name"),System.getProperty("os.arch"),System.getProperty("sun.arch.data.model")));
}
/**
* Main for test
*/
public static void main(String[] args) throws Exception {
Logger l = Logger.getLogger(MemoryMonitor.class.getPackage().getName());
l.setLevel(Level.FINE);
ConsoleHandler h = new ConsoleHandler();
h.setLevel(Level.FINE);
l.addHandler(h);
MemoryMonitor t = get();
System.out.println("implementation is "+t.getClass().getName());
System.out.println(t.monitor());
}
private static volatile MemoryMonitor INSTANCE = null;
}
jenkinsci-extras-memory-monitor-b9edd8f/src/main/java/org/jvnet/hudson/MemoryUsage.java 0000664 0000000 0000000 00000005642 11672477122 0031546 0 ustar 00root root 0000000 0000000 /*
* The MIT License
*
* Copyright (c) 2008-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi,
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jvnet.hudson;
import java.io.IOException;
import java.io.Serializable;
/**
* Memory usage. Immutable.
*
* @author Kohsuke Kawaguchi
*/
public class MemoryUsage implements Serializable {
/**
* Total physical memory of the system, in bytes.
* -1 if unknown.
*/
public final long totalPhysicalMemory;
/**
* Of the total physical memory of the system, available bytes.
* -1 if unknown.
*/
public final long availablePhysicalMemory;
/**
* Total number of swap space in bytes.
* -1 if unknown.
*/
public final long totalSwapSpace;
/**
* Available swap space in bytes.
* -1 if unknown.
*/
public final long availableSwapSpace;
public MemoryUsage(long totalPhysicalMemory, long availablePhysicalMemory, long totalSwapSpace, long availableSwapSpace) {
this.totalPhysicalMemory = totalPhysicalMemory;
this.availablePhysicalMemory = availablePhysicalMemory;
this.totalSwapSpace = totalSwapSpace;
this.availableSwapSpace = availableSwapSpace;
}
MemoryUsage(long[] v) throws IOException {
this(v[0],v[1],v[2],v[3]);
if(!hasData(v))
throw new IOException("No data available");
}
public String toString() {
return String.format("Memory:%d/%dMB Swap:%d/%dMB",
toMB(availablePhysicalMemory),
toMB(totalPhysicalMemory),
toMB(availableSwapSpace),
toMB(totalSwapSpace));
}
private static long toMB(long l) {
return l/(1024*1024);
}
/*package*/ static boolean hasData(long[] values) {
for (long v : values)
if(v!=-1) return true;
return false;
}
private static final long serialVersionUID = 1L;
}
jenkinsci-extras-memory-monitor-b9edd8f/src/main/java/org/jvnet/hudson/ProcMemInfo.java 0000664 0000000 0000000 00000007202 11672477122 0031461 0 ustar 00root root 0000000 0000000 /*
* The MIT License
*
* Copyright (c) 2008-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi,
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jvnet.hudson;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
/**
* {@link MemoryMonitor} implementation that relies in /proc/meminfo
* @author Kohsuke Kawaguchi
*/
final class ProcMemInfo extends MemoryMonitor {
public MemoryUsage monitor() throws IOException {
BufferedReader r = new BufferedReader(new FileReader("/proc/meminfo"));
try {
long[] values = new long[4];
Arrays.fill(values,-1);
String line;
while((line=r.readLine())!=null) {
for( int i=0; i/proc/meminfo that we care about.
*/
private static final String[] HEADERS = new String[] {
"MemTotal:",
"MemFree:",
"SwapTotal:",
"SwapFree:"
};
/**
* I've only seen "1234 kB" notation, but just to be safe.
*/
private static final Suffix[] SUFFIXES = new Suffix[] {
new Suffix("KB",1024),
new Suffix("MB",1024*1024),
new Suffix("GB",1024*1024*1024)
};
private static final Suffix NONE = new Suffix("",1);
private static class Suffix {
final String name;
final long multiplier;
private Suffix(String name, long multiplier) {
this.name = name;
this.multiplier = multiplier;
}
static Suffix find(String line) {
for (Suffix s : SUFFIXES)
if( line.substring(line.length()-s.name.length()).equalsIgnoreCase(s.name) )
return s;
return NONE;
}
}
}
jenkinsci-extras-memory-monitor-b9edd8f/src/main/java/org/jvnet/hudson/Solaris.java 0000664 0000000 0000000 00000010640 11672477122 0030717 0 ustar 00root root 0000000 0000000 /*
* The MIT License
*
* Copyright (c) 2008-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi,
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jvnet.hudson;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* For Solaris, where top(1) is an optional install.
*
* @author Kohsuke Kawaguchi
*/
public class Solaris extends AbstractMemoryMonitorImpl {
@Override
public MemoryUsage monitor() throws IOException {
long[] v = getSwap();
return new MemoryUsage(
getTotalPhysicalMemory(),
getAvailablePhysicalMemory(),
v[0],v[1]
);
}
private long getTotalPhysicalMemory() throws IOException {
Process proc = startProcess("/usr/sbin/prtdiag");
BufferedReader r = new BufferedReader(new InputStreamReader(proc.getInputStream()));
try {
String line;
while ((line=r.readLine())!=null) {
if (line.contains("Memory size:")) {
line = line.substring(line.indexOf(':')+1).trim();
return parse(line);
}
}
return -1;
} finally {
r.close();
}
}
private long getAvailablePhysicalMemory() throws IOException {
Process proc = startProcess("vmstat");
BufferedReader r = new BufferedReader(new InputStreamReader(proc.getInputStream()));
try {
String line;
while ((line=r.readLine())!=null) {
if (NUMBER_ONLY.matcher(line).matches()) {
return Long.parseLong(line.trim().split(" +")[4])*1024;
}
}
return -1;
} finally {
r.close();
}
}
/**
* Returns total/availablae.
*/
private long[] getSwap() throws IOException {
long[] v = new long[]{-1,-1};
Process proc = startProcess("/usr/sbin/swap","-s");
BufferedReader r = new BufferedReader(new InputStreamReader(proc.getInputStream()));
/* output
$ uname -a; swap -s
SunOS kohsuke2 5.9 Generic_112233-12 sun4u sparc SUNW,Sun-Blade-2500 Solaris
total: 800296k bytes allocated + 181784k reserved = 982080k used, 6014528k available
*/
try {
String line = r.readLine().toLowerCase();
Matcher m = USED_SWAP.matcher(line);
if (m.find()) {
v[0] = Long.parseLong(m.group(1))*1024;
}
m = AVAILABLE_SWAP.matcher(line);
if (m.find()) {
v[1] = Long.parseLong(m.group(1))*1024;
}
// we want total/available, not used/available.
if (v[0]!=-1 && v[1]!=-1)
v[0] += v[1];
return v;
} finally {
r.close();
}
}
private Process startProcess(String... cmd) throws IOException {
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process proc = pb.start();
proc.getOutputStream().close();
return proc;
}
private static final Pattern NUMBER_ONLY = Pattern.compile("[0-9 ]+");
private static final Pattern USED_SWAP = Pattern.compile(" ([0-9]+)k used");
private static final Pattern AVAILABLE_SWAP = Pattern.compile(" ([0-9]+)k available");
}
jenkinsci-extras-memory-monitor-b9edd8f/src/main/java/org/jvnet/hudson/Top.java 0000664 0000000 0000000 00000030772 11672477122 0030055 0 ustar 00root root 0000000 0000000 /*
* The MIT License
*
* Copyright (c) 2008-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi, Stephen Wolf
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jvnet.hudson;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* {@link MemoryMonitor} that parses the output from the top command.
* @author Kohsuke Kawaguchi
*/
final class Top extends AbstractMemoryMonitorImpl {
private boolean macOsTopFailed;
private boolean plainTopFailed;
public MemoryUsage monitor() throws IOException {
if(!macOsTopFailed) {
// MacOS X doesn't understand the -b option (for batch mode),
// moreover to run it in a non-terminal one needs to use the "-l1" option
// and to view the swap usage also add the "-S" option.
// This fails probably anywhere except on MacOS X.
MemoryUsage r = monitor("top","-S","-l1");
if(r!=null) return r;
// if this failed, don't make the same mistake again
LOGGER.fine("failed: top -S -l1");
macOsTopFailed=true;
}
if(!plainTopFailed) {
// MacOS X doesn't understand the -b option (for batch mode),
// so first try without any argument. This fails on Ubuntu.
MemoryUsage r = monitor("top");
if(r!=null) return r;
// if this failed, don't make the same mistake again
LOGGER.fine("failed: top");
plainTopFailed=true;
}
// if 'top' w/o any argument fails to obtain data, like Ubuntu,
// then run with the -b option in the hope that it works.
MemoryUsage r = monitor("top","-b");
if(r!=null) return r;
LOGGER.fine("failed: top -b");
// out of luck. bail out
throw new IOException("'top' unavailable");
}
private MemoryUsage monitor(String... args) throws IOException {
ProcessBuilder pb = new ProcessBuilder(args);
pb.redirectErrorStream(true);
Process proc = pb.start();
proc.getOutputStream().close();
// obtain first 16 lines, then kill 'top'
// output is converted to lower case to simplify matching.
List lines = new ArrayList();
{
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line;
while((line=in.readLine())!=null && lines.size()<16) {
line = ESCAPE_SEQUENCE.matcher(line.toLowerCase()).replaceAll("");
LOGGER.fine("| "+line);
lines.add(line);
}
proc.destroy();
in.close();
}
long[] values = new long[6];
Arrays.fill(values,-1);
OUTER:
for( int i=0; i