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.Collections; 007import java.util.List; 008import java.util.function.Predicate; 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 * Provides Collector with the details of the request issued by Prometheus to allow multi-target pattern implementation 023 * Override to implement request dependent logic to provide MetricSnapshot 024 */ 025 default MetricSnapshots collect(PrometheusScrapeRequest scrapeRequest) { 026 return collect(); 027 } 028 029 030 /** 031 * Like {@link #collect()}, but returns only the snapshots where {@code includedNames.test(name)} is {@code true}. 032 * <p> 033 * Override this if there is a more efficient way than first collecting all snapshot and then discarding the excluded ones. 034 */ 035 default MetricSnapshots collect(Predicate<String> includedNames) { 036 return collect(includedNames, null); 037 } 038 039 /** 040 * Like {@link #collect(Predicate)}, but with support for multi-target pattern. 041 * <p> 042 * Override this if there is a more efficient way than first collecting the snapshot and then discarding it. 043 */ 044 default MetricSnapshots collect(Predicate<String> includedNames, PrometheusScrapeRequest scrapeRequest) { 045 MetricSnapshots allSnapshots = scrapeRequest == null ? collect(): collect(scrapeRequest); 046 MetricSnapshots.Builder result = MetricSnapshots.builder(); 047 for (MetricSnapshot snapshot : allSnapshots) { 048 if (includedNames.test(snapshot.getMetadata().getPrometheusName())) { 049 result.metricSnapshot(snapshot); 050 } 051 } 052 return result.build(); 053 } 054 055 056 /** 057 * This is called in two places: 058 * <ol> 059 * <li>During registration to check if a metric with that name already exists.</li> 060 * <li>During scrape to check if the collector can be skipped because a name filter is present and all names are excluded.</li> 061 * </ol> 062 * Returning an empty list means checks are omitted (registration metric always succeeds), 063 * and the collector is always scraped (if a name filter is present and all names are excluded the result is dropped). 064 * <p> 065 * If your collector returns a constant list of metrics that have names that do not change at runtime 066 * it is a good idea to overwrite this and return the names. 067 */ 068 default List<String> getPrometheusNames() { 069 return Collections.emptyList(); 070 } 071}