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