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}