12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.tools.jconsole; 27 28 import java.awt.*; 29 import java.io.*; 30 import java.lang.management.*; 31 import java.lang.reflect.*; 32 import java.net.URL; 33 import java.text.*; 34 import java.util.*; 35 import java.util.concurrent.*; 36 37 import javax.swing.*; 38 import javax.swing.event.*; 39 import javax.swing.text.*; 40 41 import static sun.tools.jconsole.Formatter.*; 42 import static sun.tools.jconsole.Resources.*; 43 import static sun.tools.jconsole.Utilities.*; 44 45 @SuppressWarnings("serial") 46 class SummaryTab extends Tab { 47 private static final String cpuUsageKey = "cpu"; 48 private static final String cpuUsageName = getText("CPU Usage"); 49 private static final String cpuUsageFormat = "CPUUsageFormat"; 50 51 private static final String newDivider = "<tr><td colspan=4><font size =-1><hr>"; 52 private static final String newTable = "<tr><td colspan=4 align=left><table cellpadding=1>"; 53 private static final String newLeftTable = "<tr><td colspan=2 align=left><table cellpadding=1>"; 54 private static final String newRightTable = "<td colspan=2 align=left><table cellpadding=1>"; 55 private static final String endTable = "</table>"; 56 57 private static final int CPU_DECIMALS = 1; 58 59 private CPUOverviewPanel overviewPanel; 60 private DateFormat headerDateTimeFormat; 61 private String pathSeparator = null; 62 HTMLPane info; 63 64 private static class Result { 65 long upTime = -1L; 66 long processCpuTime = -1L; 67 long timeStamp; 68 int nCPUs; 69 String summary; 70 } 71 72 public static String getTabName() { 73 return Resources.getText("SummaryTab.tabName"); 74 } 75 76 public SummaryTab(VMPanel vmPanel) { 77 super(vmPanel, getTabName()); 78 79 setLayout(new BorderLayout()); 80 81 info = new HTMLPane(); 82 setAccessibleName(info, getTabName()); 83 add(new JScrollPane(info)); 84 85 headerDateTimeFormat = 86 getDateTimeFormat("SummaryTab.headerDateTimeFormat"); 87 } 88 89 public SwingWorker<?, ?> newSwingWorker() { 90 return new SwingWorker<Result, Object>() { 91 public Result doInBackground() { 92 return formatSummary(); 93 } 94 95 96 protected void done() { 97 try { 98 Result result = get(); 99 if (result != null) { 100 info.setText(result.summary); 101 if (overviewPanel != null && 102 result.upTime > 0L && 103 result.processCpuTime >= 0L) { 104 105 overviewPanel.updateCPUInfo(result); 106 } 121 Result result = new Result(); 122 ProxyClient proxyClient = vmPanel.getProxyClient(); 123 if (proxyClient.isDead()) { 124 return null; 125 } 126 127 buf = new StringBuilder(); 128 append("<table cellpadding=1>"); 129 130 try { 131 RuntimeMXBean rmBean = proxyClient.getRuntimeMXBean(); 132 CompilationMXBean cmpMBean = proxyClient.getCompilationMXBean(); 133 ThreadMXBean tmBean = proxyClient.getThreadMXBean(); 134 MemoryMXBean memoryBean = proxyClient.getMemoryMXBean(); 135 ClassLoadingMXBean clMBean = proxyClient.getClassLoadingMXBean(); 136 OperatingSystemMXBean osMBean = proxyClient.getOperatingSystemMXBean(); 137 com.sun.management.OperatingSystemMXBean sunOSMBean = 138 proxyClient.getSunOperatingSystemMXBean(); 139 140 append("<tr><td colspan=4>"); 141 append("<center><b>" + getText("SummaryTab.tabName") + "</b></center>"); 142 String dateTime = 143 headerDateTimeFormat.format(System.currentTimeMillis()); 144 append("<center>" + dateTime + "</center>"); 145 146 append(newDivider); 147 148 { // VM info 149 append(newLeftTable); 150 append("Connection name", vmPanel.getDisplayName()); 151 append("Virtual Machine", 152 getText("SummaryTab.vmVersion", 153 rmBean.getVmName(), rmBean.getVmVersion())); 154 append("Vendor", rmBean.getVmVendor()); 155 append("Name", rmBean.getName()); 156 append(endTable); 157 158 append(newRightTable); 159 result.upTime = rmBean.getUptime(); 160 append("Uptime", formatTime(result.upTime)); 161 if (sunOSMBean != null) { 162 result.processCpuTime = sunOSMBean.getProcessCpuTime(); 163 append("Process CPU time", formatNanoTime(result.processCpuTime)); 164 } 165 166 if (cmpMBean != null) { 167 append("JIT compiler", cmpMBean.getName()); 168 append("Total compile time", 169 cmpMBean.isCompilationTimeMonitoringSupported() 170 ? formatTime(cmpMBean.getTotalCompilationTime()) 171 : getText("Unavailable")); 172 } else { 173 append("JIT compiler", getText("Unavailable")); 174 } 175 append(endTable); 176 } 177 178 append(newDivider); 179 180 { // Threads and Classes 181 append(newLeftTable); 182 int tlCount = tmBean.getThreadCount(); 183 int tdCount = tmBean.getDaemonThreadCount(); 184 int tpCount = tmBean.getPeakThreadCount(); 185 long ttCount = tmBean.getTotalStartedThreadCount(); 186 String[] strings1 = formatLongs(tlCount, tpCount, 187 tdCount, ttCount); 188 append("Live Threads", strings1[0]); 189 append("Peak", strings1[1]); 190 append("Daemon threads", strings1[2]); 191 append("Total threads started", strings1[3]); 192 append(endTable); 193 194 append(newRightTable); 195 long clCount = clMBean.getLoadedClassCount(); 196 long cuCount = clMBean.getUnloadedClassCount(); 197 long ctCount = clMBean.getTotalLoadedClassCount(); 198 String[] strings2 = formatLongs(clCount, cuCount, ctCount); 199 append("Current classes loaded", strings2[0]); 200 append("Total classes loaded", strings2[2]); 201 append("Total classes unloaded", strings2[1]); 202 append(null, ""); 203 append(endTable); 204 } 205 206 append(newDivider); 207 208 { // Memory 209 MemoryUsage u = memoryBean.getHeapMemoryUsage(); 210 211 append(newLeftTable); 212 String[] strings1 = formatKByteStrings(u.getUsed(), u.getMax()); 213 append("Current heap size", strings1[0]); 214 append("Maximum heap size", strings1[1]); 215 append(endTable); 216 217 append(newRightTable); 218 String[] strings2 = formatKByteStrings(u.getCommitted()); 219 append("Committed memory", strings2[0]); 220 append("SummaryTab.pendingFinalization.label", 221 getText("SummaryTab.pendingFinalization.value", 222 memoryBean.getObjectPendingFinalizationCount())); 223 append(endTable); 224 225 append(newTable); 226 Collection<GarbageCollectorMXBean> garbageCollectors = 227 proxyClient.getGarbageCollectorMXBeans(); 228 for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) { 229 String gcName = garbageCollectorMBean.getName(); 230 long gcCount = garbageCollectorMBean.getCollectionCount(); 231 long gcTime = garbageCollectorMBean.getCollectionTime(); 232 233 append("Garbage collector", 234 getText("GcInfo", gcName, gcCount, 235 (gcTime >= 0) ? formatTime(gcTime) 236 : getText("Unavailable")), 237 4); 238 } 239 append(endTable); 240 } 241 242 append(newDivider); 243 244 { // Operating System info 245 append(newLeftTable); 246 String osName = osMBean.getName(); 247 String osVersion = osMBean.getVersion(); 248 String osArch = osMBean.getArch(); 249 result.nCPUs = osMBean.getAvailableProcessors(); 250 append("Operating System", osName + " " + osVersion); 251 append("Architecture", osArch); 252 append("Number of processors", result.nCPUs+""); 253 254 if (pathSeparator == null) { 255 // Must use separator of remote OS, not File.pathSeparator 256 // from this local VM. In the future, consider using 257 // RuntimeMXBean to get the remote system property. 258 pathSeparator = osName.startsWith("Windows ") ? ";" : ":"; 259 } 260 261 if (sunOSMBean != null) { 262 String[] kbStrings1 = 263 formatKByteStrings(sunOSMBean.getCommittedVirtualMemorySize()); 264 265 String[] kbStrings2 = 266 formatKByteStrings(sunOSMBean.getTotalPhysicalMemorySize(), 267 sunOSMBean.getFreePhysicalMemorySize(), 268 sunOSMBean.getTotalSwapSpaceSize(), 269 sunOSMBean.getFreeSwapSpaceSize()); 270 271 append("Committed virtual memory", kbStrings1[0]); 272 append(endTable); 273 274 append(newRightTable); 275 append("Total physical memory", kbStrings2[0]); 276 append("Free physical memory", kbStrings2[1]); 277 append("Total swap space", kbStrings2[2]); 278 append("Free swap space", kbStrings2[3]); 279 } 280 281 append(endTable); 282 } 283 284 append(newDivider); 285 286 { // VM arguments and paths 287 append(newTable); 288 String args = ""; 289 java.util.List<String> inputArguments = rmBean.getInputArguments(); 290 for (String arg : inputArguments) { 291 args += arg + " "; 292 } 293 append("VM arguments", args, 4); 294 append("Class path", rmBean.getClassPath(), 4); 295 append("Library path", rmBean.getLibraryPath(), 4); 296 append("Boot class path", 297 rmBean.isBootClassPathSupported() 298 ? rmBean.getBootClassPath() 299 : getText("Unavailable"), 300 4); 301 append(endTable); 302 } 303 } catch (IOException e) { 304 if (JConsole.isDebug()) { 305 e.printStackTrace(); 306 } 307 proxyClient.markAsDead(); 308 return null; 309 } catch (UndeclaredThrowableException e) { 310 if (JConsole.isDebug()) { 311 e.printStackTrace(); 312 } 313 proxyClient.markAsDead(); 314 return null; 315 } 316 317 append("</table>"); 318 319 result.timeStamp = System.currentTimeMillis(); 320 result.summary = buf.toString(); 321 322 return result; 323 } 324 325 private synchronized void append(String str) { 326 buf.append(str); 327 } 328 329 void append(String label, String value) { 330 append(newRow((label != null) ? getText(label) : label, value)); 331 } 332 333 private void append(String label, String value, int columnPerRow) { 334 if (columnPerRow == 4 && pathSeparator != null) { 335 value = value.replace(pathSeparator, 336 "<b></b>" + pathSeparator); 337 } 338 append(newRow(getText(label), value, columnPerRow)); 339 } 340 341 void append(String label1, String value1, 342 String label2, String value2) { 343 append(newRow(getText(label1), value1, 344 getText(label2), value2)); 345 } 346 347 OverviewPanel[] getOverviewPanels() { 348 if (overviewPanel == null) { 349 overviewPanel = new CPUOverviewPanel(); 350 } 351 return new OverviewPanel[] { overviewPanel }; 352 } 353 354 private static class CPUOverviewPanel extends OverviewPanel { 355 private long prevUpTime, prevProcessCpuTime; 356 357 CPUOverviewPanel() { 358 super(getText("CPU Usage"), cpuUsageKey, cpuUsageName, Plotter.Unit.PERCENT); 359 getPlotter().setDecimals(CPU_DECIMALS); 360 } 361 362 public void updateCPUInfo(Result result) { 363 if (prevUpTime > 0L && result.upTime > prevUpTime) { 364 // elapsedCpu is in ns and elapsedTime is in ms. 365 long elapsedCpu = result.processCpuTime - prevProcessCpuTime; 366 long elapsedTime = result.upTime - prevUpTime; 367 // cpuUsage could go higher than 100% because elapsedTime 368 // and elapsedCpu are not fetched simultaneously. Limit to 369 // 99% to avoid Plotter showing a scale from 0% to 200%. 370 float cpuUsage = 371 Math.min(99F, 372 elapsedCpu / (elapsedTime * 10000F * result.nCPUs)); 373 374 getPlotter().addValues(result.timeStamp, 375 Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS))); 376 getInfoLabel().setText(getText(cpuUsageFormat, 377 String.format("%."+CPU_DECIMALS+"f", cpuUsage))); 378 } 379 this.prevUpTime = result.upTime; 380 this.prevProcessCpuTime = result.processCpuTime; 381 } 382 } 383 384 385 386 } | 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.tools.jconsole; 27 28 import java.awt.*; 29 import java.io.*; 30 import java.lang.management.*; 31 import java.lang.reflect.*; 32 import java.text.*; 33 import java.util.*; 34 import java.util.concurrent.*; 35 36 import javax.swing.*; 37 38 import sun.tools.jconsole.resources.Messages; 39 40 import static sun.tools.jconsole.Formatter.*; 41 import static sun.tools.jconsole.Utilities.*; 42 43 @SuppressWarnings("serial") 44 class SummaryTab extends Tab { 45 private static final String cpuUsageKey = "cpu"; 46 47 private static final String newDivider = "<tr><td colspan=4><font size =-1><hr>"; 48 private static final String newTable = "<tr><td colspan=4 align=left><table cellpadding=1>"; 49 private static final String newLeftTable = "<tr><td colspan=2 align=left><table cellpadding=1>"; 50 private static final String newRightTable = "<td colspan=2 align=left><table cellpadding=1>"; 51 private static final String endTable = "</table>"; 52 53 private static final int CPU_DECIMALS = 1; 54 55 private CPUOverviewPanel overviewPanel; 56 private DateFormat headerDateTimeFormat; 57 private String pathSeparator = null; 58 HTMLPane info; 59 60 private static class Result { 61 long upTime = -1L; 62 long processCpuTime = -1L; 63 long timeStamp; 64 int nCPUs; 65 String summary; 66 } 67 68 public static String getTabName() { 69 return Messages.SUMMARY_TAB_TAB_NAME; 70 } 71 72 public SummaryTab(VMPanel vmPanel) { 73 super(vmPanel, getTabName()); 74 75 setLayout(new BorderLayout()); 76 77 info = new HTMLPane(); 78 setAccessibleName(info, getTabName()); 79 add(new JScrollPane(info)); 80 81 headerDateTimeFormat = 82 Formatter.getDateTimeFormat(Messages.SUMMARY_TAB_HEADER_DATE_TIME_FORMAT); 83 } 84 85 public SwingWorker<?, ?> newSwingWorker() { 86 return new SwingWorker<Result, Object>() { 87 public Result doInBackground() { 88 return formatSummary(); 89 } 90 91 92 protected void done() { 93 try { 94 Result result = get(); 95 if (result != null) { 96 info.setText(result.summary); 97 if (overviewPanel != null && 98 result.upTime > 0L && 99 result.processCpuTime >= 0L) { 100 101 overviewPanel.updateCPUInfo(result); 102 } 117 Result result = new Result(); 118 ProxyClient proxyClient = vmPanel.getProxyClient(); 119 if (proxyClient.isDead()) { 120 return null; 121 } 122 123 buf = new StringBuilder(); 124 append("<table cellpadding=1>"); 125 126 try { 127 RuntimeMXBean rmBean = proxyClient.getRuntimeMXBean(); 128 CompilationMXBean cmpMBean = proxyClient.getCompilationMXBean(); 129 ThreadMXBean tmBean = proxyClient.getThreadMXBean(); 130 MemoryMXBean memoryBean = proxyClient.getMemoryMXBean(); 131 ClassLoadingMXBean clMBean = proxyClient.getClassLoadingMXBean(); 132 OperatingSystemMXBean osMBean = proxyClient.getOperatingSystemMXBean(); 133 com.sun.management.OperatingSystemMXBean sunOSMBean = 134 proxyClient.getSunOperatingSystemMXBean(); 135 136 append("<tr><td colspan=4>"); 137 append("<center><b>" + Messages.SUMMARY_TAB_TAB_NAME + "</b></center>"); 138 String dateTime = 139 headerDateTimeFormat.format(System.currentTimeMillis()); 140 append("<center>" + dateTime + "</center>"); 141 142 append(newDivider); 143 144 { // VM info 145 append(newLeftTable); 146 append(Messages.CONNECTION_NAME, vmPanel.getDisplayName()); 147 append(Messages.VIRTUAL_MACHINE, 148 Resources.format(Messages.SUMMARY_TAB_VM_VERSION, 149 rmBean.getVmName(), rmBean.getVmVersion())); 150 append(Messages.VENDOR, rmBean.getVmVendor()); 151 append(Messages.NAME, rmBean.getName()); 152 append(endTable); 153 154 append(newRightTable); 155 result.upTime = rmBean.getUptime(); 156 append(Messages.UPTIME, formatTime(result.upTime)); 157 if (sunOSMBean != null) { 158 result.processCpuTime = sunOSMBean.getProcessCpuTime(); 159 append(Messages.PROCESS_CPU_TIME, formatNanoTime(result.processCpuTime)); 160 } 161 162 if (cmpMBean != null) { 163 append(Messages.JIT_COMPILER, cmpMBean.getName()); 164 append(Messages.TOTAL_COMPILE_TIME, 165 cmpMBean.isCompilationTimeMonitoringSupported() 166 ? formatTime(cmpMBean.getTotalCompilationTime()) 167 : Messages.UNAVAILABLE); 168 } else { 169 append(Messages.JIT_COMPILER, Messages.UNAVAILABLE); 170 } 171 append(endTable); 172 } 173 174 append(newDivider); 175 176 { // Threads and Classes 177 append(newLeftTable); 178 int tlCount = tmBean.getThreadCount(); 179 int tdCount = tmBean.getDaemonThreadCount(); 180 int tpCount = tmBean.getPeakThreadCount(); 181 long ttCount = tmBean.getTotalStartedThreadCount(); 182 String[] strings1 = formatLongs(tlCount, tpCount, 183 tdCount, ttCount); 184 append(Messages.LIVE_THREADS, strings1[0]); 185 append(Messages.PEAK, strings1[1]); 186 append(Messages.DAEMON_THREADS, strings1[2]); 187 append(Messages.TOTAL_THREADS_STARTED, strings1[3]); 188 append(endTable); 189 190 append(newRightTable); 191 long clCount = clMBean.getLoadedClassCount(); 192 long cuCount = clMBean.getUnloadedClassCount(); 193 long ctCount = clMBean.getTotalLoadedClassCount(); 194 String[] strings2 = formatLongs(clCount, cuCount, ctCount); 195 append(Messages.CURRENT_CLASSES_LOADED, strings2[0]); 196 append(Messages.TOTAL_CLASSES_LOADED, strings2[2]); 197 append(Messages.TOTAL_CLASSES_UNLOADED, strings2[1]); 198 append(null, ""); 199 append(endTable); 200 } 201 202 append(newDivider); 203 204 { // Memory 205 MemoryUsage u = memoryBean.getHeapMemoryUsage(); 206 207 append(newLeftTable); 208 String[] strings1 = formatKByteStrings(u.getUsed(), u.getMax()); 209 append(Messages.CURRENT_HEAP_SIZE, strings1[0]); 210 append(Messages.MAXIMUM_HEAP_SIZE, strings1[1]); 211 append(endTable); 212 213 append(newRightTable); 214 String[] strings2 = formatKByteStrings(u.getCommitted()); 215 append(Messages.COMMITTED_MEMORY, strings2[0]); 216 append(Messages.SUMMARY_TAB_PENDING_FINALIZATION_LABEL, 217 Messages.SUMMARY_TAB_PENDING_FINALIZATION_VALUE, 218 memoryBean.getObjectPendingFinalizationCount()); 219 append(endTable); 220 221 append(newTable); 222 Collection<GarbageCollectorMXBean> garbageCollectors = 223 proxyClient.getGarbageCollectorMXBeans(); 224 for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) { 225 String gcName = garbageCollectorMBean.getName(); 226 long gcCount = garbageCollectorMBean.getCollectionCount(); 227 long gcTime = garbageCollectorMBean.getCollectionTime(); 228 229 append(Messages.GARBAGE_COLLECTOR, 230 Resources.format(Messages.GC_INFO, gcName, gcCount, 231 (gcTime >= 0) ? formatTime(gcTime) 232 : Messages.UNAVAILABLE), 233 4); 234 } 235 append(endTable); 236 } 237 238 append(newDivider); 239 240 { // Operating System info 241 append(newLeftTable); 242 String osName = osMBean.getName(); 243 String osVersion = osMBean.getVersion(); 244 String osArch = osMBean.getArch(); 245 result.nCPUs = osMBean.getAvailableProcessors(); 246 append(Messages.OPERATING_SYSTEM, osName + " " + osVersion); 247 append(Messages.ARCHITECTURE, osArch); 248 append(Messages.NUMBER_OF_PROCESSORS, result.nCPUs+""); 249 250 if (pathSeparator == null) { 251 // Must use separator of remote OS, not File.pathSeparator 252 // from this local VM. In the future, consider using 253 // RuntimeMXBean to get the remote system property. 254 pathSeparator = osName.startsWith("Windows ") ? ";" : ":"; 255 } 256 257 if (sunOSMBean != null) { 258 String[] kbStrings1 = 259 formatKByteStrings(sunOSMBean.getCommittedVirtualMemorySize()); 260 261 String[] kbStrings2 = 262 formatKByteStrings(sunOSMBean.getTotalPhysicalMemorySize(), 263 sunOSMBean.getFreePhysicalMemorySize(), 264 sunOSMBean.getTotalSwapSpaceSize(), 265 sunOSMBean.getFreeSwapSpaceSize()); 266 267 append(Messages.COMMITTED_VIRTUAL_MEMORY, kbStrings1[0]); 268 append(endTable); 269 270 append(newRightTable); 271 append(Messages.TOTAL_PHYSICAL_MEMORY, kbStrings2[0]); 272 append(Messages.FREE_PHYSICAL_MEMORY, kbStrings2[1]); 273 append(Messages.TOTAL_SWAP_SPACE, kbStrings2[2]); 274 append(Messages.FREE_SWAP_SPACE, kbStrings2[3]); 275 } 276 277 append(endTable); 278 } 279 280 append(newDivider); 281 282 { // VM arguments and paths 283 append(newTable); 284 String args = ""; 285 java.util.List<String> inputArguments = rmBean.getInputArguments(); 286 for (String arg : inputArguments) { 287 args += arg + " "; 288 } 289 append(Messages.VM_ARGUMENTS, args, 4); 290 append(Messages.CLASS_PATH, rmBean.getClassPath(), 4); 291 append(Messages.LIBRARY_PATH, rmBean.getLibraryPath(), 4); 292 append(Messages.BOOT_CLASS_PATH, 293 rmBean.isBootClassPathSupported() 294 ? rmBean.getBootClassPath() 295 : Messages.UNAVAILABLE, 296 4); 297 append(endTable); 298 } 299 } catch (IOException e) { 300 if (JConsole.isDebug()) { 301 e.printStackTrace(); 302 } 303 proxyClient.markAsDead(); 304 return null; 305 } catch (UndeclaredThrowableException e) { 306 if (JConsole.isDebug()) { 307 e.printStackTrace(); 308 } 309 proxyClient.markAsDead(); 310 return null; 311 } 312 313 append("</table>"); 314 315 result.timeStamp = System.currentTimeMillis(); 316 result.summary = buf.toString(); 317 318 return result; 319 } 320 321 private synchronized void append(String str) { 322 buf.append(str); 323 } 324 325 void append(String label, String value) { 326 append(newRow(label, value)); 327 } 328 329 private void append(String label, String value, int columnPerRow) { 330 if (columnPerRow == 4 && pathSeparator != null) { 331 value = value.replace(pathSeparator, 332 "<b></b>" + pathSeparator); 333 } 334 append(newRow(label, value, columnPerRow)); 335 } 336 337 OverviewPanel[] getOverviewPanels() { 338 if (overviewPanel == null) { 339 overviewPanel = new CPUOverviewPanel(); 340 } 341 return new OverviewPanel[] { overviewPanel }; 342 } 343 344 private static class CPUOverviewPanel extends OverviewPanel { 345 private long prevUpTime, prevProcessCpuTime; 346 347 CPUOverviewPanel() { 348 super(Messages.CPU_USAGE, cpuUsageKey, Messages.CPU_USAGE, Plotter.Unit.PERCENT); 349 getPlotter().setDecimals(CPU_DECIMALS); 350 } 351 352 public void updateCPUInfo(Result result) { 353 if (prevUpTime > 0L && result.upTime > prevUpTime) { 354 // elapsedCpu is in ns and elapsedTime is in ms. 355 long elapsedCpu = result.processCpuTime - prevProcessCpuTime; 356 long elapsedTime = result.upTime - prevUpTime; 357 // cpuUsage could go higher than 100% because elapsedTime 358 // and elapsedCpu are not fetched simultaneously. Limit to 359 // 99% to avoid Plotter showing a scale from 0% to 200%. 360 float cpuUsage = 361 Math.min(99F, 362 elapsedCpu / (elapsedTime * 10000F * result.nCPUs)); 363 364 getPlotter().addValues(result.timeStamp, 365 Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS))); 366 getInfoLabel().setText(Resources.format(Messages.CPU_USAGE_FORMAT, 367 String.format("%."+CPU_DECIMALS+"f", cpuUsage))); 368 } 369 this.prevUpTime = result.upTime; 370 this.prevProcessCpuTime = result.processCpuTime; 371 } 372 } 373 } |