Created
January 14, 2022 14:26
-
-
Save jkuipers/1e0bfaf7dcb2c4002864be7813343272 to your computer and use it in GitHub Desktop.
Micrometer.io heap statistics for OpenJ9 VMs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import io.micrometer.core.instrument.Gauge; | |
import io.micrometer.core.instrument.MeterRegistry; | |
import io.micrometer.core.instrument.binder.BaseUnits; | |
import io.micrometer.core.instrument.binder.MeterBinder; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.util.ReflectionUtils; | |
import java.lang.reflect.Method; | |
/** | |
* Provides the used heap memory as a percentage so that we can scale based on that metric. | |
* Uses OpenJ9-specific class, therefore the code uses reflection so that this will also | |
* compile using an OpenJDK. | |
* | |
* @see <a href="https://www.eclipse.org/openj9/docs/api/jdk11/openj9.jvm/com/ibm/jvm/Stats.html">JavaDoc for Stats</a> | |
*/ | |
public class OpenJ9MemoryMetrics implements MeterBinder { | |
private Object stats; | |
private Method getStats; | |
private Method getUsedHeap; | |
private long maxHeap; | |
private Logger logger = LoggerFactory.getLogger(getClass()); | |
public OpenJ9MemoryMetrics() { | |
try { | |
Class statsClass = Class.forName("com.ibm.jvm.Stats"); | |
this.stats = statsClass.getDeclaredConstructor().newInstance(); | |
this.getStats = statsClass.getMethod("getStats"); | |
this.getUsedHeap = statsClass.getMethod("getUsedHeap"); | |
ReflectionUtils.invokeMethod(getStats, stats); | |
this.maxHeap = (long) ReflectionUtils.invokeMethod(statsClass.getMethod("getMaxHeap"), stats); | |
} catch (Exception e) { | |
logger.error("Failed to initialize OpenJ9MemoryMetrics", e); | |
} | |
} | |
@Override | |
public void bindTo(MeterRegistry registry) { | |
if (this.maxHeap != 0L) { | |
try { | |
Gauge.builder("jvm.memory.heap-used-percentage", stats, stats -> { | |
ReflectionUtils.invokeMethod(getStats, stats); | |
long usedHeap = (long) ReflectionUtils.invokeMethod(getUsedHeap, stats); | |
return ((double) usedHeap) / maxHeap; | |
}) | |
.description("Percentage of heap used by the JVM in the range [0..1], based on used divided by max as reported by OpenJ9's Stats class") | |
.baseUnit(BaseUnits.PERCENT) | |
.register(registry); | |
} catch (Exception e) { | |
logger.error("Could not create heap percentage gauge", e); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment