1 22 package org.jboss.system.server; 23 24 import java.lang.reflect.Method ; 25 import java.text.DecimalFormat ; 26 import java.util.Enumeration ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Set ; 30 import java.util.TreeSet ; 31 32 import javax.management.MBeanRegistration ; 33 import javax.management.MBeanServer ; 34 import javax.management.ObjectName ; 35 36 import org.jboss.logging.Logger; 37 import org.jboss.util.platform.Java; 38 39 51 public class ServerInfo 52 implements ServerInfoMBean, MBeanRegistration 53 { 54 55 private static final Logger log = Logger.getLogger(ServerInfo.class); 56 57 58 private static final Integer ZERO = new Integer (0); 59 60 61 private MBeanServer server; 62 63 64 private String hostName; 65 66 67 private String hostAddress; 68 69 70 private Object threadMXBean; 71 72 73 private Method getMemoryPoolMXBeans; 74 75 76 private Method getName; 77 private Method getType; 78 private Method getUsage; 79 private Method getPeakUsage; 80 81 82 private Method getInit; 83 private Method getUsed; 84 private Method getCommitted; 85 private Method getMax; 86 87 88 private Method getThreadInfo; 89 private Method getAllThreadIds; 90 private Method getThreadCpuTime; 91 92 93 private Method getThreadName; 94 private Method getThreadState; 95 private Method getLockName; 96 private Method getStackTrace; 97 98 99 private Method getThreadId; 100 101 105 public ObjectName preRegister(MBeanServer server, ObjectName name) 106 throws Exception 107 { 108 this.server = server; 109 log.debug("Java version: " + 111 System.getProperty("java.version") + "," + 112 System.getProperty("java.vendor")); 113 114 log.info("Java VM: " + 115 System.getProperty("java.vm.name") + " " + 116 System.getProperty("java.vm.version") + "," + 117 System.getProperty("java.vm.vendor")); 118 119 log.info("OS-System: " + 120 System.getProperty("os.name") + " " + 121 System.getProperty("os.version") + "," + 122 System.getProperty("os.arch")); 123 124 log.debug("Full System Properties Dump"); 126 Enumeration names = System.getProperties().propertyNames(); 127 while (names.hasMoreElements()) 128 { 129 String pname = (String )names.nextElement(); 130 log.debug(" " + pname + ": " + System.getProperty(pname)); 131 } 132 133 if (Java.isCompatible(Java.VERSION_1_5)) 136 { 137 try 138 { 139 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 140 Class clazz = cl.loadClass("java.lang.management.ManagementFactory"); 141 142 Method method = clazz.getMethod("getThreadMXBean", null); 144 this.threadMXBean = method.invoke(null, null); 145 146 this.getMemoryPoolMXBeans = clazz.getMethod("getMemoryPoolMXBeans", null); 148 149 clazz = cl.loadClass("java.lang.management.MemoryPoolMXBean"); 151 this.getName = clazz.getMethod("getName", null); 152 this.getType = clazz.getMethod("getType", null); 153 this.getUsage = clazz.getMethod("getUsage", null); 154 this.getPeakUsage = clazz.getMethod("getPeakUsage", null); 155 156 clazz = cl.loadClass("java.lang.management.MemoryUsage"); 158 this.getInit = clazz.getMethod("getInit", null); 159 this.getUsed = clazz.getMethod("getUsed", null); 160 this.getCommitted = clazz.getMethod("getCommitted", null); 161 this.getMax = clazz.getMethod("getMax", null); 162 163 clazz = cl.loadClass("java.lang.management.ThreadMXBean"); 165 this.getThreadInfo = clazz.getMethod("getThreadInfo", new Class [] { Long.TYPE, Integer.TYPE } ); 166 this.getAllThreadIds = clazz.getMethod("getAllThreadIds", null ); 167 this.getThreadCpuTime = clazz.getMethod("getThreadCpuTime", new Class [] { Long.TYPE } ); 168 169 clazz = cl.loadClass("java.lang.management.ThreadInfo"); 171 this.getThreadName = clazz.getMethod("getThreadName", null); 172 this.getThreadState = clazz.getMethod("getThreadState", null); 173 this.getLockName = clazz.getMethod("getLockName", null); 174 this.getStackTrace = clazz.getMethod("getStackTrace", null); 175 176 clazz = Thread .class; 178 this.getThreadId = clazz.getMethod("getId", null); 179 } 180 catch (Exception e) 181 { 182 log.debug("Cannot access platform ThreadMXBean", e); 183 } 184 } 185 186 return name == null ? new ObjectName (OBJECT_NAME_STR) : name; 187 } 188 189 public void postRegister(Boolean registrationDone) 190 { 191 } 193 194 public void preDeregister() throws Exception 195 { 196 } 198 199 public void postDeregister() 200 { 201 } 203 204 205 209 212 public String getJavaVersion() 213 { 214 return System.getProperty("java.version"); 215 } 216 217 220 public String getJavaVendor() 221 { 222 return System.getProperty("java.vendor"); 223 } 224 225 228 public String getJavaVMName() 229 { 230 return System.getProperty("java.vm.name"); 231 } 232 233 236 public String getJavaVMVersion() 237 { 238 return System.getProperty("java.vm.version"); 239 } 240 241 244 public String getJavaVMVendor() 245 { 246 return System.getProperty("java.vm.vendor"); 247 } 248 249 252 public String getOSName() 253 { 254 return System.getProperty("os.name"); 255 } 256 257 260 public String getOSVersion() 261 { 262 return System.getProperty("os.version"); 263 } 264 265 268 public String getOSArch() 269 { 270 return System.getProperty("os.arch"); 271 } 272 273 276 public Long getTotalMemory() 277 { 278 return new Long (Runtime.getRuntime().totalMemory()); 279 } 280 281 284 public Long getFreeMemory() 285 { 286 return new Long (Runtime.getRuntime().freeMemory()); 287 } 288 289 295 public Long getMaxMemory() 296 { 297 if (Java.isCompatible(Java.VERSION_1_4)) { 298 301 try { 303 Runtime rt = Runtime.getRuntime(); 304 Method m = rt.getClass().getMethod("maxMemory", new Class [0]); 305 return (Long )m.invoke(rt, new Object [0]); 306 } 307 catch (Exception e) { 308 log.error("Operation failed", e); 309 } 310 } 311 312 return new Long (-1); 313 } 314 315 321 public Integer getAvailableProcessors() 322 { 323 if (Java.isCompatible(Java.VERSION_1_4)) { 324 327 try { 329 Runtime rt = Runtime.getRuntime(); 330 Method m = rt.getClass().getMethod("availableProcessors", new Class [0]); 331 return (Integer )m.invoke(rt, new Object [0]); 332 } 333 catch (Exception e) { 334 log.error("Operation failed", e); 335 } 336 } 337 338 return new Integer (-1); 339 } 340 341 346 public String getHostName() 347 { 348 if (hostName == null) 349 { 350 try 351 { 352 hostName = java.net.InetAddress.getLocalHost().getHostName(); 353 } 354 catch (java.net.UnknownHostException e) 355 { 356 log.error("Error looking up local hostname", e); 357 hostName = "<unknown>"; 358 } 359 } 360 361 return hostName; 362 } 363 364 369 public String getHostAddress() 370 { 371 if (hostAddress == null) 372 { 373 try 374 { 375 hostAddress = java.net.InetAddress.getLocalHost().getHostAddress(); 376 } 377 catch (java.net.UnknownHostException e) 378 { 379 log.error("Error looking up local address", e); 380 hostAddress = "<unknown>"; 381 } 382 } 383 384 return hostAddress; 385 } 386 387 394 public String listMemoryPools(boolean fancy) 395 { 396 if (getMemoryPoolMXBeans != null) 397 { 398 StringBuffer sbuf = new StringBuffer (4196); 400 try 401 { 402 List poolList = (List )getMemoryPoolMXBeans.invoke(null, null); 404 sbuf.append("<b>Total Memory Pools:</b> ").append(poolList.size()); 405 sbuf.append("<blockquote>"); 406 for (Iterator i = poolList.iterator(); i.hasNext(); ) 407 { 408 Object pool = i.next(); 410 String name = (String )getName.invoke(pool, null); 411 Object type = getType.invoke(pool, null); 413 sbuf.append("<b>Pool: ").append(name); 414 sbuf.append("</b> (").append(type).append(")"); 415 416 Object peakUsage = getPeakUsage.invoke(pool, null); 418 Object usage = getUsage.invoke(pool, null); 419 420 sbuf.append("<blockquote>"); 421 if (usage != null && peakUsage != null) 422 { 423 Long init = (Long )getInit.invoke(peakUsage, null); 424 Long used = (Long )getUsed.invoke(peakUsage, null); 425 Long committed = (Long )getCommitted.invoke(peakUsage, null); 426 Long max = (Long )getMax.invoke(peakUsage, null); 427 428 sbuf.append("Peak Usage : "); 429 sbuf.append("init:").append(init); 430 sbuf.append(", used:").append(used); 431 sbuf.append(", committed:").append(committed); 432 sbuf.append(", max:").append(max); 433 sbuf.append("<br>"); 434 435 init = (Long )getInit.invoke(usage, null); 436 used = (Long )getUsed.invoke(usage, null); 437 committed = (Long )getCommitted.invoke(usage, null); 438 max = (Long )getMax.invoke(usage, null); 439 440 sbuf.append("Current Usage : "); 441 sbuf.append("init:").append(init); 442 sbuf.append(", used:").append(used); 443 sbuf.append(", committed:").append(committed); 444 sbuf.append(", max:").append(max); 445 446 if (fancy) 447 { 448 TextGraphHelper.poolUsage(sbuf, used.longValue(), committed.longValue(), max.longValue()); 449 } 450 } 451 else 452 { 453 sbuf.append("Memory pool NOT valid!"); 454 } 455 sbuf.append("</blockquote><br>"); 456 } 457 sbuf.append("</blockquote>"); 458 } 459 catch (Exception e) 460 { 461 } 463 return sbuf.toString(); 464 } 465 else 466 { 467 return "<b>Memory pool information available only under a JDK5+ compatible JVM!</b>"; 468 } 469 } 470 471 474 public Integer getActiveThreadCount() 475 { 476 return new Integer (getRootThreadGroup().activeCount()); 477 } 478 479 482 public Integer getActiveThreadGroupCount() 483 { 484 return new Integer (getRootThreadGroup().activeGroupCount()); 485 } 486 487 492 public String listThreadDump() 493 { 494 ThreadGroup root = getRootThreadGroup(); 495 496 ThreadGroupCount count = new ThreadGroupCount(); 500 501 String threadGroupInfo = getThreadGroupInfo(root, count); 503 String threadDump = 505 "<b>Total Threads:</b> " + count.threads + "<br>" + 506 "<b>Total Thread Groups:</b> " + count.groups + "<br>" + 507 threadGroupInfo; 508 509 return threadDump; 510 } 511 512 517 public String listThreadCpuUtilization() 518 { 519 Set threads = getThreadCpuUtilization(); 520 521 if (threads == null) 522 { 523 return("Thread cpu utilization requires J2SE5+"); 524 } 525 else 526 { 527 long totalCPU = 0; 528 StringBuffer buffer = new StringBuffer (); 529 buffer.append("<table><tr><th>Thread Name</th><th>CPU (milliseconds)</th></tr>"); 530 for (Iterator i = threads.iterator(); i.hasNext();) 531 { 532 ThreadCPU thread = (ThreadCPU) i.next(); 533 buffer.append("<tr><td>").append(thread.name).append("</td><td>"); 534 buffer.append(thread.cpuTime).append("</td></tr>"); 535 totalCPU += thread.cpuTime; 536 } 537 buffer.append("<tr><td> </td><td> </td></tr><tr><td>Total</td><td>"); 538 buffer.append(totalCPU).append("</td></tr></table>"); 539 return buffer.toString(); 540 } 541 } 542 543 547 552 private Set getThreadCpuUtilization() 553 { 554 if (threadMXBean == null) 555 return null; 556 557 try 558 { 559 TreeSet result = new TreeSet (); 560 long[] threads = (long[]) getAllThreadIds.invoke(threadMXBean, null); 561 for (int i = 0; i < threads.length; ++i) 562 { 563 Long id = new Long (threads[i]); 564 Long cpuTime = (Long ) getThreadCpuTime.invoke(threadMXBean, new Object [] { id }); 565 Object threadInfo = getThreadInfo.invoke(threadMXBean, new Object [] { id, ZERO }); 566 String name = (String ) getThreadName.invoke(threadInfo, null); 567 result.add(new ThreadCPU(name, cpuTime.longValue())); 568 } 569 return result; 570 } 571 catch (Exception e) 572 { 573 log.warn("Error retrieving thread cpu utiliation", e); 574 return null; 575 } 576 } 577 578 581 private ThreadGroup getRootThreadGroup() 582 { 583 ThreadGroup group = Thread.currentThread().getThreadGroup(); 584 while (group.getParent() != null) 585 { 586 group = group.getParent(); 587 } 588 589 return group; 590 } 591 592 595 private String getThreadGroupInfo(ThreadGroup group, ThreadGroupCount count) 596 { 597 StringBuffer rc = new StringBuffer (); 598 599 count.groups++; 601 602 rc.append("<br><b>"); 603 rc.append("Thread Group: " + group.getName()); 604 rc.append("</b> : "); 605 rc.append("max priority:" + group.getMaxPriority() + 606 ", demon:" + group.isDaemon()); 607 608 rc.append("<blockquote>"); 609 Thread threads[]= new Thread [group.activeCount()]; 610 group.enumerate(threads, false); 611 for (int i= 0; i < threads.length && threads[i] != null; i++) 612 { 613 count.threads++; 615 616 rc.append("<b>"); 617 rc.append("Thread: " + threads[i].getName()); 618 rc.append("</b> : "); 619 rc.append("priority:" + threads[i].getPriority() + 620 ", demon:" + threads[i].isDaemon()); 621 outputJdk5ThreadMXBeanInfo(rc, threads[i]); 623 } 624 625 ThreadGroup groups[]= new ThreadGroup [group.activeGroupCount()]; 626 group.enumerate(groups, false); 627 for (int i= 0; i < groups.length && groups[i] != null; i++) 628 { 629 rc.append(getThreadGroupInfo(groups[i], count)); 630 } 631 rc.append("</blockquote>"); 632 633 return rc.toString(); 634 } 635 636 640 private void outputJdk5ThreadMXBeanInfo(StringBuffer sbuf, Thread thread) 641 { 642 if (threadMXBean != null) 644 { 645 try 647 { 648 Long threadId = (Long )getThreadId.invoke(thread, null); 650 Object threadInfo = getThreadInfo.invoke(threadMXBean, 652 new Object [] { threadId, new Integer (Integer.MAX_VALUE) }); 653 Object threadState = getThreadState.invoke(threadInfo, null); String threadLockName = (String )getLockName.invoke(threadInfo, null); 656 Object [] stackTrace = (Object [])getStackTrace.invoke(threadInfo, null); 657 658 sbuf.append(", threadId:").append(threadId); 659 sbuf.append(", threadState:").append(threadState); 660 sbuf.append(", threadLockName:").append(threadLockName); 661 sbuf.append("<br>"); 662 if (stackTrace.length > 0) 663 { 664 sbuf.append("<blockquote>"); 665 for (int i = 0; i < stackTrace.length; i++) 666 { 667 sbuf.append(stackTrace[i]).append("<br>"); 668 } 669 sbuf.append("</blockquote>"); 670 } 671 } 672 catch (Exception ignore) 673 { 674 } 676 } 677 else 678 { 679 sbuf.append("<br>"); 681 } 682 } 683 684 689 public String displayPackageInfo(String pkgName) 690 { 691 Package pkg = Package.getPackage(pkgName); 692 if( pkg == null ) 693 return "<h2>Package:"+pkgName+" Not Found!</h2>"; 694 695 StringBuffer info = new StringBuffer ("<h2>Package: "+pkgName+"</h2>"); 696 displayPackageInfo(pkg, info); 697 return info.toString(); 698 } 699 700 private void displayPackageInfo(Package pkg, StringBuffer info) 701 { 702 info.append("<pre>\n"); 703 info.append("SpecificationTitle: "+pkg.getSpecificationTitle()); 704 info.append("\nSpecificationVersion: "+pkg.getSpecificationVersion()); 705 info.append("\nSpecificationVendor: "+pkg.getSpecificationVendor()); 706 info.append("\nImplementationTitle: "+pkg.getImplementationTitle()); 707 info.append("\nImplementationVersion: "+pkg.getImplementationVersion()); 708 info.append("\nImplementationVendor: "+pkg.getImplementationVendor()); 709 info.append("\nisSealed: "+pkg.isSealed()); 710 info.append("</pre>\n"); 711 } 712 713 717 722 private static class TextGraphHelper 723 { 724 static final DecimalFormat formatter = new DecimalFormat ("#.##"); 726 static final long KILO = 1024; 727 static final long MEGA = 1024 * 1024; 728 static final long GIGA = 1024 * 1024 * 1024; 729 730 static final int factor = 70; 732 static char[] fixedline; 733 static char[] baseline; 734 static char[] barline; 735 static char[] spaces; 736 static 737 { 738 StringBuffer sbuf0 = new StringBuffer (); 740 StringBuffer sbuf1 = new StringBuffer (); 741 StringBuffer sbuf2 = new StringBuffer (); 742 StringBuffer sbuf3 = new StringBuffer (); 743 sbuf0.append('+'); 744 sbuf1.append('|'); 745 sbuf2.append('|'); 746 for (int i = 1; i < factor; i++) 747 { 748 sbuf0.append('-'); 749 sbuf1.append('-'); 750 sbuf2.append('/'); 751 sbuf3.append(' '); 752 } 753 sbuf0.append('+'); 754 fixedline = sbuf0.toString().toCharArray(); 755 baseline = sbuf1.toString().toCharArray(); 756 barline = sbuf2.toString().toCharArray(); 757 spaces = sbuf3.toString().toCharArray(); 758 } 759 760 private TextGraphHelper() 761 { 762 } 764 765 782 public static void poolUsage(StringBuffer sbuf, long used, long committed, long max) 783 { 784 long assumedMax = (max == -1) ? committed : max; 786 int localUsed = (int)(factor * used / assumedMax); 788 int localCommitted = (int)(factor * committed / assumedMax); 789 int localMax = factor; 790 791 sbuf.append("<blockquote><br>"); 792 sbuf.append(baseline, 0, localCommitted).append("| committed:").append(outputNumber(committed)).append("<br>"); 793 sbuf.append(fixedline).append("<br>"); 794 795 sbuf.append(barline, 0, localUsed); 797 if (localUsed < localCommitted) 798 { 799 sbuf.append(localUsed > 0 ? '/' : '|'); 800 sbuf.append(spaces, 0, localCommitted - localUsed - 1); 801 } 802 sbuf.append('|'); 803 if (localCommitted < localMax) 804 { 805 sbuf.append(spaces, 0, localMax - localCommitted - 1); 806 sbuf.append('|'); 807 } 808 sbuf.append(" max:").append(outputNumber(max)).append("<br>"); 809 810 sbuf.append(fixedline).append("<br>"); 811 sbuf.append(baseline, 0, localUsed).append("| used:").append(outputNumber(used)); 812 sbuf.append("</blockquote>"); 813 } 814 815 private static String outputNumber(long value) 816 { 817 if (value >= GIGA) 818 { 819 return formatter.format((double)value / GIGA) + "Gb"; 820 } 821 else if (value >= MEGA) 822 { 823 return formatter.format((double)value / MEGA) + "Mb"; 824 } 825 else if (value >= KILO) 826 { 827 return formatter.format((double)value / KILO) + "Kb"; 828 } 829 else if (value >= 0) 830 { 831 return value + "b"; 832 } 833 else 834 { 835 return Long.toString(value); 836 } 837 } 838 } 839 840 private static class ThreadCPU implements Comparable 841 { 842 public String name; 843 public long cpuTime; 844 845 public ThreadCPU(String name, long cpuTime) 846 { 847 this.name = name; 848 this.cpuTime = cpuTime / 1000000; } 850 851 public int compareTo(Object o) 852 { 853 ThreadCPU other = (ThreadCPU) o; 854 long value = cpuTime - other.cpuTime; 855 if (value > 0) 856 return -1; 857 else if (value < 0) 858 return +1; 859 else 860 return name.compareTo(other.name); 861 } 862 } 863 864 867 private static class ThreadGroupCount 868 { 869 public int threads; 870 public int groups; 871 } 872 } | Popular Tags |