jmx4r, a JMX Libary for JRuby
Just in time for the release of JRuby 1.0 and following my experiments with writing JRuby scripts to manage remote applications using JMX (part I & II), I created jmx4r, a simple library which makes it super easy to write such scripts.
For example, to trigger a Garbage Collection on a remote Java application , the whole script is:
require 'java'
require 'jmx4r'
memory = JMX::MBean.find_by_name "java.lang:type=Memory"
memory.verbose = true
memory.gc
Simple enough, isn't it?
JMX Connection
By default, jmx4r expects to connect to the remote MBean Server on localhost using the standard JMX Service URL. Otherwise, it is possible to set the host and port of the remote MBean Server:
JMX::MBean.establish_connection :host => "localhost", :port => 3000
Attributes & Operations naming convention
JMX attributes are available on the JRuby objects but their names are changed to be snake_cased instead of CamelCased.
For example, the LoadedClassCount
attribute of the java.lang:type=ClassLoading
MBean is available as the loaded_class_count
attribute on the corresponding JRuby object.
Ditto for the operations:
logging = JMX::MBean.find_by_name "java.util.logging:type=Logging"
logging.logger_names.each do |logger_name|
logging.set_logger_level logger_name, "INFO"
end
The set_logger_level
method corresponds to the setLoggerLevel
MBean operations.
Features List
For now, the features of jmx4r are:
- read MBean attributes:
memory = JMX::MBean.find_by_name "java.lang:type=Memory"
puts "verbose : #{memory.verbose}"
- write MBean attributes (provided they are writable):
memory = JMX::MBean.find_by_name "java.lang:type=Memory"
memory.verbose != memory.verbose
- invoke MBean operations (provided the parameters types are simple):
memory = JMX::MBean.find_by_name "java.lang:type=Memory"
memory.gc
logging = JMX::MBean.find_by_name "java.util.logging:type=Logging"
logging.set_logger_level "global", "INFO"
- query for MBeans:
memory_pools = JMX::MBean.find_all_by_name "java.lang:type=MemoryPool,*"
memory_pools.each { |mem_pool| puts mem_pool.name }
- get the ObjectName correponding to a MBean:
memory_pools = JMX::MBean.find_all_by_name "java.lang:type=MemoryPool,*"
memory_pools.each { |mem_pool| puts mem_pool.object_name }
Next steps are:
- provide comprehensive tests
- document the library
- make a gem to simplify its deployment