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