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