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}