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