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