001package io.prometheus.metrics.config;
002
003import java.util.ArrayList;
004import java.util.Arrays;
005import java.util.Collections;
006import java.util.List;
007import java.util.Map;
008
009/**
010 * Properties starting with io.prometheus.exporter.filter
011 */
012public class ExporterFilterProperties {
013
014    public static final String METRIC_NAME_MUST_BE_EQUAL_TO = "metricNameMustBeEqualTo";
015    public static final String METRIC_NAME_MUST_NOT_BE_EQUAL_TO = "metricNameMustNotBeEqualTo";
016    public static final String METRIC_NAME_MUST_START_WITH = "metricNameMustStartWith";
017    public static final String METRIC_NAME_MUST_NOT_START_WITH = "metricNameMustNotStartWith";
018
019    private final List<String> allowedNames;
020    private final List<String> excludedNames;
021    private final List<String> allowedPrefixes;
022    private final List<String> excludedPrefixes;
023
024    private ExporterFilterProperties(List<String> allowedNames, List<String> excludedNames, List<String> allowedPrefixes, List<String> excludedPrefixes) {
025        this(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, "");
026    }
027
028    private ExporterFilterProperties(List<String> allowedNames, List<String> excludedNames, List<String> allowedPrefixes, List<String> excludedPrefixes, String prefix) {
029        this.allowedNames = allowedNames == null ? null : Collections.unmodifiableList(new ArrayList<>(allowedNames));
030        this.excludedNames = excludedNames == null ? null : Collections.unmodifiableList(new ArrayList<>(excludedNames));
031        this.allowedPrefixes = allowedPrefixes == null ? null : Collections.unmodifiableList(new ArrayList<>(allowedPrefixes));
032        this.excludedPrefixes = excludedPrefixes == null ? null : Collections.unmodifiableList(new ArrayList<>(excludedPrefixes));
033        validate(prefix);
034    }
035
036    public List<String> getAllowedMetricNames() {
037        return allowedNames;
038    }
039
040    public List<String> getExcludedMetricNames() {
041        return excludedNames;
042    }
043
044    public List<String> getAllowedMetricNamePrefixes() {
045        return allowedPrefixes;
046    }
047
048    public List<String> getExcludedMetricNamePrefixes() {
049        return excludedPrefixes;
050    }
051
052    private void validate(String prefix) throws PrometheusPropertiesException {
053    }
054
055    /**
056     * Note that this will remove entries from {@code properties}.
057     * This is because we want to know if there are unused properties remaining after all properties have been loaded.
058     */
059    static ExporterFilterProperties load(String prefix, Map<Object, Object> properties) throws PrometheusPropertiesException {
060        List<String> allowedNames = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_BE_EQUAL_TO, properties);
061        List<String> excludedNames = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_BE_EQUAL_TO, properties);
062        List<String> allowedPrefixes = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_START_WITH, properties);
063        List<String> excludedPrefixes = Util.loadStringList(prefix + "." + METRIC_NAME_MUST_NOT_START_WITH, properties);
064        return new ExporterFilterProperties(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes, prefix);
065    }
066
067    public static Builder builder() {
068        return new Builder();
069    }
070
071    public static class Builder {
072
073        private List<String> allowedNames;
074        private List<String> excludedNames;
075        private List<String> allowedPrefixes;
076        private List<String> excludedPrefixes;
077
078        private Builder() {
079        }
080
081        /**
082         * Only allowed metric names will be exposed.
083         */
084        public Builder allowedNames(String... allowedNames) {
085            this.allowedNames = Arrays.asList(allowedNames);
086            return this;
087        }
088
089        /**
090         * Excluded metric names will not be exposed.
091         */
092        public Builder excludedNames(String... excludedNames) {
093            this.excludedNames = Arrays.asList(excludedNames);
094            return this;
095        }
096
097        /**
098         * Only metrics with a name starting with an allowed prefix will be exposed.
099         */
100        public Builder allowedPrefixes(String... allowedPrefixes) {
101            this.allowedPrefixes = Arrays.asList(allowedPrefixes);
102            return this;
103        }
104
105        /**
106         * Metrics with a name starting with an excluded prefix will not be exposed.
107         */
108        public Builder excludedPrefixes(String... excludedPrefixes) {
109            this.excludedPrefixes = Arrays.asList(excludedPrefixes);
110            return this;
111        }
112
113        public ExporterFilterProperties build() {
114            return new ExporterFilterProperties(allowedNames, excludedNames, allowedPrefixes, excludedPrefixes);
115        }
116    }
117}