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