001package io.prometheus.metrics.model.snapshots; 002 003import java.util.ArrayList; 004import java.util.Arrays; 005import java.util.Collection; 006import java.util.Iterator; 007import java.util.List; 008import java.util.stream.Stream; 009 010import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; 011import static java.util.Collections.unmodifiableList; 012import static java.util.Comparator.comparing; 013 014/** 015 * Immutable list of metric snapshots. 016 */ 017public class MetricSnapshots implements Iterable<MetricSnapshot> { 018 019 private final List<MetricSnapshot> snapshots; 020 021 /** 022 * See {@link #MetricSnapshots(Collection)} 023 */ 024 public MetricSnapshots(MetricSnapshot... snapshots) { 025 this(Arrays.asList(snapshots)); 026 } 027 028 /** 029 * To create MetricSnapshots, you can either call the constructor directly 030 * or use {@link #builder()}. 031 * 032 * @param snapshots the constructor creates a sorted copy of snapshots. 033 * @throws IllegalArgumentException if snapshots contains duplicate metric names. 034 * To avoid duplicate metric names use {@link #builder()} and check 035 * {@link Builder#containsMetricName(String)} before calling 036 * {@link Builder#metricSnapshot(MetricSnapshot)}. 037 */ 038 public MetricSnapshots(Collection<MetricSnapshot> snapshots) { 039 List<MetricSnapshot> list = new ArrayList<>(snapshots); 040 list.sort(comparing(s -> s.getMetadata().getPrometheusName())); 041 for (int i = 0; i < snapshots.size() - 1; i++) { 042 if (list.get(i).getMetadata().getPrometheusName().equals(list.get(i + 1).getMetadata().getPrometheusName())) { 043 throw new IllegalArgumentException(list.get(i).getMetadata().getPrometheusName() + ": duplicate metric name"); 044 } 045 } 046 this.snapshots = unmodifiableList(list); 047 } 048 049 public static MetricSnapshots of(MetricSnapshot... snapshots) { 050 return new MetricSnapshots(snapshots); 051 } 052 053 @Override 054 public Iterator<MetricSnapshot> iterator() { 055 return snapshots.iterator(); 056 } 057 058 public int size() { 059 return snapshots.size(); 060 } 061 062 public MetricSnapshot get(int i) { 063 return snapshots.get(i); 064 } 065 066 public Stream<MetricSnapshot> stream() { 067 return snapshots.stream(); 068 } 069 070 public static Builder builder() { 071 return new Builder(); 072 } 073 074 public static class Builder { 075 076 private final List<MetricSnapshot> snapshots = new ArrayList<>(); 077 078 private Builder() { 079 } 080 081 public boolean containsMetricName(String name) { 082 for (MetricSnapshot snapshot : snapshots) { 083 if (snapshot.getMetadata().getPrometheusName().equals(prometheusName(name))) { 084 return true; 085 } 086 } 087 return false; 088 } 089 090 /** 091 * Add a metric snapshot. Call multiple times to add multiple metric snapshots. 092 */ 093 public Builder metricSnapshot(MetricSnapshot snapshot) { 094 snapshots.add(snapshot); 095 return this; 096 } 097 098 public MetricSnapshots build() { 099 return new MetricSnapshots(snapshots); 100 } 101 } 102}