JVM Integration for Metrics - A set of classes which allow you to monitor critical aspects of your Java Virtual Machine using Metrics
—
Generic JMX attribute monitoring for custom MBean attributes, providing flexible access to any JMX-exposed metric in the JVM or application.
import com.codahale.metrics.jvm.JmxAttributeGauge;
import com.codahale.metrics.MetricRegistry;
import javax.management.ObjectName;
import javax.management.MBeanServerConnection;Provides direct access to JMX MBean attributes with flexible connection and naming support.
/**
* A Gauge implementation which queries an MBeanServerConnection for an attribute of an object.
*/
public class JmxAttributeGauge implements Gauge<Object> {
/**
* Creates a new JmxAttributeGauge using the platform MBean server.
* @param objectName the name of the object
* @param attributeName the name of the object's attribute
*/
public JmxAttributeGauge(ObjectName objectName, String attributeName);
/**
* Creates a new JmxAttributeGauge with a custom MBeanServerConnection.
* @param mBeanServerConn the MBeanServerConnection
* @param objectName the name of the object
* @param attributeName the name of the object's attribute
*/
public JmxAttributeGauge(MBeanServerConnection mBeanServerConn, ObjectName objectName, String attributeName);
/**
* Gets the current value of the JMX attribute.
* @return the attribute value, or null if unavailable
*/
public Object getValue();
}Usage Examples:
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.jvm.JmxAttributeGauge;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
// Basic usage with platform MBean server
MetricRegistry registry = new MetricRegistry();
// Monitor JVM memory usage
ObjectName memoryName = new ObjectName("java.lang:type=Memory");
JmxAttributeGauge heapUsed = new JmxAttributeGauge(memoryName, "HeapMemoryUsage");
registry.register("jvm.memory.heap.composite", heapUsed);
// Monitor specific memory pool
ObjectName poolName = new ObjectName("java.lang:type=MemoryPool,name=PS Eden Space");
JmxAttributeGauge poolUsage = new JmxAttributeGauge(poolName, "Usage");
registry.register("jvm.memory.pool.eden.usage", poolUsage);
// Monitor garbage collector information
ObjectName gcName = new ObjectName("java.lang:type=GarbageCollector,name=PS Scavenge");
JmxAttributeGauge gcCount = new JmxAttributeGauge(gcName, "CollectionCount");
JmxAttributeGauge gcTime = new JmxAttributeGauge(gcName, "CollectionTime");
registry.register("jvm.gc.ps-scavenge.count", gcCount);
registry.register("jvm.gc.ps-scavenge.time", gcTime);
// Access attribute values
Object heapUsage = heapUsed.getValue();
System.out.println("Heap usage: " + heapUsage);
Long collectionCount = (Long) gcCount.getValue();
Long collectionTime = (Long) gcTime.getValue();
System.out.println("GC collections: " + collectionCount);
System.out.println("GC time: " + collectionTime + " ms");
// Custom MBeanServerConnection
MBeanServerConnection customConnection = ManagementFactory.getPlatformMBeanServer();
ObjectName customName = new ObjectName("com.example:type=CustomMetric");
JmxAttributeGauge customGauge = new JmxAttributeGauge(customConnection, customName, "Value");
registry.register("custom.metric", customGauge);Pattern Matching Support:
The JmxAttributeGauge supports ObjectName patterns for dynamic MBean discovery:
// Pattern-based ObjectName for dynamic discovery
ObjectName pattern = new ObjectName("java.lang:type=MemoryPool,name=*");
JmxAttributeGauge dynamicGauge = new JmxAttributeGauge(pattern, "Usage");
// When multiple MBeans match the pattern, the first one found is used
// For single-match scenarios, this provides flexibility in MBean namingCommon JMX ObjectName Patterns:
// Memory and GC monitoring
new ObjectName("java.lang:type=Memory");
new ObjectName("java.lang:type=MemoryPool,name=*");
new ObjectName("java.lang:type=GarbageCollector,name=*");
// Thread monitoring
new ObjectName("java.lang:type=Threading");
// Class loading
new ObjectName("java.lang:type=ClassLoading");
// Runtime information
new ObjectName("java.lang:type=Runtime");
// Operating system
new ObjectName("java.lang:type=OperatingSystem");
// Buffer pools (Java 7+)
new ObjectName("java.nio:type=BufferPool,name=*");
// Application-specific MBeans
new ObjectName("com.myapp:type=DatabasePool,name=primary");
new ObjectName("com.myapp:type=Cache,name=*");Error Handling:
// Robust error handling example
public class SafeJmxAttributeGauge extends JmxAttributeGauge {
private final String description;
public SafeJmxAttributeGauge(ObjectName objectName, String attributeName, String description) {
super(objectName, attributeName);
this.description = description;
}
@Override
public Object getValue() {
try {
Object value = super.getValue();
if (value == null) {
System.err.println("Warning: " + description + " returned null");
}
return value;
} catch (Exception e) {
System.err.println("Error reading " + description + ": " + e.getMessage());
return null;
}
}
}
// Usage with error handling
SafeJmxAttributeGauge safeGauge = new SafeJmxAttributeGauge(
new ObjectName("java.lang:type=Memory"),
"HeapMemoryUsage",
"JVM Heap Memory Usage"
);Composite Attributes:
Many JMX attributes return composite data types. Handle them appropriately:
import javax.management.openmbean.CompositeData;
JmxAttributeGauge memoryUsage = new JmxAttributeGauge(
new ObjectName("java.lang:type=Memory"),
"HeapMemoryUsage"
);
Object value = memoryUsage.getValue();
if (value instanceof CompositeData) {
CompositeData composite = (CompositeData) value;
Long used = (Long) composite.get("used");
Long max = (Long) composite.get("max");
Long committed = (Long) composite.get("committed");
Long init = (Long) composite.get("init");
System.out.println("Heap used: " + used);
System.out.println("Heap max: " + max);
System.out.println("Heap committed: " + committed);
System.out.println("Heap init: " + init);
}Best Practices:
Install with Tessl CLI
npx tessl i tessl/maven-io-dropwizard-metrics--metrics-jvm