001package io.prometheus.metrics.config;
002
003import java.time.Duration;
004import java.util.Map;
005import javax.annotation.Nullable;
006
007public class ExporterPushgatewayProperties {
008
009  private static final String ADDRESS = "address";
010  private static final String JOB = "job";
011  private static final String SCHEME = "scheme";
012  private static final String ESCAPING_SCHEME = "escapingScheme";
013  private static final String READ_TIMEOUT = "readTimeoutSeconds";
014  private static final String CONNECT_TIMEOUT = "connectTimeoutSeconds";
015  private static final String PREFIX = "io.prometheus.exporter.pushgateway";
016  @Nullable private final String scheme;
017  @Nullable private final String address;
018  @Nullable private final String job;
019  @Nullable private final EscapingScheme escapingScheme;
020  @Nullable private final Duration connectTimeout;
021  @Nullable private final Duration readTimeout;
022
023  private ExporterPushgatewayProperties(
024      @Nullable String address,
025      @Nullable String job,
026      @Nullable String scheme,
027      @Nullable EscapingScheme escapingScheme,
028      @Nullable Duration connectTimeout,
029      @Nullable Duration readTimeout) {
030    this.address = address;
031    this.job = job;
032    this.scheme = scheme;
033    this.escapingScheme = escapingScheme;
034    this.connectTimeout = connectTimeout;
035    this.readTimeout = readTimeout;
036  }
037
038  /** Address of the Pushgateway in the form {@code host:port}. Default is {@code localhost:9091} */
039  @Nullable
040  public String getAddress() {
041    return address;
042  }
043
044  /**
045   * {@code job} label for metrics being pushed. Default is the name of the JAR file that is
046   * running.
047   */
048  @Nullable
049  public String getJob() {
050    return job;
051  }
052
053  /**
054   * Scheme to be used when pushing metrics to the pushgateway. Must be "http" or "https". Default
055   * is "http".
056   */
057  @Nullable
058  public String getScheme() {
059    return scheme;
060  }
061
062  /** Escaping scheme to be used when pushing metric data to the pushgateway. */
063  @Nullable
064  public EscapingScheme getEscapingScheme() {
065    return escapingScheme;
066  }
067
068  /** Connection timeout for connections to the Pushgateway. */
069  @Nullable
070  public Duration getConnectTimeout() {
071    return connectTimeout;
072  }
073
074  /** Read timeout for connections to the Pushgateway. */
075  @Nullable
076  public Duration getReadTimeout() {
077    return readTimeout;
078  }
079
080  /**
081   * Note that this will remove entries from {@code properties}. This is because we want to know if
082   * there are unused properties remaining after all properties have been loaded.
083   */
084  static ExporterPushgatewayProperties load(Map<Object, Object> properties)
085      throws PrometheusPropertiesException {
086    String address = Util.loadString(PREFIX + "." + ADDRESS, properties);
087    String job = Util.loadString(PREFIX + "." + JOB, properties);
088    String scheme = Util.loadString(PREFIX + "." + SCHEME, properties);
089    String escapingScheme = Util.loadString(PREFIX + "." + ESCAPING_SCHEME, properties);
090    Duration connectTimeout = Util.loadOptionalDuration(PREFIX + "." + CONNECT_TIMEOUT, properties);
091    Duration readTimeout = Util.loadOptionalDuration(PREFIX + "." + READ_TIMEOUT, properties);
092
093    if (scheme != null) {
094      if (!scheme.equals("http") && !scheme.equals("https")) {
095        throw new PrometheusPropertiesException(
096            String.format(
097                "%s.%s: Illegal value. Expecting 'http' or 'https'. Found: %s",
098                PREFIX, SCHEME, scheme));
099      }
100    }
101
102    return new ExporterPushgatewayProperties(
103        address, job, scheme, parseEscapingScheme(escapingScheme), connectTimeout, readTimeout);
104  }
105
106  private static @Nullable EscapingScheme parseEscapingScheme(@Nullable String scheme) {
107    if (scheme == null) {
108      return null;
109    }
110    switch (scheme) {
111      case "allow-utf-8":
112        return EscapingScheme.ALLOW_UTF8;
113      case "values":
114        return EscapingScheme.VALUE_ENCODING_ESCAPING;
115      case "underscores":
116        return EscapingScheme.UNDERSCORE_ESCAPING;
117      case "dots":
118        return EscapingScheme.DOTS_ESCAPING;
119      default:
120        throw new PrometheusPropertiesException(
121            String.format(
122                "%s.%s: Illegal value. Expecting 'allow-utf-8', 'values', 'underscores', "
123                    + "or 'dots'. Found: %s",
124                PREFIX, ESCAPING_SCHEME, scheme));
125    }
126  }
127
128  public static Builder builder() {
129    return new Builder();
130  }
131
132  public static class Builder {
133    @Nullable private String address;
134    @Nullable private String job;
135    @Nullable private String scheme;
136    @Nullable private EscapingScheme escapingScheme;
137    @Nullable private Duration connectTimeout;
138    @Nullable private Duration readTimeout;
139
140    private Builder() {}
141
142    public Builder address(String address) {
143      this.address = address;
144      return this;
145    }
146
147    public Builder job(String job) {
148      this.job = job;
149      return this;
150    }
151
152    public Builder scheme(String scheme) {
153      this.scheme = scheme;
154      return this;
155    }
156
157    public Builder escapingScheme(EscapingScheme escapingScheme) {
158      this.escapingScheme = escapingScheme;
159      return this;
160    }
161
162    public Builder connectTimeout(Duration connectTimeout) {
163      this.connectTimeout = connectTimeout;
164      return this;
165    }
166
167    public Builder readTimeout(Duration readTimeout) {
168      this.readTimeout = readTimeout;
169      return this;
170    }
171
172    public ExporterPushgatewayProperties build() {
173      return new ExporterPushgatewayProperties(
174          address, job, scheme, escapingScheme, connectTimeout, readTimeout);
175    }
176  }
177}