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