001package io.prometheus.client;
002
003import java.util.ArrayList;
004import java.util.List;
005import java.util.Collections;
006
007/**
008 * Summary metric family, for custom collectors and exporters.
009 * <p>
010 * Most users want a normal {@link Summary} instead.
011 *
012 * Example usage:
013 * <pre>
014 * {@code
015 *   class YourCustomCollector extends Collector {
016 *     List<MetricFamilySamples> collect() {
017 *       List<MetricFamilySamples> mfs = new ArrayList<MetricFamilySamples>();
018 *       // With no labels.
019 *       mfs.add(new SummaryMetricFamily("my_summary", "help", 1, 42));
020 *       // With labels. Record 95th percentile as 3, and 99th percentile as 5.
021 *       SummaryMetricFamily labeledSummary = new SummaryMetricFamily("my_other_summary", "help", 
022 *           Arrays.asList("labelname"), Arrays.asList(.95, .99));
023 *       labeledSummary.addMetric(Arrays.asList("foo"), 2, 10, Arrays.asList(3.0, 5.0));
024 *       mfs.add(labeledSummary);
025 *       return mfs;
026 *     }
027 *   }
028 * }
029 * </pre>
030 */
031public class SummaryMetricFamily extends Collector.MetricFamilySamples {
032
033  private final List<String> labelNames;
034  private final List<Double> quantiles;
035
036  public SummaryMetricFamily(String name, String help, double count, double sum) {
037    super(name, Collector.Type.SUMMARY, help, new ArrayList<Sample>());
038    this.labelNames = Collections.emptyList();
039    this.quantiles = Collections.emptyList();
040    addMetric(Collections.<String>emptyList(), count, sum);
041  }
042
043  public SummaryMetricFamily(String name, String help, List<String> labelNames) {
044    this(name, help, labelNames, Collections.<Double>emptyList());
045  }
046  public SummaryMetricFamily(String name, String help, List<String> labelNames, List<Double>quantiles) {
047    super(name, Collector.Type.SUMMARY, help, new ArrayList<Sample>());
048    this.labelNames = labelNames;
049    this.quantiles = quantiles;
050  }
051
052  public SummaryMetricFamily addMetric(List<String> labelValues, double count, double sum) {
053    return addMetric(labelValues, count, sum, Collections.<Double>emptyList());
054  }
055  public SummaryMetricFamily addMetric(List<String> labelValues, double count, double sum, List<Double> quantiles) {
056    if (labelValues.size() != labelNames.size()) {
057      throw new IllegalArgumentException("Incorrect number of labels.");
058    }
059    if (this.quantiles.size() != quantiles.size()) {
060      throw new IllegalArgumentException("Incorrect number of quantiles.");
061    }
062    samples.add(new Sample(name + "_count", labelNames, labelValues, count));
063    samples.add(new Sample(name + "_sum", labelNames, labelValues, sum));
064    List<String> labelNamesWithQuantile = new ArrayList<String>(labelNames);
065    labelNamesWithQuantile.add("quantile");
066    for (int i = 0; i < quantiles.size(); i++) {
067      List<String> labelValuesWithQuantile = new ArrayList<String>(labelValues);
068      labelValuesWithQuantile.add(Collector.doubleToGoString(this.quantiles.get(i)));
069      samples.add(new Sample(name, labelNamesWithQuantile, labelValuesWithQuantile, quantiles.get(i)));
070    }
071    return this;
072  }
073}