001package io.prometheus.metrics.model.registry;
002
003import io.prometheus.metrics.model.snapshots.MetricSnapshot;
004import io.prometheus.metrics.model.snapshots.MetricSnapshots;
005
006import java.util.List;
007import java.util.function.Predicate;
008import java.util.stream.Collectors;
009
010/**
011 * Like {@link Collector}, but collecting multiple Snapshots at once.
012 */
013@FunctionalInterface
014public interface MultiCollector {
015
016    /**
017     * Called when the Prometheus server scrapes metrics.
018     */
019    MetricSnapshots collect();
020
021    /**
022     * Like {@link #collect()}, but returns only the snapshots where {@code includedNames.test(name)} is {@code true}.
023     * <p>
024     * Override this if there is a more efficient way than first collecting all snapshot and then discarding the excluded ones.
025     */
026    default MetricSnapshots collect(Predicate<String> includedNames) {
027        MetricSnapshots allSnapshots = collect();
028        MetricSnapshots.Builder result = MetricSnapshots.builder();
029        for (MetricSnapshot snapshot : allSnapshots) {
030            if (includedNames.test(snapshot.getMetadata().getPrometheusName())) {
031                result.metricSnapshot(snapshot);
032            }
033        }
034        return result.build();
035    }
036
037    /**
038     * Override this and return an empty list if the MultiCollector does not return a constant list of names
039     * (names may be added / removed between scrapes).
040     */
041    default List<String> getPrometheusNames() {
042        return collect().stream().map(snapshot -> snapshot.getMetadata().getPrometheusName()).collect(Collectors.toList());
043    }
044}