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