001package io.prometheus.metrics.instrumentation.jvm; 002 003import static io.prometheus.metrics.model.snapshots.Unit.millisToSeconds; 004 005import io.prometheus.metrics.config.PrometheusProperties; 006import io.prometheus.metrics.core.metrics.CounterWithCallback; 007import io.prometheus.metrics.model.registry.PrometheusRegistry; 008import io.prometheus.metrics.model.snapshots.Unit; 009import java.lang.management.CompilationMXBean; 010import java.lang.management.ManagementFactory; 011 012/** 013 * JVM Compilation metrics. The {@link JvmCompilationMetrics} are registered as part of the {@link 014 * JvmMetrics} like this: 015 * 016 * <pre>{@code 017 * JvmMetrics.builder().register(); 018 * }</pre> 019 * 020 * However, if you want only the {@link JvmCompilationMetrics} you can also register them directly: 021 * 022 * <pre>{@code 023 * JvmCompilationMetrics.builder().register(); 024 * }</pre> 025 * 026 * Example metrics being exported: 027 * 028 * <pre> 029 * # HELP jvm_compilation_time_seconds_total The total time in seconds taken for HotSpot class compilation 030 * # TYPE jvm_compilation_time_seconds_total counter 031 * jvm_compilation_time_seconds_total 0.152 032 * </pre> 033 */ 034public class JvmCompilationMetrics { 035 036 private static final String JVM_COMPILATION_TIME_SECONDS_TOTAL = 037 "jvm_compilation_time_seconds_total"; 038 039 private final PrometheusProperties config; 040 private final CompilationMXBean compilationBean; 041 042 private JvmCompilationMetrics(CompilationMXBean compilationBean, PrometheusProperties config) { 043 this.compilationBean = compilationBean; 044 this.config = config; 045 } 046 047 private void register(PrometheusRegistry registry) { 048 049 if (compilationBean == null || !compilationBean.isCompilationTimeMonitoringSupported()) { 050 return; 051 } 052 053 CounterWithCallback.builder(config) 054 .name(JVM_COMPILATION_TIME_SECONDS_TOTAL) 055 .help("The total time in seconds taken for HotSpot class compilation") 056 .unit(Unit.SECONDS) 057 .callback( 058 callback -> callback.call(millisToSeconds(compilationBean.getTotalCompilationTime()))) 059 .register(registry); 060 } 061 062 public static Builder builder() { 063 return new Builder(PrometheusProperties.get()); 064 } 065 066 public static Builder builder(PrometheusProperties config) { 067 return new Builder(config); 068 } 069 070 public static class Builder { 071 072 private final PrometheusProperties config; 073 private CompilationMXBean compilationBean; 074 075 private Builder(PrometheusProperties config) { 076 this.config = config; 077 } 078 079 /** Package private. For testing only. */ 080 Builder compilationBean(CompilationMXBean compilationBean) { 081 this.compilationBean = compilationBean; 082 return this; 083 } 084 085 public void register() { 086 register(PrometheusRegistry.defaultRegistry); 087 } 088 089 public void register(PrometheusRegistry registry) { 090 CompilationMXBean compilationBean = 091 this.compilationBean != null 092 ? this.compilationBean 093 : ManagementFactory.getCompilationMXBean(); 094 new JvmCompilationMetrics(compilationBean, config).register(registry); 095 } 096 } 097}