001package io.prometheus.metrics.model.snapshots;
002
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.List;
006
007/** Immutable snapshot of a Gauge. */
008public final class GaugeSnapshot extends MetricSnapshot {
009
010  /**
011   * To create a new {@link GaugeSnapshot}, you can either call the constructor directly or use the
012   * builder with {@link GaugeSnapshot#builder()}.
013   *
014   * @param metadata see {@link MetricMetadata} for naming conventions.
015   * @param data the constructor will create a sorted copy of the collection.
016   */
017  public GaugeSnapshot(MetricMetadata metadata, Collection<GaugeDataPointSnapshot> data) {
018    super(metadata, data);
019  }
020
021  @SuppressWarnings("unchecked")
022  @Override
023  public List<GaugeDataPointSnapshot> getDataPoints() {
024    return (List<GaugeDataPointSnapshot>) dataPoints;
025  }
026
027  public static final class GaugeDataPointSnapshot extends DataPointSnapshot {
028
029    private final double value;
030    private final Exemplar exemplar; // may be null
031
032    /**
033     * To create a new {@link GaugeDataPointSnapshot}, you can either call the constructor directly
034     * or use the Builder with {@link GaugeDataPointSnapshot#builder()}.
035     *
036     * @param value the gauge value.
037     * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels.
038     * @param exemplar may be null.
039     */
040    public GaugeDataPointSnapshot(double value, Labels labels, Exemplar exemplar) {
041      this(value, labels, exemplar, 0);
042    }
043
044    /**
045     * Constructor with an additional scrape timestamp. This is only useful in rare cases as the
046     * scrape timestamp is usually set by the Prometheus server during scraping. Exceptions include
047     * mirroring metrics with given timestamps from other metric sources.
048     */
049    public GaugeDataPointSnapshot(
050        double value, Labels labels, Exemplar exemplar, long scrapeTimestampMillis) {
051      super(labels, 0L, scrapeTimestampMillis);
052      this.value = value;
053      this.exemplar = exemplar;
054    }
055
056    public double getValue() {
057      return value;
058    }
059
060    /** May be {@code null}. */
061    public Exemplar getExemplar() {
062      return exemplar;
063    }
064
065    public static Builder builder() {
066      return new Builder();
067    }
068
069    public static class Builder extends DataPointSnapshot.Builder<Builder> {
070
071      private Exemplar exemplar = null;
072      private Double value = null;
073
074      private Builder() {}
075
076      /** Gauge value. This is required. */
077      public Builder value(double value) {
078        this.value = value;
079        return this;
080      }
081
082      /** Optional */
083      public Builder exemplar(Exemplar exemplar) {
084        this.exemplar = exemplar;
085        return this;
086      }
087
088      public GaugeDataPointSnapshot build() {
089        if (value == null) {
090          throw new IllegalArgumentException("Missing required field: value is null.");
091        }
092        return new GaugeDataPointSnapshot(value, labels, exemplar, scrapeTimestampMillis);
093      }
094
095      @Override
096      protected Builder self() {
097        return this;
098      }
099    }
100  }
101
102  public static Builder builder() {
103    return new Builder();
104  }
105
106  public static class Builder extends MetricSnapshot.Builder<Builder> {
107
108    private final List<GaugeDataPointSnapshot> dataPoints = new ArrayList<>();
109
110    private Builder() {}
111
112    /** Add a data point. This can be called multiple times to add multiple data points. */
113    public Builder dataPoint(GaugeDataPointSnapshot dataPoint) {
114      dataPoints.add(dataPoint);
115      return this;
116    }
117
118    @Override
119    public GaugeSnapshot build() {
120      return new GaugeSnapshot(buildMetadata(), dataPoints);
121    }
122
123    @Override
124    protected Builder self() {
125      return this;
126    }
127  }
128}