Monitoring a java application with mbeans. An example with samtools/htsjdk.
"A MBean is a Java object that follows the JMX specification. A MBean can represent a device, an application, or any resource that needs to be managed. The JConsole graphical user interface is a monitoring tool that complies to the JMX specification.". In this post I'll show how I've modified the sources of the htsjdk library to monitor the java program reading a VCF file from the Exac server. See my commit at https://github.com/lindenb/htsjdk/commit/3c1ac1a18917aaa69f8dc49c70fd893a6a0542c3.
First, we define a java class ProgressLoggerMBean to tell java about the informations that will be forwarded to the jconsole: the number of records processed, the elapsed time, etc...
package htsjdk.samtools.util; public interface ProgressLoggerMBean { /* the noun to use when logging, e.g. "Records, Variants, Loci" */ public String getNoun(); /* verb the verb to log, e.g. "Processed, Read, Written" */ public String getVerb(); /** Returns the count of records processed. */ public long getCount(); /** elapsed time */ public String getElapsedTime(); /** last record */ public String getLastRecord(); }The already existing htsjdk class htsjdk.samtools.util.ProgressLogger is modified: it now implements ProgressLoggerMBean:
public class ProgressLogger implements ProgressLoggerInterface, Closeable, ProgressLoggerMBeanThe methods are implemented:
(...) @Override public String getElapsedTime(){ return this.formatElapseTime(this.getElapsedSeconds()); } @Override public String getLastRecord(){ return this.lastRecord; }In the constructor we try to connect to the MBean server that has been created and initialized by the platform. The ProgressLogger is wrapped into an ObjectName and inserted in the MBean server:
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); /* defines an object name for the MBean instance that it will create */ this.objectMBean = new ObjectName("htsjdk.samtools.util:type="+noun); mbs.registerMBean(this, this.objectMBean);
A 'close' method is used to unregister the object from the MBean server:
@Override public void close() { if(this.objectMBean!=null) { try { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); mbs.unregisterMBean(this.objectMBean); } catch(Exception err) { //ignore } finally { this.objectMBean=null; } }Here is an example. This program uses the htsjdk library to parse a VCF file:
import htsjdk.variant.vcf.*; import htsjdk.variant.variantcontext.*; import htsjdk.tribble.readers.*; import htsjdk.samtools.util.*; public class TestProgress { private final static Log log = Log.getInstance(TestProgress.class); public static void main(String args[]) throws Exception { ProgressLoggerInterface progress = new ProgressLogger(log, 1000, "Read VCF"); VCFCodec codec= new VCFCodec(); LineReader r= LineReaderUtil.fromBufferedStream(System.in); LineIteratorImpl t= new LineIteratorImpl(r); codec.readActualHeader(t); while(t.hasNext()) { VariantContext ctx = codec.decode(t.next()); progress.record(ctx.getContig(),ctx.getStart()); } r.close(); progress.close(); } }Compile and execute to download Exac:
javac -cp dist/htsjdk-1.130.jar:dist/snappy-java-1.0.3-rc3.jar:dist/commons-jexl-2.1.1.jar:dist/commons-logging-1.1.1.jar TestProgress.java && \ curl -s "ftp://ftp.broadinstitute.org/pub/ExAC_release/release0.3/ExAC.r0.3.sites.vep.vcf.gz" |\ gunzip -c |\ java -cp dist/htsjdk-1.130.jar:dist/snappy-java-1.0.3-rc3.jar:dist/commons-jexl-2.1.1.jar:dist/commons-logging-1.1.1.jar:. TestProgress (...) INFO 2015-05-07 21:07:02 TestProgress Read VCF 675,000 records. Elapsed time: 00:03:33s. Time for last 1,000: 0s. Last read position: 1:168,035,033 INFO 2015-05-07 21:07:03 TestProgress Read VCF 676,000 records. Elapsed time: 00:03:33s. Time for last 1,000: 0s. Last read position: 1:168,216,140 INFO 2015-05-07 21:07:03 TestProgress Read VCF 677,000 records. Elapsed time: 00:03:34s. Time for last 1,000: 0s. Last read position: 1:169,076,058 INFO 2015-05-07 21:07:03 TestProgress Read VCF 678,000 records. Elapsed time: 00:03:34s. Time for last 1,000: 0s. Last read position: 1:169,366,434 INFO 2015-05-07 21:07:03 TestProgress Read VCF 679,000 records. Elapsed time: 00:03:34s. Time for last 1,000: 0s. Last read position: 1:169,500,081 (...)
The progression can now be monitored in the jconsole:
That's it.
Pierre
No comments:
Post a Comment