001package io.prometheus.metrics.model.snapshots;
002
003import io.prometheus.metrics.annotations.StableApi;
004
005/**
006 * Common base class for histogram and summary data. Histograms and Summaries represent
007 * distributions, like a latency distribution or a distribution of request sizes in Bytes.
008 */
009@StableApi
010public abstract class DistributionDataPointSnapshot extends DataPointSnapshot {
011  private final long count; // optional, negative value means no count.
012  private final double sum; // optional, Double.NaN means no sum.
013  private final Exemplars exemplars; // optional, Exemplars.EMPTY means no Exemplars.
014
015  /** See JavaDoc of the child classes. */
016  protected DistributionDataPointSnapshot(
017      long count,
018      double sum,
019      Exemplars exemplars,
020      Labels labels,
021      long createdTimestampMillis,
022      long scrapeTimestampMillis,
023      boolean internal) {
024    super(labels, createdTimestampMillis, scrapeTimestampMillis, internal);
025    this.count = count;
026    this.sum = sum;
027    this.exemplars = exemplars == null ? Exemplars.EMPTY : exemplars;
028    if (!internal) {
029      validate();
030    }
031  }
032
033  private void validate() {
034    // If a histogram or summary observes negative values the sum could be negative.
035    // According to OpenMetrics sum should be omitted in that case, but we don't enforce this here.
036  }
037
038  public boolean hasCount() {
039    return count >= 0;
040  }
041
042  public boolean hasSum() {
043    return !Double.isNaN(sum);
044  }
045
046  /** This will return garbage if {@link #hasCount()} is {@code false}. */
047  public long getCount() {
048    return count;
049  }
050
051  /** This will return garbage if {@link #hasSum()} is {@code false}. */
052  public double getSum() {
053    return sum;
054  }
055
056  /** May be {@link Exemplars#EMPTY}, but will never be {@code null}. */
057  public Exemplars getExemplars() {
058    return exemplars;
059  }
060
061  abstract static class Builder<T extends Builder<T>> extends DataPointSnapshot.Builder<T> {
062
063    protected long count = -1;
064    protected double sum = Double.NaN;
065    protected long createdTimestampMillis = 0L;
066    protected Exemplars exemplars = Exemplars.EMPTY;
067
068    /**
069     * Count can be explicitly set on summaries (this is a public method for summary metrics), and
070     * it is set implicitly on histograms (derived from the bucket counts).
071     */
072    protected T count(long count) {
073      this.count = count;
074      return self();
075    }
076
077    public T sum(double sum) {
078      this.sum = sum;
079      return self();
080    }
081
082    public T exemplars(Exemplars exemplars) {
083      this.exemplars = exemplars;
084      return self();
085    }
086
087    public T createdTimestampMillis(long createdTimestampMillis) {
088      this.createdTimestampMillis = createdTimestampMillis;
089      return self();
090    }
091  }
092}