001package io.prometheus.metrics.model.registry;
002
003import io.prometheus.metrics.model.snapshots.MetricSnapshot;
004
005import java.util.function.Predicate;
006
007import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName;
008
009/**
010 * To be registered with the Prometheus collector registry.
011 * See <i>Overall Structure</i> on
012 * <a href="https://prometheus.io/docs/instrumenting/writing_clientlibs/">https://prometheus.io/docs/instrumenting/writing_clientlibs/</a>.
013 */
014@FunctionalInterface
015public interface Collector {
016
017    /**
018     * Called when the Prometheus server scrapes metrics.
019     */
020    MetricSnapshot collect();
021
022    /**
023     * Provides Collector with the details of the request issued by Prometheus to allow multi-target pattern implementation
024     * Override to implement request dependent logic to provide MetricSnapshot
025     */
026        default MetricSnapshot collect(PrometheusScrapeRequest scrapeRequest) {
027                return collect();
028        }
029    
030    /**
031     * Like {@link #collect()}, but returns {@code null} if {@code includedNames.test(name)} is {@code false}.
032     * <p>
033     * Override this if there is a more efficient way than first collecting the snapshot and then discarding it.
034     */
035    default MetricSnapshot collect(Predicate<String> includedNames) {
036        MetricSnapshot result = collect();
037        if (includedNames.test(result.getMetadata().getPrometheusName())) {
038            return result;
039        } else {
040            return null;
041        }
042    }
043    
044    /**
045     * Like {@link #collect(Predicate)}, but with support for multi-target pattern.
046     * <p>
047     * Override this if there is a more efficient way than first collecting the snapshot and then discarding it.
048     */
049    default MetricSnapshot collect(Predicate<String> includedNames, PrometheusScrapeRequest scrapeRequest) {
050        MetricSnapshot result = collect(scrapeRequest);
051        if (includedNames.test(result.getMetadata().getPrometheusName())) {
052            return result;
053        } else {
054            return null;
055        }
056    }
057    
058
059    /**
060     * This is called in two places:
061     * <ol>
062     * <li>During registration to check if a metric with that name already exists.</li>
063     * <li>During scrape to check if this collector can be skipped because a name filter is present and the metric name is excluded.</li>
064     * </ol>
065     * Returning {@code null} means checks are omitted (registration the metric always succeeds),
066     * and the collector is always scraped (the result is dropped after scraping if a name filter is present and
067     * the metric name is excluded).
068     * <p>
069     * If your metric has a name that does not change at runtime it is a good idea to overwrite this and return the name.
070     * <p>
071     * All metrics in {@code prometheus-metrics-core} override this.
072     */
073    default String getPrometheusName() {
074        return null;
075    }
076}