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