001package io.prometheus.metrics.model.snapshots; 002 003/** 004 * Common base class for histogram and summary data. Histograms and Summaries represent 005 * distributions, like a latency distribution or a distribution of request sizes in Bytes. 006 */ 007public abstract class DistributionDataPointSnapshot extends DataPointSnapshot { 008 private final long count; // optional, negative value means no count. 009 private final double sum; // optional, Double.NaN means no sum. 010 private final Exemplars exemplars; // optional, Exemplars.EMPTY means no Exemplars. 011 012 /** See JavaDoc of the child classes. */ 013 protected DistributionDataPointSnapshot( 014 long count, 015 double sum, 016 Exemplars exemplars, 017 Labels labels, 018 long createdTimestampMillis, 019 long scrapeTimestampMillis, 020 boolean internal) { 021 super(labels, createdTimestampMillis, scrapeTimestampMillis, internal); 022 this.count = count; 023 this.sum = sum; 024 this.exemplars = exemplars == null ? Exemplars.EMPTY : exemplars; 025 if (!internal) { 026 validate(); 027 } 028 } 029 030 private void validate() { 031 // If a histogram or summary observes negative values the sum could be negative. 032 // According to OpenMetrics sum should be omitted in that case, but we don't enforce this here. 033 } 034 035 public boolean hasCount() { 036 return count >= 0; 037 } 038 039 public boolean hasSum() { 040 return !Double.isNaN(sum); 041 } 042 043 /** This will return garbage if {@link #hasCount()} is {@code false}. */ 044 public long getCount() { 045 return count; 046 } 047 048 /** This will return garbage if {@link #hasSum()} is {@code false}. */ 049 public double getSum() { 050 return sum; 051 } 052 053 /** May be {@link Exemplars#EMPTY}, but will never be {@code null}. */ 054 public Exemplars getExemplars() { 055 return exemplars; 056 } 057 058 abstract static 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), and 067 * 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}