Microsoft Open Sources BeanSpy
This post is a bit belated, but I am proud to announce that my team has open sourced the Java component for monitoring MBeans on remote applications servers. The project is called BeanSpy and it is available on github.
Platforms
Microsoft released BeanSpy under the Apache 2.0 license on January 2nd, 2012. The EAR/WAR file should be deployed to one of the following supported application servers:
- Tomcat: 5.5, 6, 7
- JBoss: 4.2, 5.1, 6
- WebLogic: 10gR3, 11gR1
- WebSphere: 6.1, 7
BeanSpy HTTP GET operations
The following HTTP Get operations can be performed in a web browser such as Internet Explorer.
a) To query JVM stats for memory, Garbage Collection, class loading, and threads, use:
https://<host:port>/BeanSpy/Stats
For example, a query to a Tomcat 7 by https://localhost:8080/BeanSpy/Stats will generate output similar to:
<?xml version="1.0" encoding="UTF-8" ?> <Stats version="7.4.1002.0"> <JmxStores> <Properties> <JmxStoreNames type="class java.lang.String">com.interopbridges.scx.jmx.TomcatJMXAbstraction</JmxStoreNames> </Properties></JmxStores> <JmxStores> <Properties> <JmxStoreNames type="class java.lang.String">com.interopbridges.scx.jmx.JdkJMXAbstraction</JmxStoreNames> </Properties> </JmxStores> <ClassLoader> <Properties> <LoadedClassCount type="int">2851</LoadedClassCount> <UnloadedClassCount type="long">192688</UnloadedClassCount> <TotalLoadedClassCount type="long">195539</TotalLoadedClassCount> </Properties> </ClassLoader> <Thread> <Properties> <PeakThreadCount type="int">30</PeakThreadCount> <ThreadCount type="int">22</ThreadCount> <TotalStartedThreadCount type="long">8430</TotalStartedThreadCount> </Properties> </Thread> <JITCompiler> <Properties> <TotalCompilationTime type="long">98866</TotalCompilationTime> </Properties> </JITCompiler> <GC> <Properties> <GCCollectionCount type="long">5892</GCCollectionCount> <GCCollectionTime type="long">299742</GCCollectionTime> <GCName type="class java.lang.String">PS Scavenge</GCName> </Properties> </GC> <GC> <Properties> <GCCollectionCount type="long">1321</GCCollectionCount> <GCCollectionTime type="long">260844</GCCollectionTime> <GCName type="class java.lang.String">PS MarkSweep</GCName> </Properties> </GC> <Memory> <Properties> <HeapInitialMemoryAllocated type="long">33547136</HeapInitialMemoryAllocated> <HeapUsedMemory type="long">38520664</HeapUsedMemory> <HeapCommittedMemory type="long">55443456</HeapCommittedMemory> <HeapMaximumMemory type="long">477233152</HeapMaximumMemory> <NonHeapInitialMemoryAllocated type="long">24313856</NonHeapInitialMemoryAllocated> <NonHeapUsedMemory type="long">24809424</NonHeapUsedMemory> <NonHeapCommittedMemory type="long">25755648</NonHeapCommittedMemory> <NonHeapMaximumMemory type="long">136314880</NonHeapMaximumMemory> <PendingFinalizationCount type="int">0</PendingFinalizationCount> <PercentHeapMemoryUsed type="int">8</PercentHeapMemoryUsed> </Properties> </Memory> <Runtime> <Properties> <StartTime type="long">1323463776869</StartTime> <UpTime type="long">4755504058</UpTime> </Properties> </Runtime> </Stats>
b) To query configuration and version info about the Java EE application server or web container, use:
https://<host:port>/BeanSpy/Stats/Info
For example, a query to a Tomcat 7 by https://localhost:8080/BeanSpy/Stats/Info will generate output similar to:
<?xml version="1.0" encoding="UTF-8" ?>
<Info version="7.4.1002.0">
<JVMMemory>
<Properties>
<MaxHeapSize type="class java.lang.String">455 MB</MaxHeapSize>
</Properties>
</JVMMemory>
<OperatingSystem>
<Properties>
<Name type="class java.lang.String">Windows Server 2008 R2</Name>
<Version type="class java.lang.String">6.1</Version>
<Architecture type="class java.lang.String">amd64</Architecture>
</Properties>
</OperatingSystem>
<JavaVirtualMachine>
<Properties>
<Name type="class java.lang.String">Java HotSpot(TM) 64-Bit Server VM</Name>
<ClassPath type="class java.lang.String">C:\PROGRA~1\Java\jdk1.6.0_25\jre\lib\resources.jar;C:\PROGRA~1\Java\jdk1.6.0_25\jre\lib\rt.jar;C:\PROGRA~1\Java\jdk1.6.0_25\jre\lib\sunrsasign.jar;C:\PROGRA~1\Java\jdk1.6.0_25\jre\lib\jsse.jar;C:\PROGRA~1\Java\jdk1.6.0_25\jre\lib\jce.jar;C:\PROGRA~1\Java\jdk1.6.0_25\jre\lib\charsets.jar;C:\PROGRA~1\Java\jdk1.6.0_25\jre\lib\modules\jdk.boot.jar;C:\PROGRA~1\Java\jdk1.6.0_25\jre\classes</ClassPath>
<LibraryPath type="class java.lang.String">C:\PROGRA~1\Java\jdk1.6.0_25\bin;.;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\teamtool;C:\teamtool\TTRemoteInstall;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\;C:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\;C:\PROGRA~1\Java\jdk1.6.0_25\bin</LibraryPath>
<StartupTime type="class java.lang.String">Mon Feb 06 10:57:59 PST 2012</StartupTime>
<Version type="class java.lang.String">1.6.0_25</Version>
<VendorName type="class java.lang.String">Sun Microsystems Inc.</VendorName>
<BuildVersion type="class java.lang.String">20.0-b11</BuildVersion>
<StartupOption type="class java.lang.String">-Djava.util.logging.config.file=C:\AppServers\Tomcat\apache-tomcat-7.0.11-windows-x64\apache-tomcat-7.0.11\conf\logging.properties, -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager, -Djava.endorsed.dirs=C:\AppServers\Tomcat\apache-tomcat-7.0.11-windows-x64\apache-tomcat-7.0.11\endorsed, -Dcatalina.base=C:\AppServers\Tomcat\apache-tomcat-7.0.11-windows-x64\apache-tomcat-7.0.11, -Dcatalina.home=C:\AppServers\Tomcat\apache-tomcat-7.0.11-windows-x64\apache-tomcat-7.0.11, -Djava.io.tmpdir=C:\AppServers\Tomcat\apache-tomcat-7.0.11-windows-x64\apache-tomcat-7.0.11\temp</StartupOption>
<JavaInstallDirectory type="class java.lang.String">C:\PROGRA~1\Java\jdk1.6.0_25\jre</JavaInstallDirectory>
</Properties>
</JavaVirtualMachine>
<JEEServer>
<Properties>
<AppServerName type="class java.lang.String">Apache Tomcat/7.0.11</AppServerName>
</Properties>
</JEEServer>
</Info>
c) To query specific MBeans, use:
https://<host:port>/BeanSpy/MBeans?JMXQuery=<BeanObjectName>
For instance, on Tomcat 7 to get a list of the deployed WebModules use the following (note: MaxDepth=0 displays only the Object Names of the MBeans)use https://localhost:8080/BeanSpy/MBeans?JMXQuery=Catalina:j2eeType=WebModule,*&MaxDepth=0. I will not do the full output of the JMX Query b/c Tomcat MBeans are quite verbose:
<?xml version="1.0" encoding="UTF-8" ?>
<MBeans version="7.4.1002.0">
<MBean Name="org.apache.catalina.mbeans.ContextMBean" objectName="Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/examples">
<objectName type="java.lang.String">Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/examples</objectName>
<objectNameElements type="objectName">
<Domain>Catalina</Domain>
<J2EEApplication>none</J2EEApplication>
<J2EEServer>none</J2EEServer>
<j2eeType>WebModule</j2eeType>
<name>//localhost/examples</name>
</objectNameElements>
</MBean>
<MBean Name="org.apache.catalina.mbeans.ContextMBean" objectName="Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/CustomOrderService">
<objectName type="java.lang.String">Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/CustomOrderService</objectName>
<objectNameElements type="objectName">
<Domain>Catalina</Domain>
<J2EEApplication>none</J2EEApplication>
<J2EEServer>none</J2EEServer>
<j2eeType>WebModule</j2eeType>
<name>//localhost/CustomOrderService</name>
</objectNameElements>
</MBean>
<MBean Name="org.apache.catalina.mbeans.ContextMBean" objectName="Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/BeanSpy">
<objectName type="java.lang.String">Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/BeanSpy</objectName>
<objectNameElements type="objectName">
<Domain>Catalina</Domain>
<J2EEApplication>none</J2EEApplication>
<J2EEServer>none</J2EEServer>
<j2eeType>WebModule</j2eeType>
<name>//localhost/BeanSpy</name>
</objectNameElements>
</MBean>
<MBean Name="org.apache.catalina.mbeans.ContextMBean" objectName="Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/docs">
<objectName type="java.lang.String">Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/docs</objectName>
<objectNameElements type="objectName">
<Domain>Catalina</Domain>
<J2EEApplication>none</J2EEApplication>
<J2EEServer>none</J2EEServer>
<j2eeType>WebModule</j2eeType>
<name>//localhost/docs</name>
</objectNameElements>
</MBean>
<MBean Name="org.apache.catalina.mbeans.ContextMBean" objectName="Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/host-manager">
<objectName type="java.lang.String">Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/host-manager</objectName>
<objectNameElements type="objectName">
<Domain>Catalina</Domain>
<J2EEApplication>none</J2EEApplication>
<J2EEServer>none</J2EEServer>
<j2eeType>WebModule</j2eeType>
<name>//localhost/host-manager</name>
</objectNameElements>
</MBean>
<MBean Name="org.apache.catalina.mbeans.ContextMBean" objectName="Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/manager">
<objectName type="java.lang.String">Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/manager</objectName>
<objectNameElements type="objectName">
<Domain>Catalina</Domain>
<J2EEApplication>none</J2EEApplication>
<J2EEServer>none</J2EEServer>
<j2eeType>WebModule</j2eeType>
<name>//localhost/manager</name>
</objectNameElements>
</MBean>
<MBean Name="org.apache.catalina.mbeans.ContextMBean" objectName="Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/">
<objectName type="java.lang.String">Catalina:J2EEApplication=none,J2EEServer=none,j2eeType=WebModule,name=//localhost/</objectName>
<objectNameElements type="objectName">
<Domain>Catalina</Domain>
<J2EEApplication>none</J2EEApplication>
<J2EEServer>none</J2EEServer>
<j2eeType>WebModule</j2eeType>
<name>//localhost/</name>
</objectNameElements>
</MBean>
</MBeans>
BeanSpy HTTP POST operations
Some MBean information is not available by through properties, instead a method call to the MBean is necessary. To invoke a method on a MBean, use HTTP POST:
https://<host:port>/BeanSpy/MBeans/Invoke
The HTTP post body should look like this:
<Invoke>
<BeanObjectName>com.contoso:name=CustomMBeanName</BeanObjectName>
<Method name="FooMethod">
<Param name="p0" type="java.lang.Integer">400</Param>
<Param name="p1" type="java.lang.String">bar</Param>
</Method>
</Invoke>
The Result XML should look like:
<?xml version="1.0" encoding="UTF-8"?>
<InvokeResponse>
<Result>SUCCESS</Result>
<Response type="java.lang.Integer">2</Response>
</InvokeResponse>
Comments
Anonymous
January 01, 2003
Hi Kenneth & thanks for the comment. The short answer to your question is no. That said, there more to come regarding monitoring Java. If you like, I could contact you offline to better understand your scenario.Anonymous
January 01, 2003
The supported platforms can be found in the documentation per application server here: www.microsoft.com/.../details.aspx For Tomcat, the Windows platforms are: Windows Server 2003 SP2 Windows Server 2003 R2 SP2 Windows Server 2008 SP2 and above Windows Server 2008 R2 and aboveAnonymous
January 01, 2003
Hi, I need to deploy beanspy on jboss v 6.1.1 on a windows server. Platform: windows server 2012 System center 2012 R2 I have the below queries: 1. which file to install for Http with authentication application 2.The detailed deployment process of windows jboss server. I have no previous experience of jboss application or bean spy.Anonymous
January 01, 2003
No, BeanSpy was designed for monitoring Web applications.Anonymous
January 01, 2003
Hi, Is it must to deploy the MBeanspy in Application server to monitor the Tomcat6 application running on Windows Server 2008. Regards, SundarAnonymous
March 08, 2012
interesting, I'm investigating using this with scom 2012. I'm wondering whether you plan to extend beanspy to do generic JMX monitoring, for generic java jvms that aren't running inside of a middleware layer? KAnonymous
September 10, 2013
Hi, Is it possible to use BeanSpy to monitor JVMs that are running on the machine but are not a running web application in the application server? For example, I have a machine with Tomcat which independently runs a standard Java application (or "service"). Is it possible to monitor my application using BeanSpy?