001package io.prometheus.metrics.instrumentation.jvm;
002
003import io.prometheus.metrics.annotations.StableApi;
004import io.prometheus.metrics.config.PrometheusProperties;
005import io.prometheus.metrics.model.registry.PrometheusRegistry;
006import io.prometheus.metrics.model.snapshots.Labels;
007import java.util.Set;
008import java.util.concurrent.ConcurrentHashMap;
009
010/**
011 * Registers all JVM metrics. Example usage:
012 *
013 * <pre>{@code
014 * JvmMetrics.builder().register();
015 * }</pre>
016 */
017@StableApi
018public class JvmMetrics {
019
020  private static final Set<PrometheusRegistry> REGISTERED = ConcurrentHashMap.newKeySet();
021
022  public static Builder builder() {
023    return new Builder(PrometheusProperties.get());
024  }
025
026  // Note: Currently there is no configuration for JVM metrics, so it doesn't matter whether you
027  // pass a config or not.
028  // However, we will add config options in the future, like whether you want to use Prometheus
029  // naming conventions
030  // or OpenTelemetry semantic conventions for JVM metrics.
031  public static Builder builder(PrometheusProperties config) {
032    return new Builder(config);
033  }
034
035  public static class Builder {
036
037    private final PrometheusProperties config;
038    private Labels constLabels = Labels.EMPTY;
039
040    private Builder(PrometheusProperties config) {
041      this.config = config;
042    }
043
044    /** Set constant labels that will be applied to all JVM metrics registered by this builder. */
045    public Builder constLabels(Labels constLabels) {
046      this.constLabels = constLabels;
047      return this;
048    }
049
050    /**
051     * Register all JVM metrics with the default registry.
052     *
053     * <p>It's safe to call this multiple times, only the first call will register the metrics, all
054     * subsequent calls will be ignored.
055     */
056    public void register() {
057      register(PrometheusRegistry.defaultRegistry);
058    }
059
060    /**
061     * Register all JVM metrics with the {@code registry}.
062     *
063     * <p>It's safe to call this multiple times, only the first call will register the metrics, all
064     * subsequent calls will be ignored.
065     */
066    public void register(PrometheusRegistry registry) {
067      if (REGISTERED.add(registry)) {
068        JvmThreadsMetrics.builder(config).constLabels(constLabels).register(registry);
069        JvmBufferPoolMetrics.builder(config).constLabels(constLabels).register(registry);
070        JvmClassLoadingMetrics.builder(config).constLabels(constLabels).register(registry);
071        JvmCompilationMetrics.builder(config).constLabels(constLabels).register(registry);
072        JvmGarbageCollectorMetrics.builder(config).constLabels(constLabels).register(registry);
073        JvmMemoryPoolAllocationMetrics.builder(config).constLabels(constLabels).register(registry);
074        JvmMemoryMetrics.builder(config).constLabels(constLabels).register(registry);
075        JvmNativeMemoryMetrics.builder(config).constLabels(constLabels).register(registry);
076        JvmRuntimeInfoMetric.builder(config).constLabels(constLabels).register(registry);
077        ProcessMetrics.builder(config).constLabels(constLabels).register(registry);
078      }
079    }
080  }
081}