001package io.prometheus.metrics.instrumentation.jvm;
002
003import io.prometheus.metrics.annotations.StableApi;
004import io.prometheus.metrics.config.PrometheusProperties;
005import io.prometheus.metrics.core.metrics.Info;
006import io.prometheus.metrics.model.registry.PrometheusRegistry;
007import io.prometheus.metrics.model.snapshots.Labels;
008import javax.annotation.Nullable;
009
010/**
011 * JVM Runtime Info metric. The {@link JvmRuntimeInfoMetric} is registered as part of the {@link
012 * JvmMetrics} like this:
013 *
014 * <pre>{@code
015 * JvmMetrics.builder().register();
016 * }</pre>
017 *
018 * However, if you want only the {@link JvmRuntimeInfoMetric} you can also register them directly:
019 *
020 * <pre>{@code
021 * JvmRuntimeInfoMetric.builder().register();
022 * }</pre>
023 *
024 * <pre>
025 * # TYPE jvm_runtime info
026 * # HELP jvm_runtime JVM runtime info
027 * jvm_runtime_info{runtime="OpenJDK Runtime Environment",vendor="Oracle Corporation",version="1.8.0_382-b05"} 1
028 * </pre>
029 */
030@StableApi
031public class JvmRuntimeInfoMetric {
032
033  private static final String JVM_RUNTIME_INFO = "jvm_runtime_info";
034
035  private final PrometheusProperties config;
036  private final String version;
037  private final String vendor;
038  private final String runtime;
039  private final Labels constLabels;
040
041  private JvmRuntimeInfoMetric(
042      String version,
043      String vendor,
044      String runtime,
045      PrometheusProperties config,
046      Labels constLabels) {
047    this.config = config;
048    this.version = version;
049    this.vendor = vendor;
050    this.runtime = runtime;
051    this.constLabels = constLabels;
052  }
053
054  private void register(PrometheusRegistry registry) {
055
056    Info jvmInfo =
057        Info.builder(config)
058            .name(JVM_RUNTIME_INFO)
059            .help("JVM runtime info")
060            .labelNames("version", "vendor", "runtime")
061            .constLabels(constLabels)
062            .register(registry);
063
064    jvmInfo.setLabelValues(version, vendor, runtime);
065  }
066
067  public static Builder builder() {
068    return new Builder(PrometheusProperties.get());
069  }
070
071  public static Builder builder(PrometheusProperties config) {
072    return new Builder(config);
073  }
074
075  public static class Builder {
076
077    private final PrometheusProperties config;
078    @Nullable private String version;
079    @Nullable private String vendor;
080    @Nullable private String runtime;
081    private Labels constLabels = Labels.EMPTY;
082
083    private Builder(PrometheusProperties config) {
084      this.config = config;
085    }
086
087    public Builder constLabels(Labels constLabels) {
088      this.constLabels = constLabels;
089      return this;
090    }
091
092    /** Package private. For testing only. */
093    Builder version(String version) {
094      this.version = version;
095      return this;
096    }
097
098    /** Package private. For testing only. */
099    Builder vendor(String vendor) {
100      this.vendor = vendor;
101      return this;
102    }
103
104    /** Package private. For testing only. */
105    Builder runtime(String runtime) {
106      this.runtime = runtime;
107      return this;
108    }
109
110    public void register() {
111      register(PrometheusRegistry.defaultRegistry);
112    }
113
114    public void register(PrometheusRegistry registry) {
115      String version =
116          this.version != null
117              ? this.version
118              : System.getProperty("java.runtime.version", "unknown");
119      String vendor =
120          this.vendor != null ? this.vendor : System.getProperty("java.vm.vendor", "unknown");
121      String runtime =
122          this.runtime != null ? this.runtime : System.getProperty("java.runtime.name", "unknown");
123      new JvmRuntimeInfoMetric(version, vendor, runtime, config, constLabels).register(registry);
124    }
125  }
126}