Skip to content

Commit

Permalink
new graphs: "Used buffered memory" and "% System CPU"
Browse files Browse the repository at this point in the history
  • Loading branch information
evernat committed Oct 28, 2015
1 parent 589ac9a commit 5029404
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 25 deletions.
42 changes: 21 additions & 21 deletions javamelody-core/src/main/java/net/bull/javamelody/Collector.java
Expand Up @@ -383,9 +383,12 @@ private void collectJavaInformations(List<JavaInformations> javaInformationsList
activeThreadCount, activeConnectionCount, usedConnectionCount);
}

// CHECKSTYLE:OFF
private void collectOtherJavaInformations(List<JavaInformations> javaInformationsList)
throws IOException {
// CHECKSTYLE:ON
long usedNonHeapMemory = 0;
long usedBufferedMemory = 0;
int loadedClassesCount = 0;
long garbageCollectionTimeMillis = 0;
long usedPhysicalMemorySize = 0;
Expand All @@ -398,6 +401,7 @@ private void collectOtherJavaInformations(List<JavaInformations> javaInformation
double systemLoadAverage = 0;
long unixOpenFileDescriptorCount = 0;
long freeDiskSpaceInTemp = Long.MAX_VALUE;
double systemCpuLoad = 0;

for (final JavaInformations javaInformations : javaInformationsList) {
final MemoryInformations memoryInformations = javaInformations.getMemoryInformations();
Expand All @@ -410,6 +414,7 @@ private void collectOtherJavaInformations(List<JavaInformations> javaInformation
availableProcessors = add(Math.max(javaInformations.getAvailableProcessors(), 1),
availableProcessors);
usedNonHeapMemory = add(memoryInformations.getUsedNonHeapMemory(), usedNonHeapMemory);
usedBufferedMemory = add(memoryInformations.getUsedBufferedMemory(), usedBufferedMemory);
loadedClassesCount = add(memoryInformations.getLoadedClassesCount(), loadedClassesCount);
usedPhysicalMemorySize = add(memoryInformations.getUsedPhysicalMemorySize(),
usedPhysicalMemorySize);
Expand All @@ -426,6 +431,7 @@ private void collectOtherJavaInformations(List<JavaInformations> javaInformation
freeDiskSpaceInTemp = Math.min(javaInformations.getFreeDiskSpaceInTemp(),
freeDiskSpaceInTemp);
}
systemCpuLoad = add(javaInformations.getSystemCpuLoad(), systemCpuLoad);

This comment has been minimized.

Copy link
@bpedersen2

bpedersen2 Sep 23, 2016

This function is not supported on FreeBSD, see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=205229

}

// collecte du pourcentage de temps en ramasse-miette
Expand All @@ -438,8 +444,21 @@ private void collectOtherJavaInformations(List<JavaInformations> javaInformation
this.gcTimeMillis = garbageCollectionTimeMillis;
}

collectOtherJRobinsValues(usedNonHeapMemory, loadedClassesCount, usedPhysicalMemorySize,
usedSwapSpaceSize, threadCount, systemLoadAverage, unixOpenFileDescriptorCount);
final Map<String, Double> otherJRobinsValues = new LinkedHashMap<String, Double>();
otherJRobinsValues.put("threadCount", (double) threadCount);
otherJRobinsValues.put("loadedClassesCount", (double) loadedClassesCount);
otherJRobinsValues.put("usedBufferedMemory", (double) usedBufferedMemory);
otherJRobinsValues.put("usedNonHeapMemory", (double) usedNonHeapMemory);
otherJRobinsValues.put("usedPhysicalMemorySize", (double) usedPhysicalMemorySize);
otherJRobinsValues.put("usedSwapSpaceSize", (double) usedSwapSpaceSize);
otherJRobinsValues.put("systemLoad", systemLoadAverage);
otherJRobinsValues.put("systemCpuLoad", systemCpuLoad / javaInformationsList.size());
otherJRobinsValues.put("fileDescriptors", (double) unixOpenFileDescriptorCount);
for (final Map.Entry<String, Double> entry : otherJRobinsValues.entrySet()) {
if (entry.getValue() >= 0) {
getOtherJRobin(entry.getKey()).addValue(entry.getValue());
}
}

collectSessionsMeanAge(sessionAgeSum, sessionCount);

Expand Down Expand Up @@ -543,25 +562,6 @@ private void collectTomcatValues(int tomcatBusyThreads, long bytesReceived, long
this.tomcatBytesSent = bytesSent;
}

private void collectOtherJRobinsValues(long usedNonHeapMemory, int loadedClassesCount,
long usedPhysicalMemorySize, long usedSwapSpaceSize, int threadCount,
double systemLoadAverage, long unixOpenFileDescriptorCount) throws IOException {
final Map<String, Double> otherJRobinsValues = new LinkedHashMap<String, Double>();
otherJRobinsValues.put("threadCount", (double) threadCount);
otherJRobinsValues.put("loadedClassesCount", (double) loadedClassesCount);
otherJRobinsValues.put("usedNonHeapMemory", (double) usedNonHeapMemory);
otherJRobinsValues.put("usedPhysicalMemorySize", (double) usedPhysicalMemorySize);
otherJRobinsValues.put("usedSwapSpaceSize", (double) usedSwapSpaceSize);
otherJRobinsValues.put("systemLoad", systemLoadAverage);
otherJRobinsValues.put("fileDescriptors", (double) unixOpenFileDescriptorCount);

for (final Map.Entry<String, Double> entry : otherJRobinsValues.entrySet()) {
if (entry.getValue() >= 0) {
getOtherJRobin(entry.getKey()).addValue(entry.getValue());
}
}
}

private void collectSessionsMeanAge(long sessionAgeSum, int sessionCount) throws IOException {
if (sessionCount >= 0 && getCounterByName(Counter.HTTP_COUNTER_NAME) != null) {
final long sessionAgeMeanInMinutes;
Expand Down
Expand Up @@ -72,7 +72,7 @@ void toHtml() throws IOException {
write(br);
}
// pour l'alignement le nb de br doit correspondre au nb de lignes dans le résumé ci-dessus
writeln("<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
writeln("<br/><br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
writeShowHideLink("detailsJava", "#Details#");
writeln("<br/><br/><br/>");
// div interne pour showHideLink
Expand Down Expand Up @@ -127,6 +127,13 @@ private void writeSummary(JavaInformations javaInformations) throws IOException
writeGraph("systemLoad", decimalFormat.format(javaInformations.getSystemLoadAverage()));
writeln(columnAndLineEnd);
}
if (javaInformations.getSystemCpuLoad() >= 0) {
write("<tr><td>#systemCpuLoad#</td><td>");
writeGraph("systemCpuLoad", decimalFormat.format(javaInformations.getSystemCpuLoad()));
writeln("&nbsp;&nbsp;&nbsp;</td><td>");
writeln(toBarWithAlert(javaInformations.getSystemCpuLoad(), null));
writeln(lineEnd);
}
writeln("</table>");
}

Expand Down
Expand Up @@ -50,6 +50,7 @@ class JavaInformations implements Serializable { // NOPMD
static final double HIGH_USAGE_THRESHOLD_IN_PERCENTS = 95d;
private static final long serialVersionUID = 3281861236369720876L;
private static final Date START_DATE = new Date();
private static final boolean SYSTEM_CPU_LOAD_ENABLED = "1.7".compareTo(Parameters.JAVA_VERSION) < 0;
private static boolean localWebXmlExists = true; // true par défaut
private static boolean localPomXmlExists = true; // true par défaut
private final MemoryInformations memoryInformations;
Expand All @@ -64,6 +65,7 @@ class JavaInformations implements Serializable { // NOPMD
private final long transactionCount;
private final long processCpuTimeMillis;
private final double systemLoadAverage;
private final double systemCpuLoad;
private final long unixOpenFileDescriptorCount;
private final long unixMaxFileDescriptorCount;
private final String host;
Expand Down Expand Up @@ -141,6 +143,7 @@ public int compare(JobInformations job1, JobInformations job2) {
maxConnectionCount = JdbcWrapper.getMaxConnectionCount();
transactionCount = JdbcWrapper.getTransactionCount();
systemLoadAverage = buildSystemLoadAverage();
systemCpuLoad = buildSystemCpuLoad();
processCpuTimeMillis = buildProcessCpuTimeMillis();
unixOpenFileDescriptorCount = buildOpenFileDescriptorCount();
unixMaxFileDescriptorCount = buildMaxFileDescriptorCount();
Expand Down Expand Up @@ -261,6 +264,21 @@ private static long buildMaxFileDescriptorCount() {
return -1;
}

private static double buildSystemCpuLoad() {
// System cpu load.
// The "recent cpu usage" for the whole system.
// This value is a double in the [0.0,1.0] interval.
// A value of 0.0 means that all CPUs were idle during the recent period of time observed,
// while a value of 1.0 means that all CPUs were actively running 100% of the time during the recent period being observed.
final OperatingSystemMXBean operatingSystem = ManagementFactory.getOperatingSystemMXBean();
if (SYSTEM_CPU_LOAD_ENABLED && isSunOsMBean(operatingSystem)) {
// systemCpuLoad n'existe qu'à partir du jdk 1.7
return MemoryInformations.getDoubleFromOperatingSystem(operatingSystem,
"getSystemCpuLoad") * 100;
}
return -1;
}

private static double buildSystemLoadAverage() {
// System load average for the last minute.
// The system load average is the sum of
Expand Down Expand Up @@ -540,6 +558,10 @@ long getProcessCpuTimeMillis() {
return systemLoadAverage;
}

double getSystemCpuLoad() {
return systemCpuLoad;
}

long getUnixOpenFileDescriptorCount() {
return unixOpenFileDescriptorCount;
}
Expand Down
4 changes: 4 additions & 0 deletions javamelody-core/src/main/java/net/bull/javamelody/MBeans.java
Expand Up @@ -80,6 +80,10 @@ Set<ObjectName> getTomcatGlobalRequestProcessors() throws MalformedObjectNameExc
return mbeanServer.queryNames(new ObjectName("*:type=GlobalRequestProcessor,*"), null);
}

Set<ObjectName> getNioBufferPools() throws MalformedObjectNameException {
return mbeanServer.queryNames(new ObjectName("java.nio:type=BufferPool,*"), null);
}

Object getAttribute(ObjectName name, String attribute) throws JMException {
return mbeanServer.getAttribute(name, attribute);
}
Expand Down
Expand Up @@ -26,6 +26,12 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.HashSet;
import java.util.Set;

import javax.management.JMException;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

/**
* Informations systèmes sur la mémoire du serveur, sans code html de présentation.
Expand All @@ -39,6 +45,15 @@ class MemoryInformations implements Serializable {
private static final long serialVersionUID = 3281861236369720876L;
private static final String NEXT = ",\n";
private static final String MO = " Mo";
private static final Set<ObjectName> NIO_BUFFER_POOLS = new HashSet<ObjectName>();
static {
try {
NIO_BUFFER_POOLS.addAll(new MBeans().getNioBufferPools());
} catch (final MalformedObjectNameException e) {
LOG.debug(e.toString());
}
}

// usedMemory est la mémoire utilisée du heap (voir aussi non heap dans gestion mémoire)
private final long usedMemory;
// maxMemory est la mémoire maximum pour le heap (paramètre -Xmx1024m par exemple)
Expand All @@ -48,6 +63,7 @@ class MemoryInformations implements Serializable {
// maxPermGen est la mémoire maximum pour "Perm Gen" (paramètre -XX:MaxPermSize=128m par exemple)
private final long maxPermGen;
private final long usedNonHeapMemory;
private final long usedBufferedMemory;
private final int loadedClassesCount;
private final long garbageCollectionTimeMillis;
private final long usedPhysicalMemorySize;
Expand All @@ -68,6 +84,7 @@ class MemoryInformations implements Serializable {
maxPermGen = -1;
}
usedNonHeapMemory = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getUsed();
usedBufferedMemory = getUsedBufferMemory();
loadedClassesCount = ManagementFactory.getClassLoadingMXBean().getLoadedClassCount();
garbageCollectionTimeMillis = buildGarbageCollectionTimeMillis();

Expand Down Expand Up @@ -96,6 +113,24 @@ private static MemoryPoolMXBean getPermGenMemoryPool() {
return null;
}

private static long getUsedBufferMemory() {
if (NIO_BUFFER_POOLS.isEmpty()) {
return -1;
}
long result = 0;
final MBeans mBeans = new MBeans();
try {
for (final ObjectName objectName : NIO_BUFFER_POOLS) {
// adds direct and mapped buffers
result += (Long) mBeans.getAttribute(objectName, "MemoryUsed");
}
} catch (final JMException e) {
// n'est pas censé arriver
throw new IllegalStateException(e);
}
return result;
}

private static long buildGarbageCollectionTimeMillis() {
long garbageCollectionTime = 0;
for (final GarbageCollectorMXBean garbageCollector : ManagementFactory
Expand Down Expand Up @@ -140,8 +175,13 @@ private String buildMemoryDetails() {
+ integerFormat.format(getLongFromOperatingSystem(operatingSystem,
"getTotalSwapSpaceSize") / 1024 / 1024) + MO;
}

return nonHeapMemory + NEXT + classLoading + NEXT + gc + NEXT + osInfo;
if (usedBufferedMemory < 0) {
return nonHeapMemory + NEXT + classLoading + NEXT + gc + NEXT + osInfo;
}
final String bufferedMemory = "Buffered memory = "
+ integerFormat.format(usedBufferedMemory / 1024 / 1024) + MO;
return nonHeapMemory + NEXT + bufferedMemory + NEXT + classLoading + NEXT + gc + NEXT
+ osInfo;
}

private static boolean isSunOsMBean(OperatingSystemMXBean operatingSystem) {
Expand All @@ -155,11 +195,20 @@ private static boolean isSunOsMBean(OperatingSystemMXBean operatingSystem) {
}

static long getLongFromOperatingSystem(OperatingSystemMXBean operatingSystem, String methodName) {
return (Long) getFromOperatingSystem(operatingSystem, methodName);
}

static double getDoubleFromOperatingSystem(OperatingSystemMXBean operatingSystem,
String methodName) {
return (Double) getFromOperatingSystem(operatingSystem, methodName);
}

static Object getFromOperatingSystem(OperatingSystemMXBean operatingSystem, String methodName) {
try {
final Method method = operatingSystem.getClass().getMethod(methodName,
(Class<?>[]) null);
method.setAccessible(true);
return (Long) method.invoke(operatingSystem, (Object[]) null);
return method.invoke(operatingSystem, (Object[]) null);
} catch (final InvocationTargetException e) {
if (e.getCause() instanceof Error) {
throw (Error) e.getCause();
Expand Down Expand Up @@ -205,6 +254,10 @@ long getUsedNonHeapMemory() {
return usedNonHeapMemory;
}

long getUsedBufferedMemory() {
return usedBufferedMemory;
}

int getLoadedClassesCount() {
return loadedClassesCount;
}
Expand Down
Expand Up @@ -319,9 +319,11 @@ usedMemory=Used memory
cpu=% CPU
gc=% Garbage Collector time
systemLoad=System load
systemCpuLoad=% System CPU
fileDescriptors=Nb of opened files
threadCount=Threads count
loadedClassesCount=Loaded classes count
usedBufferedMemory=Used buffered memory
usedNonHeapMemory=Used non heap memory
usedPhysicalMemorySize=Used physical memory
usedSwapSpaceSize=Used swap space
Expand Down
Expand Up @@ -320,9 +320,11 @@ usedMemory=Speichernutzung
cpu=% CPU
gc=% Zeit für Speicherbereinigung
systemLoad=Systemauslastung
systemCpuLoad=% System CPU
fileDescriptors=Anzahl offene Dateien
threadCount=Anzahl Threads
loadedClassesCount=Anzahl geladene Klassen
usedBufferedMemory=Used buffered memory
usedNonHeapMemory=Speichernutzung Non-Heap
usedPhysicalMemorySize=Nutzung physischer Speicher
usedSwapSpaceSize=Nutzung Swap-Speicher
Expand Down
Expand Up @@ -319,9 +319,11 @@ usedMemory=M
cpu=% CPU
gc=% temps ramasse miette
systemLoad=Charge système
systemCpuLoad=% CPU système
fileDescriptors=Nb de fichiers ouverts
threadCount=Nombre de threads
loadedClassesCount=Nombre de classes chargées
usedBufferedMemory=Mémoire buffered utilisée
usedNonHeapMemory=Mémoire utilisée hors tas
usedPhysicalMemorySize=Mémoire physique utilisée
usedSwapSpaceSize=Espace swap utilisé
Expand Down
Expand Up @@ -323,9 +323,11 @@ usedMemory=Mem
cpu=% CPU
gc=% Tempo Coletor de lixo
systemLoad=Carga do sistema
systemCpuLoad=% System CPU
fileDescriptors=Nro de arquivos abertos
threadCount=Contagem de threads
loadedClassesCount=Classes carregadas
usedBufferedMemory=Used buffered memory
usedNonHeapMemory=Memória não heap usada
usedPhysicalMemorySize=Memória física usada
usedSwapSpaceSize=Espaço de swap usado
Expand Down
Expand Up @@ -778,6 +778,8 @@ sur = \u5728{0}

systemLoad = \u7CFB\u7EDF\u52A0\u8F7D

systemCpuLoad=% System CPU

taille_moyenne_sessions = \u5E73\u5747sessions\u7684\u5927\u5C0F : {0} bytes

temps_affichage = \u663E\u793A\u65F6\u95F4
Expand Down Expand Up @@ -814,6 +816,8 @@ urls_format = URL(s) \u5E94\u8BE5\u4EE5 http:// or https://\u5F00\u59CB

urls_sample = URL(s) \u4F8B\u5B50

usedBufferedMemory=Used buffered memory

usedConnections = \u88AB\u4F7F\u7528\u7684jdbc\u8FDE\u63A5\u6570

usedMemory = \u88AB\u7528\u7684\u5185\u5B58
Expand Down

0 comments on commit 5029404

Please sign in to comment.