001package io.prometheus.metrics.config;
002
003import java.util.Map;
004
005/**
006 * Properties starting with io.prometheus.exemplars
007 */
008public class ExemplarsProperties {
009
010    private static final String MIN_RETENTION_PERIOD_SECONDS = "minRetentionPeriodSeconds";
011    private static final String MAX_RETENTION_PERIOD_SECONDS = "maxRetentionPeriodSeconds";
012    private static final String SAMPLE_INTERVAL_MILLISECONDS = "sampleIntervalMilliseconds";
013
014    private final Integer minRetentionPeriodSeconds;
015    private final Integer maxRetentionPeriodSeconds;
016    private final Integer sampleIntervalMilliseconds;
017
018    private ExemplarsProperties(
019            Integer minRetentionPeriodSeconds,
020            Integer maxRetentionPeriodSeconds,
021            Integer sampleIntervalMilliseconds) {
022        this.minRetentionPeriodSeconds = minRetentionPeriodSeconds;
023        this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds;
024        this.sampleIntervalMilliseconds = sampleIntervalMilliseconds;
025    }
026
027    /**
028     * Minimum time how long Exemplars are kept before they may be replaced by new Exemplars.
029     * <p>
030     * Default see {@code ExemplarSamplerConfig.DEFAULT_MIN_RETENTION_PERIOD_SECONDS}
031     */
032    public Integer getMinRetentionPeriodSeconds() {
033        return minRetentionPeriodSeconds;
034    }
035
036    /**
037     * Maximum time how long Exemplars are kept before they are evicted.
038     * <p>
039     * Default see {@code ExemplarSamplerConfig.DEFAULT_MAX_RETENTION_PERIOD_SECONDS}
040     */
041    public Integer getMaxRetentionPeriodSeconds() {
042        return maxRetentionPeriodSeconds;
043    }
044
045    /**
046     * Time between attempts to sample new Exemplars. This is a performance improvement for high-frequency
047     * applications, because with the sample interval we make sure that the exemplar sampler is not called
048     * for every single request.
049     * <p>
050     * Default see {@code ExemplarSamplerConfig.DEFAULT_SAMPLE_INTERVAL_MILLISECONDS}
051     */
052    public Integer getSampleIntervalMilliseconds() {
053        return sampleIntervalMilliseconds;
054    }
055
056    /**
057     * Note that this will remove entries from {@code properties}.
058     * This is because we want to know if there are unused properties remaining after all properties have been loaded.
059     */
060    static ExemplarsProperties load(String prefix, Map<Object, Object> properties) throws PrometheusPropertiesException {
061        Integer minRetentionPeriodSeconds = Util.loadInteger(prefix + "." + MIN_RETENTION_PERIOD_SECONDS, properties);
062        Integer maxRetentionPeriodSeconds = Util.loadInteger(prefix + "." + MAX_RETENTION_PERIOD_SECONDS, properties);
063        Integer sampleIntervalMilliseconds = Util.loadInteger(prefix + "." + SAMPLE_INTERVAL_MILLISECONDS, properties);
064
065        Util.assertValue(minRetentionPeriodSeconds, t -> t > 0, "Expecting value > 0.", prefix, MIN_RETENTION_PERIOD_SECONDS);
066        Util.assertValue(minRetentionPeriodSeconds, t -> t > 0, "Expecting value > 0.", prefix, MAX_RETENTION_PERIOD_SECONDS);
067        Util.assertValue(sampleIntervalMilliseconds, t -> t > 0, "Expecting value > 0.", prefix, SAMPLE_INTERVAL_MILLISECONDS);
068
069        if (minRetentionPeriodSeconds != null && maxRetentionPeriodSeconds != null) {
070            if (minRetentionPeriodSeconds > maxRetentionPeriodSeconds) {
071                throw new PrometheusPropertiesException(prefix + "." + MIN_RETENTION_PERIOD_SECONDS + " must not be greater than " + prefix + "." + MAX_RETENTION_PERIOD_SECONDS + ".");
072            }
073        }
074
075        return new ExemplarsProperties(
076                minRetentionPeriodSeconds,
077                maxRetentionPeriodSeconds,
078                sampleIntervalMilliseconds
079        );
080    }
081
082    public static Builder builder() {
083        return new Builder();
084    }
085
086    public static class Builder {
087
088        private Integer minRetentionPeriodSeconds;
089        private Integer maxRetentionPeriodSeconds;
090        private Integer sampleIntervalMilliseconds;
091
092        private Builder() {
093        }
094
095        public Builder minRetentionPeriodSeconds(int minRetentionPeriodSeconds) {
096            this.minRetentionPeriodSeconds = minRetentionPeriodSeconds;
097            return this;
098        }
099
100        public Builder maxRetentionPeriodSeconds(int maxRetentionPeriodSeconds) {
101            this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds;
102            return this;
103        }
104
105        public Builder sampleIntervalMilliseconds(int sampleIntervalMilliseconds) {
106            this.sampleIntervalMilliseconds = sampleIntervalMilliseconds;
107            return this;
108        }
109
110        public ExemplarsProperties build() {
111            return new ExemplarsProperties(minRetentionPeriodSeconds, maxRetentionPeriodSeconds, sampleIntervalMilliseconds);
112        }
113    }
114}