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