Coverage Report - sk.baka.webvm.Graphs
 
Classes in this File Line Coverage Branch Coverage Complexity
Graphs
0%
0/115
0%
0/36
2.636
 
 1  
 /**
 2  
  * Copyright 2009 Martin Vysny.
 3  
  *
 4  
  * This file is part of WebVM.
 5  
  *
 6  
  * WebVM is free software: you can redistribute it and/or modify
 7  
  * it under the terms of the GNU General Public License as published by
 8  
  * the Free Software Foundation, either version 3 of the License, or
 9  
  * (at your option) any later version.
 10  
  *
 11  
  * WebVM is distributed in the hope that it will be useful,
 12  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  
  * GNU General Public License for more details.
 15  
  *
 16  
  * You should have received a copy of the GNU General Public License
 17  
  * along with WebVM.  If not, see <http://www.gnu.org/licenses/>.
 18  
  */
 19  
 package sk.baka.webvm;
 20  
 
 21  
 import java.lang.management.ClassLoadingMXBean;
 22  
 import java.lang.management.ManagementFactory;
 23  
 import java.lang.management.MemoryUsage;
 24  
 import java.lang.management.ThreadMXBean;
 25  
 import sk.baka.webvm.analyzer.HistorySample;
 26  
 import java.util.List;
 27  
 import org.apache.wicket.markup.html.basic.Label;
 28  
 import sk.baka.webvm.analyzer.HistorySampler;
 29  
 import sk.baka.webvm.analyzer.hostos.Cpu;
 30  
 import sk.baka.webvm.analyzer.hostos.Memory;
 31  
 import sk.baka.webvm.misc.AbstractGraph;
 32  
 import sk.baka.webvm.misc.BluffGraph;
 33  
 import sk.baka.webvm.misc.GraphStyle;
 34  
 import sk.baka.webvm.misc.MgmtUtils;
 35  
 
 36  
 /**
 37  
  * Shows the JVM memory usage and GC CPU usage graphs.
 38  
  * @author Martin Vysny
 39  
  */
 40  
 public final class Graphs extends WebVMPage {
 41  
 
 42  
     public static final String GRAPH_BORDER = "black";
 43  
     public static final int GRAPH_HEIGHT_PX = 120;
 44  
     public static final int GRAPH_WIDTH_PX = 300;
 45  
     private static final long serialVersionUID = 1L;
 46  
     /**
 47  
      * The blue color used in graphs.
 48  
      */
 49  
     public static final String COLOR_BLUE = "#7e43b2";
 50  
     /**
 51  
      * The brown color used in graphs.
 52  
      */
 53  
     public static final String COLOR_BROWN = "#ff7f7f";
 54  
     /**
 55  
      * The darkgrey color used in graphs.
 56  
      */
 57  
     public static final String COLOR_DARKGREY = "#888888";
 58  
     public static final String COLOR_WHITE = "#ffffff";
 59  
     public static final String COLOR_GREY = "#999999";
 60  
 
 61  
     /**
 62  
      * Creates the page instance.
 63  
      */
 64  0
     public Graphs() {
 65  0
         final List<HistorySample> history = WicketApplication.getHistory().getVmstatHistory();
 66  0
         drawGcCpuUsage(history);
 67  0
         drawHeap(history);
 68  0
         drawNonHeap(history);
 69  0
         drawClassesGraph(history);
 70  0
         drawThreadsGraph(history);
 71  0
         drawPhysMem(history);
 72  0
         drawSwap(history);
 73  0
         drawHostCpuUsage(history);
 74  0
     }
 75  
 
 76  
     /**
 77  
      * Creates the default telemetry graph style.
 78  
      * @return the graph style.
 79  
      */
 80  
     public static GraphStyle newDefaultStyle() {
 81  0
         final GraphStyle gs = new GraphStyle();
 82  0
         gs.height = GRAPH_HEIGHT_PX;
 83  0
         gs.width = GRAPH_WIDTH_PX;
 84  0
         gs.border = GRAPH_BORDER;
 85  0
         gs.yLegend = true;
 86  0
         return gs;
 87  
     }
 88  
 
 89  
     private void drawClassesGraph(List<HistorySample> history) {
 90  0
         final GraphStyle gs = newDefaultStyle();
 91  0
         gs.colors = new String[]{COLOR_BROWN};
 92  0
         int maxClasses = 0;
 93  0
         for (final HistorySample hs : history) {
 94  0
             if (maxClasses < hs.classesLoaded) {
 95  0
                 maxClasses = hs.classesLoaded;
 96  
             }
 97  
         }
 98  0
         maxClasses = maxClasses * 5 / 4;
 99  0
         final BluffGraph dg = new BluffGraph(maxClasses, gs);
 100  0
         for (final HistorySample hs : history) {
 101  0
             dg.add(new int[]{hs.classesLoaded});
 102  
         }
 103  0
         dg.fillWithZero(HistorySampler.HISTORY_VMSTAT.getHistoryLength(), false);
 104  0
         unescaped("classesGraph", dg.draw());
 105  0
         final ClassLoadingMXBean bean = ManagementFactory.getClassLoadingMXBean();
 106  0
         border.add(new Label("classesCurrentlyLoaded", Integer.toString(bean.getLoadedClassCount())));
 107  0
         border.add(new Label("classesLoadedTotal", Long.toString(bean.getTotalLoadedClassCount())));
 108  0
         border.add(new Label("classesUnloadedTotal", Long.toString(bean.getUnloadedClassCount())));
 109  0
     }
 110  
 
 111  
     private void drawHostCpuUsage(List<HistorySample> history) {
 112  0
         final boolean hostCpu = Cpu.isHostCpuSupported();
 113  0
         final boolean javaCpu = Cpu.isJavaCpuSupported();
 114  0
         final boolean hostIOCpu = Cpu.isHostIOCpuSupported();
 115  0
         if (hostCpu || javaCpu || hostIOCpu) {
 116  0
             final GraphStyle gs = newDefaultStyle();
 117  0
             gs.colors = new String[]{COLOR_BLUE, COLOR_BROWN, COLOR_DARKGREY};
 118  0
             final AbstractGraph dg = new BluffGraph(100, gs);
 119  0
             dg.makeAscending = true;
 120  0
             for (final HistorySample hs : history) {
 121  0
                 dg.add(new int[]{hs.cpuJavaUsage, hs.cpuUsage, hs.cpuIOUsage});
 122  
             }
 123  0
             dg.fillWithZero(HistorySampler.HISTORY_VMSTAT.getHistoryLength(), false);
 124  0
             unescaped("cpuUsageGraph", dg.draw());
 125  0
             final HistorySample last = history.isEmpty() ? new HistorySample(0, 0, 0, 0) : history.get(history.size() - 1);
 126  0
             border.add(new Label("cpuUsagePerc", printValue(hostCpu, last.cpuUsage)));
 127  0
             border.add(new Label("javaCpuUsagePerc", printValue(javaCpu, last.cpuJavaUsage)));
 128  0
             border.add(new Label("iowait", printValue(hostIOCpu, last.cpuIOUsage)));
 129  0
         } else {
 130  0
             add(new Label("cpuUsageGraph", "Both HostOS CPU measurement and Java CPU usage measurement are unsupported on this OS/JavaVM"));
 131  0
             add(new Label("cpuUsagePerc", "-"));
 132  0
             add(new Label("javaCpuUsagePerc", "-"));
 133  0
             add(new Label("iowait", "-"));
 134  
         }
 135  0
     }
 136  
 
 137  
     private static String printValue(final boolean enabled, final int value) {
 138  0
         return enabled ? Integer.toString(value) : "?";
 139  
     }
 140  
 
 141  
     private void drawGcCpuUsage(final List<HistorySample> history) {
 142  0
         final GraphStyle gs = newDefaultStyle();
 143  0
         gs.colors = new String[]{COLOR_BLUE};
 144  0
         final AbstractGraph dg = new BluffGraph(100, gs);
 145  0
         for (final HistorySample hs : history) {
 146  0
             dg.add(new int[]{hs.gcCpuUsage});
 147  
         }
 148  0
         dg.fillWithZero(HistorySampler.HISTORY_VMSTAT.getHistoryLength(), false);
 149  0
         unescaped("gcCPUUsageGraph", dg.draw());
 150  0
         final HistorySample last = history.isEmpty() ? null : history.get(history.size() - 1);
 151  0
         border.add(new Label("gcCPUUsagePerc", last == null ? "?" : Integer.toString(last.gcCpuUsage)));
 152  0
     }
 153  
 
 154  
     private void drawHeap(final List<HistorySample> history) {
 155  0
         drawMemoryUsageGraph(history, "heapUsageGraph", HistorySample.POOL_HEAP);
 156  0
         final MemoryUsage heap = MgmtUtils.getInMB(MgmtUtils.getHeapFromRuntime());
 157  0
         border.add(new Label("heapUsage", Long.toString(heap.getUsed())));
 158  0
         border.add(new Label("heapSize", Long.toString(heap.getCommitted())));
 159  0
     }
 160  
 
 161  
     private void drawNonHeap(final List<HistorySample> history) {
 162  0
         if (MgmtUtils.isNonHeapPool()) {
 163  0
             drawMemoryUsageGraph(history, "nonHeapUsageGraph", HistorySample.POOL_NON_HEAP);
 164  0
             final MemoryUsage nonHeap = MgmtUtils.getInMB(MgmtUtils.getNonHeapSummary());
 165  0
             border.add(new Label("nonHeapUsage", Long.toString(nonHeap.getUsed())));
 166  0
             border.add(new Label("nonHeapSize", Long.toString(nonHeap.getCommitted())));
 167  0
         } else {
 168  0
             border.add(new Label("nonHeapUsageGraph", "No information available"));
 169  0
             border.add(new Label("nonHeapUsage", "-"));
 170  0
             border.add(new Label("nonHeapSize", "-"));
 171  
         }
 172  0
     }
 173  
 
 174  
     private void drawPhysMem(final List<HistorySample> history) {
 175  0
         final MemoryUsage physMem = MgmtUtils.getInMB(Memory.getPhysicalMemory());
 176  0
         if (physMem != null) {
 177  0
             drawMemoryUsageGraph(history, "physUsageGraph", HistorySample.POOL_PHYS_MEM);
 178  0
             border.add(new Label("physCommitted", Long.toString(physMem.getCommitted())));
 179  0
             border.add(new Label("physUsed", Long.toString(physMem.getUsed())));
 180  
         } else {
 181  0
             border.add(new Label("physUsageGraph", "No information available"));
 182  0
             border.add(new Label("physCommitted", "-"));
 183  0
             border.add(new Label("physUsed", "-"));
 184  
         }
 185  0
     }
 186  
 
 187  
     private void drawSwap(final List<HistorySample> history) {
 188  0
         final MemoryUsage swap = MgmtUtils.getInMB(Memory.getSwap());
 189  0
         if (swap != null) {
 190  0
             drawMemoryUsageGraph(history, "swapUsageGraph", HistorySample.POOL_SWAP);
 191  0
             border.add(new Label("swapUsed", Long.toString(swap.getUsed())));
 192  
         } else {
 193  0
             border.add(new Label("swapUsageGraph", "No information available"));
 194  0
             border.add(new Label("swapUsed", "-"));
 195  
         }
 196  0
     }
 197  
 
 198  
     private void drawThreadsGraph(List<HistorySample> history) {
 199  0
         final GraphStyle gs = newDefaultStyle();
 200  0
         gs.colors = new String[]{COLOR_BLUE, COLOR_BROWN};
 201  0
         int maxThreads = 0;
 202  0
         for (final HistorySample hs : history) {
 203  0
             if (maxThreads < hs.threadCount) {
 204  0
                 maxThreads = hs.threadCount;
 205  
             }
 206  
         }
 207  0
         maxThreads = maxThreads * 5 / 4;
 208  0
         final AbstractGraph dg = new BluffGraph(maxThreads, gs);
 209  0
         for (final HistorySample hs : history) {
 210  0
             dg.add(new int[]{hs.daemonThreadCount, hs.threadCount});
 211  
         }
 212  0
         dg.fillWithZero(HistorySampler.HISTORY_VMSTAT.getHistoryLength(), false);
 213  0
         unescaped("threadsGraph", dg.draw());
 214  0
         final ThreadMXBean bean = ManagementFactory.getThreadMXBean();
 215  0
         border.add(new Label("liveThreads", Integer.toString(bean.getThreadCount())));
 216  0
         border.add(new Label("daemonThreads", Long.toString(bean.getDaemonThreadCount())));
 217  0
         border.add(new Label("threadsStartedTotal", Long.toString(bean.getTotalStartedThreadCount())));
 218  0
     }
 219  
 }