Jmx4Perl 0.70

Posted on July 10th, 2010 by roland

I’m happy to announce the new jmx4perl release 0.70 with a lot of new features. The most exciting new stuff are configuration files and multi-checks for check_jmx4perl, a new Java client library and the start of a readline based JMX shell j4psh with syntax highlighting and command line completion.

The Jmx4Perl summer update

It took some time (and nerves), but finally jmx4perl is now available at version 0.70 with quite some new features. Although the jump in the version number is quite minor, this is probably the release with the largest feature delta to its predecessor.

check_jmx4perl

The documentation for check_jmx4perl has been largely extended. It contains now about 30 pages including a quick start style tutorial, background information and reference documentation.

In addition to the traditional way of specifying the check parameters via command line options, checks can now be defined in the configuration files, too. A configuration file is divided into two parts: A section for defining server connection parameters and a section for check configurations. A sample config file looks like:

 # Define server connection parameters
 <Server tomcat>
    Url = http://localhost:8080/j4p
 </Server>
 
 # A simple heap memory check with a critical threshold of 
 # 90% of the maximum heap memory. 
 <Check memory_heap>     
   Value = java.lang:type=Memory/HeapMemoryUsage/used
   Base = java.lang:type=Memory/HeapMemoryUsage/max
   Label = Heap-Memory: %.2r% used (%.2v %u / %.2b %u)
   Critical = 90
 </Check>

This configuration file then can be used by check_jmx4perl:

   check_jmx4perl --config path/to/config --server tomcat --check memory_heap

Advanced features tunable with the configuration syntax are:

  • Checks can inherit from parent checks via the Use directive
  • Parameterized checks. Positional placeholders like $0 are filled in from inherited checks or command line arguments.
  • Check parameters can take default values
  • Multiple checks can be combined with <MultiCheck> by referencing already defined checks. A multi-check uses only a single server turnaround for fetching the values.
  • A set of prefedefined checks comes with this release (threads.cfg, memory.cfg, tomcat.cfg, jetty.cfg)

Java client library

Starting with 0.70, a Java client library has been added for accessing the j4p-Agent. It provides an easy to use, typeless semantics and supports bulk requests. The usages is fairly easy:

  J4pClient j4pClient = new J4pClient("http://localhost:8080/j4p");
  J4pReadRequest request = new J4pReadRequest("java.lang:type=Memory","HeapMemoryUsage");
  J4pReadResponse response = j4pClient.execute(request);
  long usedMemory = Long.parseLong(response.getValue().get("used"));

Currently, reading and writing attributes and execution of operations is supported. List and search operations are scheduled for the next release. Note also, that the API is somewhat in flux, so consider this release in beta state for the moment.

j4psh

In the same spirit as osgish (my litte OSGi shell) j4psh provides interactive access to remote MBeans which are exposed with via the j4p-agent. It is the perfect tool for exploring the JMX namespace and accessing attributes or executing operations interactively.

j4psh provides:

  • GNU Readline support with history saved accross sessions
  • Context sensitive command line completion
  • Emacs key bindings ;-)
  • Consistent syntax highlighting (switchable) with color theme support
  • Listing of MBeans, reading and writing of attributes, execution of operations

Here’s a first screenshot, a screencast will follow:

Security enhancements

Since quite some time jmx4perl knows about policy files (j4p-access.xml) for enabling fine granular security. The syntax of this configuration has been extended in order to allow wildcards (*) for attribute and operation names as well as separate <allow> and <deny> sections for overwriting default behaviour.

Example:

 <restrict>
   <!-- For each command type missing in a given <commands> section, 
           for certain MBeans (which might be a pattern, too) 
           a command be allowed. Note that an <allow> entry e.g. 
           for reading an attribute of an certain MBean has no influence if reading 
           is enabled globally anyway -->
   <allow>
     <!-- Allow access to the j4p configuration operations, which are needed 
              for proper check_jmx4perl operation -->
     <mbean>
       <name>jmx4perl:type=Config</name>
       <operation>*</operation>
       <attribute>*</attribute>
     </mbean>
   </allow>
 
   <!-- MBean access can be restricted by a <deny> section 
            for commands enabled in a <commands> section
            (or when the <commands> section is missing completely 
            in which case all commands are allowed)
   -->
   <deny>
     <mbean>
       <!-- Exposes user/password of data source, so we forbid this one always -->
       <name>com.mchange.v2.c3p0:type=PooledDataSource*</name>
       <attribute>properties</attribute>
     </mbean>
   </deny>
 </restrict>

Minor fixes and enhancements

Finally, some minor bug fixes and enhancements has been included, too:

  • check_jmx4perl: Added --value as a shortcut for –mbean/–attribute/–value
  • Path elements containing ‘/‘ can now be escaped with ‘\/
  • j4p-osgi-bundle including pax-web-bundle so only a single bundle is needed for deploying (when no OSGi HttpService is installed)
  • Relaxed version requirements on core and compendium OSGi classes for j4p-osgi bundle.
  • Added logging (level info) for printing out which security policy is used during startup
  • Switched from JUnit to TestNG for testing because of support for testing groups
  • New servlet init parameter option ‘mbeanQualifier’ to allow multiple j4p-servlet in a single application server

I hope you have much fun with this release, any feedback is highly appreciated (as always).

Filed under Jmx4Perl |

4 Responses to “Jmx4Perl 0.70”

  1. Greg Says:
    August 8th, 2010 at 22:22

    Hello Roland,

    Thanks for this great module! I arrived at this page by googling “jmx4perl c3p0″. I am trying to use the get_attribute method to read the c3p0 mbeans like so:

    my $jdbc = $jmx->get_attribute(“com.mchange.v2.c3p0:*”, undef);

    But this does not work: Error requesting (com.mchange.v2.c3p0:*,): java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.io.StreamCorruptedException at ./test.pl line 70

    Do I have to search for it first?

    Thanks.

    [Reply]

    roland Reply:

    It seems, that reading one of the attributes results in an exception.

    Please send me (roland at cpan.org) the stacktrace which you get when requesting the agent with your browser: http://host:8080/j4p/read/com.mchange.c3p0:*

    The problem with a pattern read request of this kind is, if a read request on a single MBean fails on the server side, the whole request fails. To be on the save side, you should restrict the pattern as much as possible and provide the attribute names you are looking for as an array ref as second parameter to read.

    To find out which MBean cause problems, try ‘jmx4perl http://… attributes’ and examine the output for the c3p0 MBeans. This method is more robust since it doesn’t stop on the first mbean’s error.

    [Reply]

    Greg Reply:

    @roland,

    I’d love to send you the stacktrace, but I need you to tell me how to get at a target via the REST interface.

    [Reply]

  2. roland Says:
    August 10th, 2010 at 19:41

    @Greg, ah, ok. Now I understand your setup, you are using the proxy mode (well, should have been clear from the beginning, since it was a RMI marshalling exception). As described elsewhere in this blog (search for ‘proxy’), there a several issues with this operational mode. One of them is, that Java serialization becomes a problem if the classes to be serialized are not present at the proxy. (This is no problem for the ‘direct’ agent mode, since the agent uses JSON serialization which works in almost all circumstances). If you insist on the proxy mode ;-), you could try to package the c3p0.jar into the j4p.war (under WEB-INF/lib), so that at least c3p0 specific types can be deserialized between the proxy and the target server).

    For getting the full stacktrace, you need to used the request-response programming model of jmx4perl (pseudo-code):

      my $req = new JMX::Jmx4Perl::Request(READ,$mbean_pattern);
      #Add target below, see man page ....
      my $j4p = new JMX::Jmx4Perl(url => $proxy_url ... ); 
      my $resp = $j4p->execute($req);
      print Data::Dumper($resp);

    This will give you a full fledged stacktrace.

    The best chances to use the proxy mode is to restrict oneself to specific MBeans and specific attributes, which are simpe data types only.

    ‘hope this works for you, let me know if I could help you further ….

    [Reply]

Leave a Reply