diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3bbe74bc2..1e1eb867c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -10,3 +10,9 @@ Prometheus uses GitHub to manage reviews of pull requests.
on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers).
This will avoid unnecessary work and surely give you and us a good deal
of inspiration.
+
+## Formatting
+
+This repository uses [Google Java Format](https://github.com/google/google-java-format) to format the code.
+
+Run `./mvnw spotless:apply` to format the code (only changed files) before committing.
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/Collector.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/Collector.java
index 0c69a89a9..57b2b640f 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/Collector.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/Collector.java
@@ -1,76 +1,77 @@
package io.prometheus.metrics.model.registry;
import io.prometheus.metrics.model.snapshots.MetricSnapshot;
-
import java.util.function.Predicate;
-import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName;
-
/**
- * To be registered with the Prometheus collector registry.
- * See Overall Structure on
- * https://prometheus.io/docs/instrumenting/writing_clientlibs/ .
+ * To be registered with the Prometheus collector registry. See Overall Structure on https://prometheus.io/docs/instrumenting/writing_clientlibs/ .
*/
@FunctionalInterface
public interface Collector {
- /**
- * Called when the Prometheus server scrapes metrics.
- */
- MetricSnapshot collect();
+ /** Called when the Prometheus server scrapes metrics. */
+ MetricSnapshot collect();
- /**
- * Provides Collector with the details of the request issued by Prometheus to allow multi-target pattern implementation
- * Override to implement request dependent logic to provide MetricSnapshot
- */
- default MetricSnapshot collect(PrometheusScrapeRequest scrapeRequest) {
- return collect();
- }
-
- /**
- * Like {@link #collect()}, but returns {@code null} if {@code includedNames.test(name)} is {@code false}.
- *
- * Override this if there is a more efficient way than first collecting the snapshot and then discarding it.
- */
- default MetricSnapshot collect(Predicate includedNames) {
- MetricSnapshot result = collect();
- if (includedNames.test(result.getMetadata().getPrometheusName())) {
- return result;
- } else {
- return null;
- }
- }
-
- /**
- * Like {@link #collect(Predicate)}, but with support for multi-target pattern.
- *
- * Override this if there is a more efficient way than first collecting the snapshot and then discarding it.
- */
- default MetricSnapshot collect(Predicate includedNames, PrometheusScrapeRequest scrapeRequest) {
- MetricSnapshot result = collect(scrapeRequest);
- if (includedNames.test(result.getMetadata().getPrometheusName())) {
- return result;
- } else {
- return null;
- }
+ /**
+ * Provides Collector with the details of the request issued by Prometheus to allow multi-target
+ * pattern implementation Override to implement request dependent logic to provide MetricSnapshot
+ */
+ default MetricSnapshot collect(PrometheusScrapeRequest scrapeRequest) {
+ return collect();
+ }
+
+ /**
+ * Like {@link #collect()}, but returns {@code null} if {@code includedNames.test(name)} is {@code
+ * false}.
+ *
+ * Override this if there is a more efficient way than first collecting the snapshot and then
+ * discarding it.
+ */
+ default MetricSnapshot collect(Predicate includedNames) {
+ MetricSnapshot result = collect();
+ if (includedNames.test(result.getMetadata().getPrometheusName())) {
+ return result;
+ } else {
+ return null;
}
-
+ }
- /**
- * This is called in two places:
- *
- * During registration to check if a metric with that name already exists.
- * During scrape to check if this collector can be skipped because a name filter is present and the metric name is excluded.
- *
- * Returning {@code null} means checks are omitted (registration the metric always succeeds),
- * and the collector is always scraped (the result is dropped after scraping if a name filter is present and
- * the metric name is excluded).
- *
- * If your metric has a name that does not change at runtime it is a good idea to overwrite this and return the name.
- *
- * All metrics in {@code prometheus-metrics-core} override this.
- */
- default String getPrometheusName() {
- return null;
+ /**
+ * Like {@link #collect(Predicate)}, but with support for multi-target pattern.
+ *
+ *
Override this if there is a more efficient way than first collecting the snapshot and then
+ * discarding it.
+ */
+ default MetricSnapshot collect(
+ Predicate includedNames, PrometheusScrapeRequest scrapeRequest) {
+ MetricSnapshot result = collect(scrapeRequest);
+ if (includedNames.test(result.getMetadata().getPrometheusName())) {
+ return result;
+ } else {
+ return null;
}
+ }
+
+ /**
+ * This is called in two places:
+ *
+ *
+ * During registration to check if a metric with that name already exists.
+ * During scrape to check if this collector can be skipped because a name filter is present
+ * and the metric name is excluded.
+ *
+ *
+ * Returning {@code null} means checks are omitted (registration the metric always succeeds), and
+ * the collector is always scraped (the result is dropped after scraping if a name filter is
+ * present and the metric name is excluded).
+ *
+ * If your metric has a name that does not change at runtime it is a good idea to overwrite
+ * this and return the name.
+ *
+ *
All metrics in {@code prometheus-metrics-core} override this.
+ */
+ default String getPrometheusName() {
+ return null;
+ }
}
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusRegistry.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusRegistry.java
index 8b059adb3..00a19d9f6 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusRegistry.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/registry/PrometheusRegistry.java
@@ -2,128 +2,143 @@
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName;
+import io.prometheus.metrics.model.snapshots.MetricSnapshot;
+import io.prometheus.metrics.model.snapshots.MetricSnapshots;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Predicate;
-import io.prometheus.metrics.model.snapshots.MetricSnapshot;
-import io.prometheus.metrics.model.snapshots.MetricSnapshots;
-
public class PrometheusRegistry {
- public static final PrometheusRegistry defaultRegistry = new PrometheusRegistry();
-
- private final Set prometheusNames = ConcurrentHashMap.newKeySet();
- private final List collectors = new CopyOnWriteArrayList<>();
- private final List multiCollectors = new CopyOnWriteArrayList<>();
+ public static final PrometheusRegistry defaultRegistry = new PrometheusRegistry();
- public void register(Collector collector) {
- String prometheusName = collector.getPrometheusName();
- if (prometheusName != null) {
- if (!prometheusNames.add(prometheusName)) {
- throw new IllegalStateException("Can't register " + prometheusName + " because a metric with that name is already registered.");
- }
- }
- collectors.add(collector);
- }
+ private final Set prometheusNames = ConcurrentHashMap.newKeySet();
+ private final List collectors = new CopyOnWriteArrayList<>();
+ private final List multiCollectors = new CopyOnWriteArrayList<>();
- public void register(MultiCollector collector) {
- for (String prometheusName : collector.getPrometheusNames()) {
- if (!prometheusNames.add(prometheusName)) {
- throw new IllegalStateException("Can't register " + prometheusName + " because that name is already registered.");
- }
- }
- multiCollectors.add(collector);
- }
+ public void register(Collector collector) {
+ String prometheusName = collector.getPrometheusName();
+ if (prometheusName != null) {
+ if (!prometheusNames.add(prometheusName)) {
+ throw new IllegalStateException(
+ "Can't register "
+ + prometheusName
+ + " because a metric with that name is already registered.");
+ }
+ }
+ collectors.add(collector);
+ }
- public void unregister(Collector collector) {
- collectors.remove(collector);
- String prometheusName = collector.getPrometheusName();
- if (prometheusName != null) {
- prometheusNames.remove(collector.getPrometheusName());
- }
- }
+ public void register(MultiCollector collector) {
+ for (String prometheusName : collector.getPrometheusNames()) {
+ if (!prometheusNames.add(prometheusName)) {
+ throw new IllegalStateException(
+ "Can't register " + prometheusName + " because that name is already registered.");
+ }
+ }
+ multiCollectors.add(collector);
+ }
- public void unregister(MultiCollector collector) {
- multiCollectors.remove(collector);
- for (String prometheusName : collector.getPrometheusNames()) {
- prometheusNames.remove(prometheusName(prometheusName));
- }
- }
+ public void unregister(Collector collector) {
+ collectors.remove(collector);
+ String prometheusName = collector.getPrometheusName();
+ if (prometheusName != null) {
+ prometheusNames.remove(collector.getPrometheusName());
+ }
+ }
- public MetricSnapshots scrape() {
- return scrape((PrometheusScrapeRequest) null);
- }
+ public void unregister(MultiCollector collector) {
+ multiCollectors.remove(collector);
+ for (String prometheusName : collector.getPrometheusNames()) {
+ prometheusNames.remove(prometheusName(prometheusName));
+ }
+ }
- public MetricSnapshots scrape(PrometheusScrapeRequest scrapeRequest) {
- MetricSnapshots.Builder result = MetricSnapshots.builder();
- for (Collector collector : collectors) {
- MetricSnapshot snapshot = scrapeRequest == null ? collector.collect() : collector.collect(scrapeRequest);
- if (snapshot != null) {
- if (result.containsMetricName(snapshot.getMetadata().getName())) {
- throw new IllegalStateException(snapshot.getMetadata().getPrometheusName() + ": duplicate metric name.");
- }
- result.metricSnapshot(snapshot);
- }
- }
- for (MultiCollector collector : multiCollectors) {
- MetricSnapshots snaphots = scrapeRequest == null ? collector.collect() : collector.collect(scrapeRequest);
- for (MetricSnapshot snapshot : snaphots) {
- if (result.containsMetricName(snapshot.getMetadata().getName())) {
- throw new IllegalStateException(snapshot.getMetadata().getPrometheusName() + ": duplicate metric name.");
- }
- result.metricSnapshot(snapshot);
- }
- }
- return result.build();
- }
+ public MetricSnapshots scrape() {
+ return scrape((PrometheusScrapeRequest) null);
+ }
- public MetricSnapshots scrape(Predicate includedNames) {
- if (includedNames == null) {
- return scrape();
- }
- return scrape(includedNames, null);
- }
+ public MetricSnapshots scrape(PrometheusScrapeRequest scrapeRequest) {
+ MetricSnapshots.Builder result = MetricSnapshots.builder();
+ for (Collector collector : collectors) {
+ MetricSnapshot snapshot =
+ scrapeRequest == null ? collector.collect() : collector.collect(scrapeRequest);
+ if (snapshot != null) {
+ if (result.containsMetricName(snapshot.getMetadata().getName())) {
+ throw new IllegalStateException(
+ snapshot.getMetadata().getPrometheusName() + ": duplicate metric name.");
+ }
+ result.metricSnapshot(snapshot);
+ }
+ }
+ for (MultiCollector collector : multiCollectors) {
+ MetricSnapshots snapshots =
+ scrapeRequest == null ? collector.collect() : collector.collect(scrapeRequest);
+ for (MetricSnapshot snapshot : snapshots) {
+ if (result.containsMetricName(snapshot.getMetadata().getName())) {
+ throw new IllegalStateException(
+ snapshot.getMetadata().getPrometheusName() + ": duplicate metric name.");
+ }
+ result.metricSnapshot(snapshot);
+ }
+ }
+ return result.build();
+ }
- public MetricSnapshots scrape(Predicate includedNames, PrometheusScrapeRequest scrapeRequest) {
- if (includedNames == null) {
- return scrape(scrapeRequest);
- }
- MetricSnapshots.Builder result = MetricSnapshots.builder();
- for (Collector collector : collectors) {
- String prometheusName = collector.getPrometheusName();
- // prometheusName == null means the name is unknown, and we have to scrape to learn the name.
- // prometheusName != null means we can skip the scrape if the name is excluded.
- if (prometheusName == null || includedNames.test(prometheusName)) {
- MetricSnapshot snapshot = scrapeRequest == null ? collector.collect(includedNames) : collector.collect(includedNames, scrapeRequest);
- if (snapshot != null) {
- result.metricSnapshot(snapshot);
- }
- }
- }
- for (MultiCollector collector : multiCollectors) {
- List prometheusNames = collector.getPrometheusNames();
- // empty prometheusNames means the names are unknown, and we have to scrape to learn the names.
- // non-empty prometheusNames means we can exclude the collector if all names are excluded by the filter.
- boolean excluded = !prometheusNames.isEmpty();
- for (String prometheusName : prometheusNames) {
- if (includedNames.test(prometheusName)) {
- excluded = false;
- break;
- }
- }
- if (!excluded) {
- MetricSnapshots snapshots = scrapeRequest == null ? collector.collect(includedNames) : collector.collect(includedNames, scrapeRequest);
- for (MetricSnapshot snapshot : snapshots) {
- if (snapshot != null) {
- result.metricSnapshot(snapshot);
- }
- }
- }
- }
- return result.build();
- }
+ public MetricSnapshots scrape(Predicate includedNames) {
+ if (includedNames == null) {
+ return scrape();
+ }
+ return scrape(includedNames, null);
+ }
+ public MetricSnapshots scrape(
+ Predicate includedNames, PrometheusScrapeRequest scrapeRequest) {
+ if (includedNames == null) {
+ return scrape(scrapeRequest);
+ }
+ MetricSnapshots.Builder result = MetricSnapshots.builder();
+ for (Collector collector : collectors) {
+ String prometheusName = collector.getPrometheusName();
+ // prometheusName == null means the name is unknown, and we have to scrape to learn the name.
+ // prometheusName != null means we can skip the scrape if the name is excluded.
+ if (prometheusName == null || includedNames.test(prometheusName)) {
+ MetricSnapshot snapshot =
+ scrapeRequest == null
+ ? collector.collect(includedNames)
+ : collector.collect(includedNames, scrapeRequest);
+ if (snapshot != null) {
+ result.metricSnapshot(snapshot);
+ }
+ }
+ }
+ for (MultiCollector collector : multiCollectors) {
+ List prometheusNames = collector.getPrometheusNames();
+ // empty prometheusNames means the names are unknown, and we have to scrape to learn the
+ // names.
+ // non-empty prometheusNames means we can exclude the collector if all names are excluded by
+ // the filter.
+ boolean excluded = !prometheusNames.isEmpty();
+ for (String prometheusName : prometheusNames) {
+ if (includedNames.test(prometheusName)) {
+ excluded = false;
+ break;
+ }
+ }
+ if (!excluded) {
+ MetricSnapshots snapshots =
+ scrapeRequest == null
+ ? collector.collect(includedNames)
+ : collector.collect(includedNames, scrapeRequest);
+ for (MetricSnapshot snapshot : snapshots) {
+ if (snapshot != null) {
+ result.metricSnapshot(snapshot);
+ }
+ }
+ }
+ }
+ return result.build();
+ }
}
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplars.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplars.java
index b5286b0c2..ca9109b96 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplars.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Exemplars.java
@@ -9,141 +9,131 @@
/**
* Immutable container for Exemplars.
- *
- * This is currently backed by a {@code List}. May be refactored later to use a more efficient data structure.
+ *
+ * This is currently backed by a {@code List}. May be refactored later to use a more
+ * efficient data structure.
*/
public class Exemplars implements Iterable {
- /**
- * EMPTY means no Exemplars.
- */
- public static final Exemplars EMPTY = new Exemplars(Collections.emptyList());
- private final List exemplars;
-
- private Exemplars(Collection exemplars) {
- ArrayList copy = new ArrayList<>(exemplars.size());
- for (Exemplar exemplar : exemplars) {
- if (exemplar == null) {
- throw new NullPointerException("Illegal null value in Exemplars");
- }
- copy.add(exemplar);
- }
- this.exemplars = Collections.unmodifiableList(copy);
- }
+ /** EMPTY means no Exemplars. */
+ public static final Exemplars EMPTY = new Exemplars(Collections.emptyList());
- /**
- * Create a new Exemplars instance.
- * You can either create Exemplars with one of the static {@code Exemplars.of(...)} methods,
- * or you can use the {@link Exemplars#builder()}.
- *
- * @param exemplars a copy of the exemplars collection will be created.
- */
- public static Exemplars of(Collection exemplars) {
- return new Exemplars(exemplars);
- }
-
- /**
- * Create a new Exemplars instance.
- * You can either create Exemplars with one of the static {@code Exemplars.of(...)} methods,
- * or you can use the {@link Exemplars#builder()}.
- *
- * @param exemplars a copy of the exemplars array will be created.
- */
- public static Exemplars of(Exemplar... exemplars) {
- return new Exemplars(Arrays.asList(exemplars));
- }
-
- @Override
- public Iterator iterator() {
- return exemplars.iterator();
- }
-
- public int size() {
- return exemplars.size();
- }
+ private final List exemplars;
- public Exemplar get(int index) {
- return exemplars.get(index);
+ private Exemplars(Collection exemplars) {
+ List copy = new ArrayList<>(exemplars.size());
+ for (Exemplar exemplar : exemplars) {
+ if (exemplar == null) {
+ throw new NullPointerException("Illegal null value in Exemplars");
+ }
+ copy.add(exemplar);
}
-
- /**
- * This is used by classic histograms to find an exemplar with a value between lowerBound and upperBound.
- * If there is more than one exemplar within the bounds the one with the newest time stamp is returned.
- */
- public Exemplar get(double lowerBound, double upperBound) {
- Exemplar result = null;
- for (int i = 0; i < exemplars.size(); i++) {
- Exemplar exemplar = exemplars.get(i);
- double value = exemplar.getValue();
- if (value > lowerBound && value <= upperBound) {
- if (result == null) {
- result = exemplar;
- } else if (result.hasTimestamp() && exemplar.hasTimestamp()) {
- if (exemplar.getTimestampMillis() > result.getTimestampMillis()) {
- result = exemplar;
- }
- }
- }
+ this.exemplars = Collections.unmodifiableList(copy);
+ }
+
+ /**
+ * Create a new Exemplars instance. You can either create Exemplars with one of the static {@code
+ * Exemplars.of(...)} methods, or you can use the {@link Exemplars#builder()}.
+ *
+ * @param exemplars a copy of the exemplars collection will be created.
+ */
+ public static Exemplars of(Collection exemplars) {
+ return new Exemplars(exemplars);
+ }
+
+ /**
+ * Create a new Exemplars instance. You can either create Exemplars with one of the static {@code
+ * Exemplars.of(...)} methods, or you can use the {@link Exemplars#builder()}.
+ *
+ * @param exemplars a copy of the exemplars array will be created.
+ */
+ public static Exemplars of(Exemplar... exemplars) {
+ return new Exemplars(Arrays.asList(exemplars));
+ }
+
+ @Override
+ public Iterator iterator() {
+ return exemplars.iterator();
+ }
+
+ public int size() {
+ return exemplars.size();
+ }
+
+ public Exemplar get(int index) {
+ return exemplars.get(index);
+ }
+
+ /**
+ * This is used by classic histograms to find an exemplar with a value between lowerBound and
+ * upperBound. If there is more than one exemplar within the bounds the one with the newest time
+ * stamp is returned.
+ */
+ public Exemplar get(double lowerBound, double upperBound) {
+ Exemplar result = null;
+ for (Exemplar exemplar : exemplars) {
+ double value = exemplar.getValue();
+ if (value > lowerBound && value <= upperBound) {
+ if (result == null) {
+ result = exemplar;
+ } else if (result.hasTimestamp() && exemplar.hasTimestamp()) {
+ if (exemplar.getTimestampMillis() > result.getTimestampMillis()) {
+ result = exemplar;
+ }
}
- return result;
+ }
}
-
- /**
- * Find the Exemplar with the newest timestamp. May return {@code null}.
- */
- public Exemplar getLatest() {
- Exemplar latest = null;
- for (int i=0; i exemplars = new ArrayList<>();
+ private final ArrayList exemplars = new ArrayList<>();
- private Builder() {
- }
+ private Builder() {}
- /**
- * Add an exemplar. This can be called multiple times to add multiple exemplars.
- */
- public Builder exemplar(Exemplar exemplar) {
- exemplars.add(exemplar);
- return this;
- }
+ /** Add an exemplar. This can be called multiple times to add multiple exemplars. */
+ public Builder exemplar(Exemplar exemplar) {
+ exemplars.add(exemplar);
+ return this;
+ }
- /**
- * Add all exemplars form the collection.
- */
- public Builder exemplars(Collection exemplars) {
- this.exemplars.addAll(exemplars);
- return this;
- }
+ /** Add all exemplars form the collection. */
+ public Builder exemplars(Collection exemplars) {
+ this.exemplars.addAll(exemplars);
+ return this;
+ }
- public Exemplars build() {
- return Exemplars.of(exemplars);
- }
+ public Exemplars build() {
+ return Exemplars.of(exemplars);
}
+ }
}
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Labels.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Labels.java
index 67a0dcf1f..170ec4fc2 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Labels.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Labels.java
@@ -1,5 +1,8 @@
package io.prometheus.metrics.model.snapshots;
+import static io.prometheus.metrics.model.snapshots.PrometheusNaming.isValidLabelName;
+import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -7,434 +10,427 @@
import java.util.List;
import java.util.stream.Stream;
-import static io.prometheus.metrics.model.snapshots.PrometheusNaming.isValidLabelName;
-import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName;
-
-/**
- * Immutable set of name/value pairs, sorted by name.
- */
+/** Immutable set of name/value pairs, sorted by name. */
public class Labels implements Comparable, Iterable {
- public static final Labels EMPTY;
-
- static {
- String[] names = new String[]{};
- String[] values = new String[]{};
- EMPTY = new Labels(names, names, values);
- }
-
- // prometheusNames is the same as names, but dots are replaced with underscores.
- // Labels is sorted by prometheusNames.
- // If names[i] does not contain a dot, prometheusNames[i] references the same String as names[i]
- // so that we don't have unnecessary duplicates of strings.
- // If none of the names contains a dot, then prometheusNames references the same array as names
- // so that we don't have unnecessary duplicate arrays.
- private final String[] prometheusNames;
- private final String[] names;
- private final String[] values;
-
- private Labels(String[] names, String[] prometheusNames, String[] values) {
- this.names = names;
- this.prometheusNames = prometheusNames;
- this.values = values;
- }
-
- public boolean isEmpty() {
- return this == EMPTY || this.equals(EMPTY);
- }
-
- /**
- * Create a new Labels instance.
- * You can either create Labels with one of the static {@code Labels.of(...)} methods,
- * or you can use the {@link Labels#builder()}.
- *
- * @param keyValuePairs as in {@code {name1, value1, name2, value2}}. Length must be even.
- * {@link PrometheusNaming#isValidLabelName(String)} must be true for each name.
- * Use {@link PrometheusNaming#sanitizeLabelName(String)} to convert arbitrary strings
- * to valid label names. Label names must be unique (no duplicate label names).
- */
- public static Labels of(String... keyValuePairs) {
- if (keyValuePairs.length % 2 != 0) {
- throw new IllegalArgumentException("Key/value pairs must have an even length");
- }
- if (keyValuePairs.length == 0) {
- return EMPTY;
- }
- String[] names = new String[keyValuePairs.length / 2];
- String[] values = new String[keyValuePairs.length / 2];
- for (int i = 0; 2 * i < keyValuePairs.length; i++) {
- names[i] = keyValuePairs[2 * i];
- values[i] = keyValuePairs[2 * i + 1];
- }
- String[] prometheusNames = makePrometheusNames(names);
- sortAndValidate(names, prometheusNames, values);
- return new Labels(names, prometheusNames, values);
- }
-
- // package private for testing
- static String[] makePrometheusNames(String[] names) {
- String[] prometheusNames = names;
- for (int i=0; i names, List values) {
- if (names.size() != values.size()) {
- throw new IllegalArgumentException("Names and values must have the same size.");
- }
- if (names.size() == 0) {
- return EMPTY;
- }
- String[] namesCopy = names.toArray(new String[0]);
- String[] valuesCopy = values.toArray(new String[0]);
- String[] prometheusNames = makePrometheusNames(namesCopy);
- sortAndValidate(namesCopy, prometheusNames, valuesCopy);
- return new Labels(namesCopy, prometheusNames, valuesCopy);
- }
-
- /**
- * Create a new Labels instance.
- * You can either create Labels with one of the static {@code Labels.of(...)} methods,
- * or you can use the {@link Labels#builder()}.
- *
- * @param names label names. {@link PrometheusNaming#isValidLabelName(String)} must be true for each name.
- * Use {@link PrometheusNaming#sanitizeLabelName(String)} to convert arbitrary strings
- * to valid label names. Label names must be unique (no duplicate label names).
- * @param values label values. {@code names.length} must be equal to {@code values.length}.
- */
- public static Labels of(String[] names, String[] values) {
- if (names.length != values.length) {
- throw new IllegalArgumentException("Names and values must have the same length.");
+ public static final Labels EMPTY;
+
+ static {
+ String[] names = new String[] {};
+ String[] values = new String[] {};
+ EMPTY = new Labels(names, names, values);
+ }
+
+ // prometheusNames is the same as names, but dots are replaced with underscores.
+ // Labels is sorted by prometheusNames.
+ // If names[i] does not contain a dot, prometheusNames[i] references the same String as names[i]
+ // so that we don't have unnecessary duplicates of strings.
+ // If none of the names contains a dot, then prometheusNames references the same array as names
+ // so that we don't have unnecessary duplicate arrays.
+ private final String[] prometheusNames;
+ private final String[] names;
+ private final String[] values;
+
+ private Labels(String[] names, String[] prometheusNames, String[] values) {
+ this.names = names;
+ this.prometheusNames = prometheusNames;
+ this.values = values;
+ }
+
+ public boolean isEmpty() {
+ return this == EMPTY || this.equals(EMPTY);
+ }
+
+ /**
+ * Create a new Labels instance. You can either create Labels with one of the static {@code
+ * Labels.of(...)} methods, or you can use the {@link Labels#builder()}.
+ *
+ * @param keyValuePairs as in {@code {name1, value1, name2, value2}}. Length must be even. {@link
+ * PrometheusNaming#isValidLabelName(String)} must be true for each name. Use {@link
+ * PrometheusNaming#sanitizeLabelName(String)} to convert arbitrary strings to valid label
+ * names. Label names must be unique (no duplicate label names).
+ */
+ public static Labels of(String... keyValuePairs) {
+ if (keyValuePairs.length % 2 != 0) {
+ throw new IllegalArgumentException("Key/value pairs must have an even length");
+ }
+ if (keyValuePairs.length == 0) {
+ return EMPTY;
+ }
+ String[] names = new String[keyValuePairs.length / 2];
+ String[] values = new String[keyValuePairs.length / 2];
+ for (int i = 0; 2 * i < keyValuePairs.length; i++) {
+ names[i] = keyValuePairs[2 * i];
+ values[i] = keyValuePairs[2 * i + 1];
+ }
+ String[] prometheusNames = makePrometheusNames(names);
+ sortAndValidate(names, prometheusNames, values);
+ return new Labels(names, prometheusNames, values);
+ }
+
+ // package private for testing
+ static String[] makePrometheusNames(String[] names) {
+ String[] prometheusNames = names;
+ for (int i = 0; i < names.length; i++) {
+ if (names[i].contains(".")) {
+ if (prometheusNames == names) {
+ prometheusNames = Arrays.copyOf(names, names.length);
}
- if (names.length == 0) {
- return EMPTY;
- }
- String[] namesCopy = Arrays.copyOf(names, names.length);
- String[] valuesCopy = Arrays.copyOf(values, values.length);
- String[] prometheusNames = makePrometheusNames(namesCopy);
- sortAndValidate(namesCopy, prometheusNames, valuesCopy);
- return new Labels(namesCopy, prometheusNames, valuesCopy);
- }
-
- /**
- * Test if these labels contain a specific label name.
- *
- * Dots are treated as underscores, so {@code contains("my.label")} and {@code contains("my_label")} are the same.
- */
- public boolean contains(String labelName) {
- return get(labelName) != null;
- }
-
- /**
- * Get the label value for a given label name.
- *
- * Returns {@code null} if the {@code labelName} is not found.
- *
- * Dots are treated as underscores, so {@code get("my.label")} and {@code get("my_label")} are the same.
- */
- public String get(String labelName) {
- labelName = prometheusName(labelName);
- for (int i=0; i 0 && prometheusNames[i - 1].equals(prometheusNames[i])) {
- throw new IllegalArgumentException(names[i] + ": duplicate label name");
- }
- }
- }
-
- private static void sort(String[] names, String[] prometheusNames, String[] values) {
- // bubblesort
- int n = prometheusNames.length;
- for (int i = 0; i < n - 1; i++) {
- for (int j = 0; j < n - i - 1; j++) {
- if (prometheusNames[j].compareTo(prometheusNames[j + 1]) > 0) {
- swap(j, j + 1, names, prometheusNames, values);
- }
- }
- }
- }
-
- private static void swap(int i, int j, String[] names, String[] prometheusNames, String[] values) {
- String tmp = names[j];
- names[j] = names[i];
- names[i] = tmp;
- tmp = values[j];
- values[j] = values[i];
- values[i] = tmp;
- if (prometheusNames != names) {
- tmp = prometheusNames[j];
- prometheusNames[j] = prometheusNames[i];
- prometheusNames[i] = tmp;
- }
- }
-
- @Override
- public Iterator iterator() {
- return asList().iterator();
- }
-
- public Stream stream() {
- return asList().stream();
- }
-
- public int size() {
- return names.length;
- }
-
- public String getName(int i) {
- return names[i];
- }
-
- /**
- * Like {@link #getName(int)}, but dots are replaced with underscores.
- *
- * This is used by Prometheus exposition formats.
- */
- public String getPrometheusName(int i) {
- return prometheusNames[i];
- }
-
- public String getValue(int i) {
+ prometheusNames[i] = PrometheusNaming.prometheusName(names[i]);
+ }
+ }
+ return prometheusNames;
+ }
+
+ /**
+ * Create a new Labels instance. You can either create Labels with one of the static {@code
+ * Labels.of(...)} methods, or you can use the {@link Labels#builder()}.
+ *
+ * @param names label names. {@link PrometheusNaming#isValidLabelName(String)} must be true for
+ * each name. Use {@link PrometheusNaming#sanitizeLabelName(String)} to convert arbitrary
+ * strings to valid label names. Label names must be unique (no duplicate label names).
+ * @param values label values. {@code names.size()} must be equal to {@code values.size()}.
+ */
+ public static Labels of(List names, List values) {
+ if (names.size() != values.size()) {
+ throw new IllegalArgumentException("Names and values must have the same size.");
+ }
+ if (names.isEmpty()) {
+ return EMPTY;
+ }
+ String[] namesCopy = names.toArray(new String[0]);
+ String[] valuesCopy = values.toArray(new String[0]);
+ String[] prometheusNames = makePrometheusNames(namesCopy);
+ sortAndValidate(namesCopy, prometheusNames, valuesCopy);
+ return new Labels(namesCopy, prometheusNames, valuesCopy);
+ }
+
+ /**
+ * Create a new Labels instance. You can either create Labels with one of the static {@code
+ * Labels.of(...)} methods, or you can use the {@link Labels#builder()}.
+ *
+ * @param names label names. {@link PrometheusNaming#isValidLabelName(String)} must be true for
+ * each name. Use {@link PrometheusNaming#sanitizeLabelName(String)} to convert arbitrary
+ * strings to valid label names. Label names must be unique (no duplicate label names).
+ * @param values label values. {@code names.length} must be equal to {@code values.length}.
+ */
+ public static Labels of(String[] names, String[] values) {
+ if (names.length != values.length) {
+ throw new IllegalArgumentException("Names and values must have the same length.");
+ }
+ if (names.length == 0) {
+ return EMPTY;
+ }
+ String[] namesCopy = Arrays.copyOf(names, names.length);
+ String[] valuesCopy = Arrays.copyOf(values, values.length);
+ String[] prometheusNames = makePrometheusNames(namesCopy);
+ sortAndValidate(namesCopy, prometheusNames, valuesCopy);
+ return new Labels(namesCopy, prometheusNames, valuesCopy);
+ }
+
+ /**
+ * Test if these labels contain a specific label name.
+ *
+ * Dots are treated as underscores, so {@code contains("my.label")} and {@code
+ * contains("my_label")} are the same.
+ */
+ public boolean contains(String labelName) {
+ return get(labelName) != null;
+ }
+
+ /**
+ * Get the label value for a given label name.
+ *
+ *
Returns {@code null} if the {@code labelName} is not found.
+ *
+ *
Dots are treated as underscores, so {@code get("my.label")} and {@code get("my_label")} are
+ * the same.
+ */
+ public String get(String labelName) {
+ labelName = prometheusName(labelName);
+ for (int i = 0; i < prometheusNames.length; i++) {
+ if (prometheusNames[i].equals(labelName)) {
return values[i];
- }
-
- /**
- * Create a new Labels instance containing the labels of this and the labels of other.
- * This and other must not contain the same label name.
- */
- public Labels merge(Labels other) {
- if (this.isEmpty()) {
- return other;
- }
- if (other.isEmpty()) {
- return this;
- }
- String[] names = new String[this.names.length + other.names.length];
- String[] prometheusNames = names;
- if (this.names != this.prometheusNames || other.names != other.prometheusNames) {
- prometheusNames = new String[names.length];
- }
- String[] values = new String[names.length];
- int thisPos = 0;
- int otherPos = 0;
- while (thisPos + otherPos < names.length) {
- if (thisPos >= this.names.length) {
- names[thisPos + otherPos] = other.names[otherPos];
- values[thisPos + otherPos] = other.values[otherPos];
- if (prometheusNames != names) {
- prometheusNames[thisPos + otherPos] = other.prometheusNames[otherPos];
- }
- otherPos++;
- } else if (otherPos >= other.names.length) {
- names[thisPos + otherPos] = this.names[thisPos];
- values[thisPos + otherPos] = this.values[thisPos];
- if (prometheusNames != names) {
- prometheusNames[thisPos + otherPos] = this.prometheusNames[thisPos];
- }
- thisPos++;
- } else if (this.prometheusNames[thisPos].compareTo(other.prometheusNames[otherPos]) < 0) {
- names[thisPos + otherPos] = this.names[thisPos];
- values[thisPos + otherPos] = this.values[thisPos];
- if (prometheusNames != names) {
- prometheusNames[thisPos + otherPos] = this.prometheusNames[thisPos];
- }
- thisPos++;
- } else if (this.prometheusNames[thisPos].compareTo(other.prometheusNames[otherPos]) > 0) {
- names[thisPos + otherPos] = other.names[otherPos];
- values[thisPos + otherPos] = other.values[otherPos];
- if (prometheusNames != names) {
- prometheusNames[thisPos + otherPos] = other.prometheusNames[otherPos];
- }
- otherPos++;
- } else {
- throw new IllegalArgumentException("Duplicate label name: '" + this.names[thisPos] + "'.");
- }
- }
- return new Labels(names, prometheusNames, values);
- }
-
- /**
- * Create a new Labels instance containing the labels of this and the label passed as name and value.
- * The label name must not already be contained in this Labels instance.
- */
- public Labels add(String name, String value) {
- return merge(Labels.of(name, value));
- }
-
- /**
- * Create a new Labels instance containing the labels of this and the labels passed as names and values.
- * The new label names must not already be contained in this Labels instance.
- */
- public Labels merge(String[] names, String[] values) {
- if (this.equals(EMPTY)) {
- return Labels.of(names, values);
- }
- String[] mergedNames = new String[this.names.length + names.length];
- String[] mergedValues = new String[this.values.length + values.length];
- System.arraycopy(this.names, 0, mergedNames, 0, this.names.length);
- System.arraycopy(this.values, 0, mergedValues, 0, this.values.length);
- System.arraycopy(names, 0, mergedNames, this.names.length, names.length);
- System.arraycopy(values, 0, mergedValues, this.values.length, values.length);
- String[] prometheusNames = makePrometheusNames(mergedNames);
- sortAndValidate(mergedNames, prometheusNames, mergedValues);
- return new Labels(mergedNames, prometheusNames, mergedValues);
- }
-
- public boolean hasSameNames(Labels other) {
- return Arrays.equals(prometheusNames, other.prometheusNames);
- }
-
- public boolean hasSameValues(Labels other) {
- return Arrays.equals(values, other.values);
- }
-
- @Override
- public int compareTo(Labels other) {
- int result = compare(prometheusNames, other.prometheusNames);
- if (result != 0) {
- return result;
- }
- return compare(values, other.values);
- }
-
- // Looks like Java doesn't have a compareTo() method for arrays.
- private int compare(String[] array1, String[] array2) {
- int result;
- for (int i = 0; i < array1.length; i++) {
- if (array2.length <= i) {
- return 1;
- }
- result = array1[i].compareTo(array2[i]);
- if (result != 0) {
- return result;
- }
+ }
+ }
+ return null;
+ }
+
+ private static void sortAndValidate(String[] names, String[] prometheusNames, String[] values) {
+ sort(names, prometheusNames, values);
+ validateNames(names, prometheusNames);
+ }
+
+ private static void validateNames(String[] names, String[] prometheusNames) {
+ for (int i = 0; i < names.length; i++) {
+ if (!isValidLabelName(names[i])) {
+ throw new IllegalArgumentException("'" + names[i] + "' is an illegal label name");
+ }
+ // The arrays are sorted, so duplicates are next to each other
+ if (i > 0 && prometheusNames[i - 1].equals(prometheusNames[i])) {
+ throw new IllegalArgumentException(names[i] + ": duplicate label name");
+ }
+ }
+ }
+
+ private static void sort(String[] names, String[] prometheusNames, String[] values) {
+ // bubblesort
+ int n = prometheusNames.length;
+ for (int i = 0; i < n - 1; i++) {
+ for (int j = 0; j < n - i - 1; j++) {
+ if (prometheusNames[j].compareTo(prometheusNames[j + 1]) > 0) {
+ swap(j, j + 1, names, prometheusNames, values);
}
- if (array2.length > array1.length) {
- return -1;
+ }
+ }
+ }
+
+ private static void swap(
+ int i, int j, String[] names, String[] prometheusNames, String[] values) {
+ String tmp = names[j];
+ names[j] = names[i];
+ names[i] = tmp;
+ tmp = values[j];
+ values[j] = values[i];
+ values[i] = tmp;
+ if (prometheusNames != names) {
+ tmp = prometheusNames[j];
+ prometheusNames[j] = prometheusNames[i];
+ prometheusNames[i] = tmp;
+ }
+ }
+
+ @Override
+ public Iterator iterator() {
+ return asList().iterator();
+ }
+
+ public Stream stream() {
+ return asList().stream();
+ }
+
+ public int size() {
+ return names.length;
+ }
+
+ public String getName(int i) {
+ return names[i];
+ }
+
+ /**
+ * Like {@link #getName(int)}, but dots are replaced with underscores.
+ *
+ * This is used by Prometheus exposition formats.
+ */
+ public String getPrometheusName(int i) {
+ return prometheusNames[i];
+ }
+
+ public String getValue(int i) {
+ return values[i];
+ }
+
+ /**
+ * Create a new Labels instance containing the labels of this and the labels of other. This and
+ * other must not contain the same label name.
+ */
+ public Labels merge(Labels other) {
+ if (this.isEmpty()) {
+ return other;
+ }
+ if (other.isEmpty()) {
+ return this;
+ }
+ String[] names = new String[this.names.length + other.names.length];
+ String[] prometheusNames = names;
+ if (this.names != this.prometheusNames || other.names != other.prometheusNames) {
+ prometheusNames = new String[names.length];
+ }
+ String[] values = new String[names.length];
+ int thisPos = 0;
+ int otherPos = 0;
+ while (thisPos + otherPos < names.length) {
+ if (thisPos >= this.names.length) {
+ names[thisPos + otherPos] = other.names[otherPos];
+ values[thisPos + otherPos] = other.values[otherPos];
+ if (prometheusNames != names) {
+ prometheusNames[thisPos + otherPos] = other.prometheusNames[otherPos];
}
- return 0;
- }
-
- private List asList() {
- List result = new ArrayList<>(names.length);
- for (int i = 0; i < names.length; i++) {
- result.add(new Label(names[i], values[i]));
+ otherPos++;
+ } else if (otherPos >= other.names.length) {
+ names[thisPos + otherPos] = this.names[thisPos];
+ values[thisPos + otherPos] = this.values[thisPos];
+ if (prometheusNames != names) {
+ prometheusNames[thisPos + otherPos] = this.prometheusNames[thisPos];
}
- return Collections.unmodifiableList(result);
- }
-
- /**
- * This must not be used in Prometheus exposition formats because names may contain dots.
- *
- * However, for debugging it's better to show the original names rather than the Prometheus names.
- */
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder();
- b.append("{");
- for (int i = 0; i < names.length; i++) {
- if (i > 0) {
- b.append(",");
- }
- b.append(names[i]);
- b.append("=\"");
- appendEscapedLabelValue(b, values[i]);
- b.append("\"");
+ thisPos++;
+ } else if (this.prometheusNames[thisPos].compareTo(other.prometheusNames[otherPos]) < 0) {
+ names[thisPos + otherPos] = this.names[thisPos];
+ values[thisPos + otherPos] = this.values[thisPos];
+ if (prometheusNames != names) {
+ prometheusNames[thisPos + otherPos] = this.prometheusNames[thisPos];
}
- b.append("}");
- return b.toString();
- }
-
- private void appendEscapedLabelValue(StringBuilder b, String value) {
- for (int i = 0; i < value.length(); i++) {
- char c = value.charAt(i);
- switch (c) {
- case '\\':
- b.append("\\\\");
- break;
- case '\"':
- b.append("\\\"");
- break;
- case '\n':
- b.append("\\n");
- break;
- default:
- b.append(c);
- }
+ thisPos++;
+ } else if (this.prometheusNames[thisPos].compareTo(other.prometheusNames[otherPos]) > 0) {
+ names[thisPos + otherPos] = other.names[otherPos];
+ values[thisPos + otherPos] = other.values[otherPos];
+ if (prometheusNames != names) {
+ prometheusNames[thisPos + otherPos] = other.prometheusNames[otherPos];
}
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- Labels labels = (Labels) o;
- return labels.hasSameNames(this) && labels.hasSameValues(this);
- }
-
- @Override
- public int hashCode() {
- int result = Arrays.hashCode(prometheusNames);
- result = 31 * result + Arrays.hashCode(values);
+ otherPos++;
+ } else {
+ throw new IllegalArgumentException("Duplicate label name: '" + this.names[thisPos] + "'.");
+ }
+ }
+ return new Labels(names, prometheusNames, values);
+ }
+
+ /**
+ * Create a new Labels instance containing the labels of this and the label passed as name and
+ * value. The label name must not already be contained in this Labels instance.
+ */
+ public Labels add(String name, String value) {
+ return merge(Labels.of(name, value));
+ }
+
+ /**
+ * Create a new Labels instance containing the labels of this and the labels passed as names and
+ * values. The new label names must not already be contained in this Labels instance.
+ */
+ public Labels merge(String[] names, String[] values) {
+ if (this.equals(EMPTY)) {
+ return Labels.of(names, values);
+ }
+ String[] mergedNames = new String[this.names.length + names.length];
+ String[] mergedValues = new String[this.values.length + values.length];
+ System.arraycopy(this.names, 0, mergedNames, 0, this.names.length);
+ System.arraycopy(this.values, 0, mergedValues, 0, this.values.length);
+ System.arraycopy(names, 0, mergedNames, this.names.length, names.length);
+ System.arraycopy(values, 0, mergedValues, this.values.length, values.length);
+ String[] prometheusNames = makePrometheusNames(mergedNames);
+ sortAndValidate(mergedNames, prometheusNames, mergedValues);
+ return new Labels(mergedNames, prometheusNames, mergedValues);
+ }
+
+ public boolean hasSameNames(Labels other) {
+ return Arrays.equals(prometheusNames, other.prometheusNames);
+ }
+
+ public boolean hasSameValues(Labels other) {
+ return Arrays.equals(values, other.values);
+ }
+
+ @Override
+ public int compareTo(Labels other) {
+ int result = compare(prometheusNames, other.prometheusNames);
+ if (result != 0) {
+ return result;
+ }
+ return compare(values, other.values);
+ }
+
+ // Looks like Java doesn't have a compareTo() method for arrays.
+ private int compare(String[] array1, String[] array2) {
+ int result;
+ for (int i = 0; i < array1.length; i++) {
+ if (array2.length <= i) {
+ return 1;
+ }
+ result = array1[i].compareTo(array2[i]);
+ if (result != 0) {
return result;
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private final List names = new ArrayList<>();
- private final List values = new ArrayList<>();
-
- private Builder() {
- }
-
- /**
- * Add a label. Call multiple times to add multiple labels.
- */
- public Builder label(String name, String value) {
- names.add(name);
- values.add(value);
- return this;
- }
-
- public Labels build() {
- return Labels.of(names, values);
- }
- }
+ }
+ }
+ if (array2.length > array1.length) {
+ return -1;
+ }
+ return 0;
+ }
+
+ private List asList() {
+ List result = new ArrayList<>(names.length);
+ for (int i = 0; i < names.length; i++) {
+ result.add(new Label(names[i], values[i]));
+ }
+ return Collections.unmodifiableList(result);
+ }
+
+ /**
+ * This must not be used in Prometheus exposition formats because names may contain dots.
+ *
+ * However, for debugging it's better to show the original names rather than the Prometheus
+ * names.
+ */
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("{");
+ for (int i = 0; i < names.length; i++) {
+ if (i > 0) {
+ b.append(",");
+ }
+ b.append(names[i]);
+ b.append("=\"");
+ appendEscapedLabelValue(b, values[i]);
+ b.append("\"");
+ }
+ b.append("}");
+ return b.toString();
+ }
+
+ private void appendEscapedLabelValue(StringBuilder b, String value) {
+ for (int i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ switch (c) {
+ case '\\':
+ b.append("\\\\");
+ break;
+ case '\"':
+ b.append("\\\"");
+ break;
+ case '\n':
+ b.append("\\n");
+ break;
+ default:
+ b.append(c);
+ }
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Labels labels = (Labels) o;
+ return labels.hasSameNames(this) && labels.hasSameValues(this);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Arrays.hashCode(prometheusNames);
+ result = 31 * result + Arrays.hashCode(values);
+ return result;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private final List names = new ArrayList<>();
+ private final List values = new ArrayList<>();
+
+ private Builder() {}
+
+ /** Add a label. Call multiple times to add multiple labels. */
+ public Builder label(String name, String value) {
+ names.add(name);
+ values.add(value);
+ return this;
+ }
+
+ public Labels build() {
+ return Labels.of(names, values);
+ }
+ }
}
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantile.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantile.java
index 7d5c1c166..1601920f0 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantile.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantile.java
@@ -1,34 +1,34 @@
package io.prometheus.metrics.model.snapshots;
-/**
- * Immutable representation of a Quantile.
- */
+/** Immutable representation of a Quantile. */
public class Quantile {
- private final double quantile;
- private final double value;
+ private final double quantile;
+ private final double value;
- /**
- * @param quantile expecting 0.0 <= quantile <= 1.0, otherwise an {@link IllegalArgumentException} will be thrown.
- * @param value
- */
- public Quantile(double quantile, double value) {
- this.quantile = quantile;
- this.value = value;
- validate();
- }
+ /**
+ * @param quantile expecting 0.0 <= quantile <= 1.0, otherwise an {@link
+ * IllegalArgumentException} will be thrown.
+ * @param value the quantile value
+ */
+ public Quantile(double quantile, double value) {
+ this.quantile = quantile;
+ this.value = value;
+ validate();
+ }
- public double getQuantile() {
- return quantile;
- }
+ public double getQuantile() {
+ return quantile;
+ }
- public double getValue() {
- return value;
- }
+ public double getValue() {
+ return value;
+ }
- private void validate() {
- if (quantile < 0.0 || quantile > 1.0) {
- throw new IllegalArgumentException(quantile + ": Illegal quantile. Expecting 0 <= quantile <= 1");
- }
+ private void validate() {
+ if (quantile < 0.0 || quantile > 1.0) {
+ throw new IllegalArgumentException(
+ quantile + ": Illegal quantile. Expecting 0 <= quantile <= 1");
}
+ }
}
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantiles.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantiles.java
index e4a7b3621..135af6658 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantiles.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/Quantiles.java
@@ -2,91 +2,86 @@
import java.util.*;
-/**
- * Immutable list of quantiles.
- */
+/** Immutable list of quantiles. */
public class Quantiles implements Iterable {
- private final List quantiles;
- public static final Quantiles EMPTY = new Quantiles(Collections.emptyList());
-
- private Quantiles(List quantiles) {
- quantiles = new ArrayList<>(quantiles);
- quantiles.sort(Comparator.comparing(Quantile::getQuantile));
- this.quantiles = Collections.unmodifiableList(quantiles);
- validate();
+ private final List quantiles;
+ public static final Quantiles EMPTY = new Quantiles(Collections.emptyList());
+
+ private Quantiles(List quantiles) {
+ quantiles = new ArrayList<>(quantiles);
+ quantiles.sort(Comparator.comparing(Quantile::getQuantile));
+ this.quantiles = Collections.unmodifiableList(quantiles);
+ validate();
+ }
+
+ private void validate() {
+ for (int i = 0; i < quantiles.size() - 1; i++) {
+ if (quantiles.get(i).getQuantile() == quantiles.get(i + 1).getQuantile()) {
+ throw new IllegalArgumentException(
+ "Duplicate " + quantiles.get(i).getQuantile() + " quantile.");
+ }
}
-
- private void validate() {
- for (int i=0; i< quantiles.size() - 1; i++) {
- if (quantiles.get(i).getQuantile() == quantiles.get(i+1).getQuantile()) {
- throw new IllegalArgumentException("Duplicate " + quantiles.get(i).getQuantile() + " quantile.");
- }
- }
- }
-
- /**
- * Create a new Quantiles instance.
- * You can either create Quantiles with one of the static {@code Quantiles.of(...)} methods,
- * or you can use the {@link Quantiles#builder()}.
- */
- public static Quantiles of(List quantiles) {
- return new Quantiles(quantiles);
+ }
+
+ /**
+ * Create a new Quantiles instance. You can either create Quantiles with one of the static {@code
+ * Quantiles.of(...)} methods, or you can use the {@link Quantiles#builder()}.
+ */
+ public static Quantiles of(List quantiles) {
+ return new Quantiles(quantiles);
+ }
+
+ /**
+ * Create a new Quantiles instance. You can either create Quantiles with one of the static {@code
+ * Quantiles.of(...)} methods, or you can use the {@link Quantiles#builder()}.
+ */
+ public static Quantiles of(Quantile... quantiles) {
+ return of(Arrays.asList(quantiles));
+ }
+
+ public int size() {
+ return quantiles.size();
+ }
+
+ public Quantile get(int i) {
+ return quantiles.get(i);
+ }
+
+ @Override
+ public Iterator iterator() {
+ return quantiles.iterator();
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+
+ private final List quantiles = new ArrayList<>();
+
+ private Builder() {}
+
+ /** Add a quantile. Call multiple times to add multiple quantiles. */
+ public Builder quantile(Quantile quantile) {
+ quantiles.add(quantile);
+ return this;
}
/**
- * Create a new Quantiles instance.
- * You can either create Quantiles with one of the static {@code Quantiles.of(...)} methods,
- * or you can use the {@link Quantiles#builder()}.
+ * Add a quantile. Call multiple times to add multiple quantiles.
+ *
+ * @param quantile 0.0 <= quantile <= 1.0
+ * @param value the quantile value
*/
- public static Quantiles of(Quantile... quantiles) {
- return of(Arrays.asList(quantiles));
- }
-
- public int size() {
- return quantiles.size();
+ public Builder quantile(double quantile, double value) {
+ quantiles.add(new Quantile(quantile, value));
+ return this;
}
- public Quantile get(int i) {
- return quantiles.get(i);
+ public Quantiles build() {
+ return new Quantiles(quantiles);
}
-
- @Override
- public Iterator iterator() {
- return quantiles.iterator();
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
-
- private final List quantiles = new ArrayList<>();
-
- private Builder() {
- }
-
- /**
- * Add a quantile. Call multiple times to add multiple quantiles.
- */
- public Builder quantile(Quantile quantile) {
- quantiles.add(quantile);
- return this;
- }
-
- /**
- * Add a quantile. Call multiple times to add multiple quantiles.
- * @param quantile 0.0 <= quantile <= 1.0
- */
- public Builder quantile(double quantile, double value) {
- quantiles.add(new Quantile(quantile, value));
- return this;
- }
-
- public Quantiles build() {
- return new Quantiles(quantiles);
- }
- }
-
+ }
}
diff --git a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/StateSetSnapshot.java b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/StateSetSnapshot.java
index ddcc94bc2..591732137 100644
--- a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/StateSetSnapshot.java
+++ b/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/StateSetSnapshot.java
@@ -8,225 +8,221 @@
import java.util.List;
import java.util.stream.Stream;
-/**
- * Immutable snapshot of a StateSet metric.
- */
+/** Immutable snapshot of a StateSet metric. */
public final class StateSetSnapshot extends MetricSnapshot {
+ /**
+ * To create a new {@link StateSetSnapshot}, you can either call the constructor directly or use
+ * the builder with {@link StateSetSnapshot#builder()}.
+ *
+ * @param metadata See {@link MetricMetadata} for more naming conventions.
+ * @param data the constructor will create a sorted copy of the collection.
+ */
+ public StateSetSnapshot(MetricMetadata metadata, Collection data) {
+ super(metadata, data);
+ validate();
+ }
+
+ private void validate() {
+ if (getMetadata().hasUnit()) {
+ throw new IllegalArgumentException("An state set metric cannot have a unit.");
+ }
+ for (StateSetDataPointSnapshot entry : getDataPoints()) {
+ if (entry.getLabels().contains(getMetadata().getPrometheusName())) {
+ throw new IllegalArgumentException(
+ "Label name " + getMetadata().getPrometheusName() + " is reserved.");
+ }
+ }
+ }
+
+ @Override
+ public List getDataPoints() {
+ return (List) dataPoints;
+ }
+
+ public static class StateSetDataPointSnapshot extends DataPointSnapshot
+ implements Iterable {
+ private final String[] names;
+ private final boolean[] values;
+
/**
- * To create a new {@link StateSetSnapshot}, you can either call the constructor directly or use
- * the builder with {@link StateSetSnapshot#builder()}.
+ * To create a new {@link StateSetDataPointSnapshot}, you can either call the constructor
+ * directly or use the Builder with {@link StateSetDataPointSnapshot#builder()}.
*
- * @param metadata See {@link MetricMetadata} for more naming conventions.
- * @param data the constructor will create a sorted copy of the collection.
+ * @param names state names. Must have at least 1 entry. The constructor will create a copy of
+ * the array.
+ * @param values state values. Must have the same length as {@code names}. The constructor will
+ * create a copy of the array.
+ * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels.
+ */
+ public StateSetDataPointSnapshot(String[] names, boolean[] values, Labels labels) {
+ this(names, values, labels, 0L);
+ }
+
+ /**
+ * Constructor with an additional scrape timestamp. This is only useful in rare cases as the
+ * scrape timestamp is usually set by the Prometheus server during scraping. Exceptions include
+ * mirroring metrics with given timestamps from other metric sources.
*/
- public StateSetSnapshot(MetricMetadata metadata, Collection data) {
- super(metadata, data);
- validate();
+ public StateSetDataPointSnapshot(
+ String[] names, boolean[] values, Labels labels, long scrapeTimestampMillis) {
+ super(labels, 0L, scrapeTimestampMillis);
+ if (names.length == 0) {
+ throw new IllegalArgumentException("StateSet must have at least one state.");
+ }
+ if (names.length != values.length) {
+ throw new IllegalArgumentException("names[] and values[] must have the same length");
+ }
+ String[] namesCopy = Arrays.copyOf(names, names.length);
+ boolean[] valuesCopy = Arrays.copyOf(values, names.length);
+ sort(namesCopy, valuesCopy);
+ this.names = namesCopy;
+ this.values = valuesCopy;
+ validate();
+ }
+
+ public int size() {
+ return names.length;
+ }
+
+ public String getName(int i) {
+ return names[i];
+ }
+
+ public boolean isTrue(int i) {
+ return values[i];
}
private void validate() {
- if (getMetadata().hasUnit()) {
- throw new IllegalArgumentException("An state set metric cannot have a unit.");
+ for (int i = 0; i < names.length; i++) {
+ if (names[i].isEmpty()) {
+ throw new IllegalArgumentException("Empty string as state name");
}
- for (StateSetDataPointSnapshot entry : getDataPoints()) {
- if (entry.getLabels().contains(getMetadata().getPrometheusName())) {
- throw new IllegalArgumentException("Label name " + getMetadata().getPrometheusName() + " is reserved.");
- }
+ if (i > 0 && names[i - 1].equals(names[i])) {
+ throw new IllegalArgumentException(names[i] + " duplicate state name");
}
+ }
}
- @Override
- public List getDataPoints() {
- return (List) dataPoints;
- }
-
-
- public static class StateSetDataPointSnapshot extends DataPointSnapshot implements Iterable {
- private final String[] names;
- private final boolean[] values;
-
- /**
- * To create a new {@link StateSetDataPointSnapshot}, you can either call the constructor directly or use the
- * Builder with {@link StateSetDataPointSnapshot#builder()}.
- *
- * @param names state names. Must have at least 1 entry.
- * The constructor will create a copy of the array.
- * @param values state values. Must have the same length as {@code names}.
- * The constructor will create a copy of the array.
- * @param labels must not be null. Use {@link Labels#EMPTY} if there are no labels.
- */
- public StateSetDataPointSnapshot(String[] names, boolean[] values, Labels labels) {
- this(names, values, labels, 0L);
- }
-
- /**
- * Constructor with an additional scrape timestamp.
- * This is only useful in rare cases as the scrape timestamp is usually set by the Prometheus server
- * during scraping. Exceptions include mirroring metrics with given timestamps from other metric sources.
- */
- public StateSetDataPointSnapshot(String[] names, boolean[] values, Labels labels, long scrapeTimestampMillis) {
- super(labels, 0L, scrapeTimestampMillis);
- if (names.length == 0) {
- throw new IllegalArgumentException("StateSet must have at least one state.");
- }
- if (names.length != values.length) {
- throw new IllegalArgumentException("names[] and values[] must have the same length");
- }
- String[] namesCopy = Arrays.copyOf(names, names.length);
- boolean[] valuesCopy = Arrays.copyOf(values, names.length);
- sort(namesCopy, valuesCopy);
- this.names = namesCopy;
- this.values = valuesCopy;
- validate();
- }
+ private List asList() {
+ List result = new ArrayList<>(size());
+ for (int i = 0; i < names.length; i++) {
+ result.add(new State(names[i], values[i]));
+ }
+ return Collections.unmodifiableList(result);
+ }
- public int size() {
- return names.length;
- }
+ @Override
+ public Iterator iterator() {
+ return asList().iterator();
+ }
- public String getName(int i) {
- return names[i];
- }
+ public Stream stream() {
+ return asList().stream();
+ }
- public boolean isTrue(int i) {
- return values[i];
+ private static void sort(String[] names, boolean[] values) {
+ // Bubblesort
+ int n = names.length;
+ for (int i = 0; i < n - 1; i++) {
+ for (int j = 0; j < n - i - 1; j++) {
+ if (names[j].compareTo(names[j + 1]) > 0) {
+ swap(j, j + 1, names, values);
+ }
}
+ }
+ }
- private void validate() {
- for (int i = 0; i < names.length; i++) {
- if (names[i].length() == 0) {
- throw new IllegalArgumentException("Empty string as state name");
- }
- if (i > 0 && names[i - 1].equals(names[i])) {
- throw new IllegalArgumentException(names[i] + " duplicate state name");
- }
- }
- }
+ private static void swap(int i, int j, String[] names, boolean[] values) {
+ String tmpName = names[j];
+ names[j] = names[i];
+ names[i] = tmpName;
+ boolean tmpValue = values[j];
+ values[j] = values[i];
+ values[i] = tmpValue;
+ }
- private List asList() {
- List result = new ArrayList<>(size());
- for (int i = 0; i < names.length; i++) {
- result.add(new State(names[i], values[i]));
- }
- return Collections.unmodifiableList(result);
- }
+ public static Builder builder() {
+ return new Builder();
+ }
- @Override
- public Iterator iterator() {
- return asList().iterator();
- }
+ public static class Builder extends DataPointSnapshot.Builder {
- public Stream stream() {
- return asList().stream();
- }
+ private final List names = new ArrayList<>();
+ private final List values = new ArrayList<>();
- private static void sort(String[] names, boolean[] values) {
- // Bubblesort
- int n = names.length;
- for (int i = 0; i < n - 1; i++) {
- for (int j = 0; j < n - i - 1; j++) {
- if (names[j].compareTo(names[j + 1]) > 0) {
- swap(j, j + 1, names, values);
- }
- }
- }
- }
+ private Builder() {}
- private static void swap(int i, int j, String[] names, boolean[] values) {
- String tmpName = names[j];
- names[j] = names[i];
- names[i] = tmpName;
- boolean tmpValue = values[j];
- values[j] = values[i];
- values[i] = tmpValue;
- }
+ /** Add a state. Call multiple times to add multiple states. */
+ public Builder state(String name, boolean value) {
+ names.add(name);
+ values.add(value);
+ return this;
+ }
- public static Builder builder() {
- return new Builder();
- }
+ @Override
+ protected Builder self() {
+ return this;
+ }
- public static class Builder extends DataPointSnapshot.Builder {
-
- private final ArrayList names = new ArrayList<>();
- private final ArrayList values = new ArrayList<>();
-
- private Builder() {}
-
- /**
- * Add a state. Call multple times to add multiple states.
- */
- public Builder state(String name, boolean value) {
- names.add(name);
- values.add(value);
- return this;
- }
-
- @Override
- protected Builder self() {
- return this;
- }
-
- public StateSetDataPointSnapshot build() {
- boolean[] valuesArray = new boolean[values.size()];
- for (int i = 0; i < values.size(); i++) {
- valuesArray[i] = values.get(i);
- }
- return new StateSetDataPointSnapshot(names.toArray(new String[]{}), valuesArray, labels, scrapeTimestampMillis);
- }
+ public StateSetDataPointSnapshot build() {
+ boolean[] valuesArray = new boolean[values.size()];
+ for (int i = 0; i < values.size(); i++) {
+ valuesArray[i] = values.get(i);
}
+ return new StateSetDataPointSnapshot(
+ names.toArray(new String[] {}), valuesArray, labels, scrapeTimestampMillis);
+ }
}
+ }
- public static class State {
- private final String name;
- private final boolean value;
-
- private State(String name, boolean value) {
- this.name = name;
- this.value = value;
- }
+ public static class State {
+ private final String name;
+ private final boolean value;
- public String getName() {
- return name;
- }
+ private State(String name, boolean value) {
+ this.name = name;
+ this.value = value;
+ }
- public boolean isTrue() {
- return value;
- }
+ public String getName() {
+ return name;
}
- public static Builder builder() {
- return new Builder();
+ public boolean isTrue() {
+ return value;
}
+ }
- public static class Builder extends MetricSnapshot.Builder {
+ public static Builder builder() {
+ return new Builder();
+ }
- private final List dataPoints = new ArrayList<>();
+ public static class Builder extends MetricSnapshot.Builder {
- private Builder() {
- }
+ private final List dataPoints = new ArrayList<>();
- /**
- * Add a data point. Call multiple times to add multiple data points.
- */
- public Builder dataPoint(StateSetDataPointSnapshot dataPoint) {
- dataPoints.add(dataPoint);
- return this;
- }
+ private Builder() {}
- @Override
- public Builder unit(Unit unit) {
- throw new IllegalArgumentException("StateSet metric cannot have a unit.");
- }
+ /** Add a data point. Call multiple times to add multiple data points. */
+ public Builder dataPoint(StateSetDataPointSnapshot dataPoint) {
+ dataPoints.add(dataPoint);
+ return this;
+ }
- @Override
- public StateSetSnapshot build() {
- return new StateSetSnapshot(buildMetadata(), dataPoints);
- }
+ @Override
+ public Builder unit(Unit unit) {
+ throw new IllegalArgumentException("StateSet metric cannot have a unit.");
+ }
- @Override
- protected Builder self() {
- return this;
- }
+ @Override
+ public StateSetSnapshot build() {
+ return new StateSetSnapshot(buildMetadata(), dataPoints);
+ }
+
+ @Override
+ protected Builder self() {
+ return this;
}
+ }
}
diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MetricNameFilterTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MetricNameFilterTest.java
index 91bcf74fc..6c7917bda 100644
--- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MetricNameFilterTest.java
+++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MetricNameFilterTest.java
@@ -2,79 +2,70 @@
import io.prometheus.metrics.model.snapshots.CounterSnapshot;
import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
-import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
-import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot;
import io.prometheus.metrics.model.snapshots.Labels;
import io.prometheus.metrics.model.snapshots.MetricSnapshots;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Predicate;
-
public class MetricNameFilterTest {
- private PrometheusRegistry registry;
+ private PrometheusRegistry registry;
- @Before
- public void setUp() {
- registry = new PrometheusRegistry();
- }
+ @Before
+ public void setUp() {
+ registry = new PrometheusRegistry();
+ }
- @Test
- public void testCounter() {
- registry.register(() -> CounterSnapshot.builder()
+ @Test
+ public void testCounter() {
+ registry.register(
+ () ->
+ CounterSnapshot.builder()
.name("counter1")
.help("test counter 1")
- .dataPoint(CounterDataPointSnapshot.builder()
+ .dataPoint(
+ CounterDataPointSnapshot.builder()
.labels(Labels.of("path", "/hello"))
.value(1.0)
- .build()
- )
- .dataPoint(CounterDataPointSnapshot.builder()
+ .build())
+ .dataPoint(
+ CounterDataPointSnapshot.builder()
.labels(Labels.of("path", "/goodbye"))
.value(2.0)
- .build()
- )
- .build()
- );
- registry.register(() -> CounterSnapshot.builder()
+ .build())
+ .build());
+ registry.register(
+ () ->
+ CounterSnapshot.builder()
.name("counter2")
.help("test counter 2")
- .dataPoint(CounterDataPointSnapshot.builder()
- .value(1.0)
- .build()
- )
- .build()
- );
+ .dataPoint(CounterDataPointSnapshot.builder().value(1.0).build())
+ .build());
- MetricNameFilter filter = MetricNameFilter.builder().build();
- Assert.assertEquals(2, registry.scrape(filter).size());
+ MetricNameFilter filter = MetricNameFilter.builder().build();
+ Assert.assertEquals(2, registry.scrape(filter).size());
- filter = MetricNameFilter.builder().nameMustStartWith("counter1").build();
- MetricSnapshots snapshots = registry.scrape(filter);
- Assert.assertEquals(1, snapshots.size());
- Assert.assertEquals("counter1", snapshots.get(0).getMetadata().getName());
+ filter = MetricNameFilter.builder().nameMustStartWith("counter1").build();
+ MetricSnapshots snapshots = registry.scrape(filter);
+ Assert.assertEquals(1, snapshots.size());
+ Assert.assertEquals("counter1", snapshots.get(0).getMetadata().getName());
- filter = MetricNameFilter.builder().nameMustNotStartWith("counter1").build();
- snapshots = registry.scrape(filter);
- Assert.assertEquals(1, snapshots.size());
- Assert.assertEquals("counter2", snapshots.get(0).getMetadata().getName());
+ filter = MetricNameFilter.builder().nameMustNotStartWith("counter1").build();
+ snapshots = registry.scrape(filter);
+ Assert.assertEquals(1, snapshots.size());
+ Assert.assertEquals("counter2", snapshots.get(0).getMetadata().getName());
- filter = MetricNameFilter.builder()
- .nameMustBeEqualTo("counter2_total", "counter1_total")
- .build();
- snapshots = registry.scrape(filter);
- Assert.assertEquals(2, snapshots.size());
+ filter =
+ MetricNameFilter.builder().nameMustBeEqualTo("counter2_total", "counter1_total").build();
+ snapshots = registry.scrape(filter);
+ Assert.assertEquals(2, snapshots.size());
- filter = MetricNameFilter.builder()
- .nameMustBeEqualTo("counter1_total")
- .nameMustNotBeEqualTo("counter1_total")
- .build();
- Assert.assertEquals(0, registry.scrape(filter).size());
- }
+ filter =
+ MetricNameFilter.builder()
+ .nameMustBeEqualTo("counter1_total")
+ .nameMustNotBeEqualTo("counter1_total")
+ .build();
+ Assert.assertEquals(0, registry.scrape(filter).size());
+ }
}
diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MultiCollectorNameFilterTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MultiCollectorNameFilterTest.java
index b36d58aa6..b302f4508 100644
--- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MultiCollectorNameFilterTest.java
+++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/MultiCollectorNameFilterTest.java
@@ -5,96 +5,96 @@
import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot;
import io.prometheus.metrics.model.snapshots.MetricSnapshots;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
public class MultiCollectorNameFilterTest {
- private PrometheusRegistry registry;
- private boolean[] collectCalled = {false};
- private Predicate includedNames = null;
- List prometheusNames = new ArrayList<>();
-
- @Before
- public void setUp() {
- registry = new PrometheusRegistry();
- collectCalled[0] = false;
- includedNames = null;
- prometheusNames = Collections.emptyList();
-
- registry.register(new MultiCollector() {
- @Override
- public MetricSnapshots collect() {
- collectCalled[0] = true;
- return MetricSnapshots.builder()
- .metricSnapshot(CounterSnapshot.builder()
- .name("counter_1")
- .dataPoint(CounterDataPointSnapshot.builder().value(1.0).build())
- .build()
- )
- .metricSnapshot(GaugeSnapshot.builder()
- .name("gauge_2")
- .dataPoint(GaugeDataPointSnapshot.builder().value(1.0).build())
- .build()
- )
- .build();
- }
-
- @Override
- public List getPrometheusNames() {
- return prometheusNames;
- }
+ private final boolean[] collectCalled = {false};
+ private PrometheusRegistry registry;
+ private Predicate includedNames = null;
+ private List prometheusNames = new ArrayList<>();
+
+ @Before
+ public void setUp() {
+ registry = new PrometheusRegistry();
+ collectCalled[0] = false;
+ includedNames = null;
+ prometheusNames = Collections.emptyList();
+
+ registry.register(
+ new MultiCollector() {
+ @Override
+ public MetricSnapshots collect() {
+ collectCalled[0] = true;
+ return MetricSnapshots.builder()
+ .metricSnapshot(
+ CounterSnapshot.builder()
+ .name("counter_1")
+ .dataPoint(CounterDataPointSnapshot.builder().value(1.0).build())
+ .build())
+ .metricSnapshot(
+ GaugeSnapshot.builder()
+ .name("gauge_2")
+ .dataPoint(GaugeDataPointSnapshot.builder().value(1.0).build())
+ .build())
+ .build();
+ }
+
+ @Override
+ public List getPrometheusNames() {
+ return prometheusNames;
+ }
});
- }
+ }
- @Test
- public void testPartialFilter() {
+ @Test
+ public void testPartialFilter() {
- includedNames = name -> name.equals("counter_1");
+ includedNames = name -> name.equals("counter_1");
- MetricSnapshots snapshots = registry.scrape(includedNames);
- Assert.assertTrue(collectCalled[0]);
- Assert.assertEquals(1, snapshots.size());
- Assert.assertEquals("counter_1", snapshots.get(0).getMetadata().getName());
- }
+ MetricSnapshots snapshots = registry.scrape(includedNames);
+ Assert.assertTrue(collectCalled[0]);
+ Assert.assertEquals(1, snapshots.size());
+ Assert.assertEquals("counter_1", snapshots.get(0).getMetadata().getName());
+ }
- @Test
- public void testPartialFilterWithPrometheusNames() {
+ @Test
+ public void testPartialFilterWithPrometheusNames() {
- includedNames = name -> name.equals("counter_1");
- prometheusNames = Arrays.asList("counter_1", "gauge_2");
+ includedNames = name -> name.equals("counter_1");
+ prometheusNames = Arrays.asList("counter_1", "gauge_2");
- MetricSnapshots snapshots = registry.scrape(includedNames);
- Assert.assertTrue(collectCalled[0]);
- Assert.assertEquals(1, snapshots.size());
- Assert.assertEquals("counter_1", snapshots.get(0).getMetadata().getName());
- }
+ MetricSnapshots snapshots = registry.scrape(includedNames);
+ Assert.assertTrue(collectCalled[0]);
+ Assert.assertEquals(1, snapshots.size());
+ Assert.assertEquals("counter_1", snapshots.get(0).getMetadata().getName());
+ }
- @Test
- public void testCompleteFilter_CollectCalled() {
+ @Test
+ public void testCompleteFilter_CollectCalled() {
- includedNames = name -> !name.equals("counter_1") && !name.equals("gauge_2");
+ includedNames = name -> !name.equals("counter_1") && !name.equals("gauge_2");
- MetricSnapshots snapshots = registry.scrape(includedNames);
- Assert.assertTrue(collectCalled[0]);
- Assert.assertEquals(0, snapshots.size());
- }
+ MetricSnapshots snapshots = registry.scrape(includedNames);
+ Assert.assertTrue(collectCalled[0]);
+ Assert.assertEquals(0, snapshots.size());
+ }
- @Test
- public void testCompleteFilter_CollectNotCalled() {
+ @Test
+ public void testCompleteFilter_CollectNotCalled() {
- includedNames = name -> !name.equals("counter_1") && !name.equals("gauge_2");
- prometheusNames = Arrays.asList("counter_1", "gauge_2");
+ includedNames = name -> !name.equals("counter_1") && !name.equals("gauge_2");
+ prometheusNames = Arrays.asList("counter_1", "gauge_2");
- MetricSnapshots snapshots = registry.scrape(includedNames);
- Assert.assertFalse(collectCalled[0]);
- Assert.assertEquals(0, snapshots.size());
- }
+ MetricSnapshots snapshots = registry.scrape(includedNames);
+ Assert.assertFalse(collectCalled[0]);
+ Assert.assertEquals(0, snapshots.size());
+ }
}
diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/PrometheusRegistryTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/PrometheusRegistryTest.java
index 498d2354b..c5dd287d7 100644
--- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/PrometheusRegistryTest.java
+++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/registry/PrometheusRegistryTest.java
@@ -4,101 +4,140 @@
import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
import io.prometheus.metrics.model.snapshots.MetricSnapshot;
import io.prometheus.metrics.model.snapshots.MetricSnapshots;
+import java.util.Arrays;
+import java.util.List;
import org.junit.Assert;
import org.junit.Test;
public class PrometheusRegistryTest {
- Collector noName = () -> GaugeSnapshot.builder()
- .name("no_name_gauge")
- .build();
+ Collector noName = () -> GaugeSnapshot.builder().name("no_name_gauge").build();
- Collector counterA1 = new Collector() {
+ Collector counterA1 =
+ new Collector() {
@Override
public MetricSnapshot collect() {
- return CounterSnapshot.builder().name("counter_a").build();
+ return CounterSnapshot.builder().name("counter_a").build();
}
@Override
public String getPrometheusName() {
- return "counter_a";
+ return "counter_a";
}
- };
+ };
- Collector counterA2 = new Collector() {
+ Collector counterA2 =
+ new Collector() {
@Override
public MetricSnapshot collect() {
- return CounterSnapshot.builder().name("counter.a").build();
+ return CounterSnapshot.builder().name("counter.a").build();
}
@Override
public String getPrometheusName() {
- return "counter_a";
+ return "counter_a";
}
- };
+ };
- Collector counterB = new Collector() {
+ Collector counterB =
+ new Collector() {
@Override
public MetricSnapshot collect() {
- return CounterSnapshot.builder().name("counter_b").build();
+ return CounterSnapshot.builder().name("counter_b").build();
}
@Override
public String getPrometheusName() {
- return "counter_b";
+ return "counter_b";
}
- };
+ };
- Collector gaugeA = new Collector() {
+ Collector gaugeA =
+ new Collector() {
@Override
public MetricSnapshot collect() {
- return GaugeSnapshot.builder().name("gauge_a").build();
+ return GaugeSnapshot.builder().name("gauge_a").build();
}
@Override
public String getPrometheusName() {
- return "gauge_a";
+ return "gauge_a";
}
- };
-
- @Test
- public void registerNoName() {
- PrometheusRegistry registry = new PrometheusRegistry();
- // If the collector does not have a name at registration time, there is no conflict during registration.
- registry.register(noName);
- registry.register(noName);
- // However, at scrape time the collector has to provide a metric name, and then we'll get a duplicat name error.
- try {
- registry.scrape();
- } catch (IllegalStateException e) {
- Assert.assertTrue(e.getMessage().contains("duplicate") && e.getMessage().contains("no_name_gauge"));
- return;
- }
- Assert.fail("Expected duplicate name exception");
- }
+ };
- @Test(expected = IllegalStateException.class)
- public void registerDuplicateName() {
- PrometheusRegistry registry = new PrometheusRegistry();
- registry.register(counterA1);
- registry.register(counterA2);
- }
+ MultiCollector multiCollector =
+ new MultiCollector() {
+ @Override
+ public MetricSnapshots collect() {
+ return new MetricSnapshots(gaugeA.collect(), counterB.collect());
+ }
- @Test
- public void registerOk() {
- PrometheusRegistry registry = new PrometheusRegistry();
- registry.register(counterA1);
- registry.register(counterB);
- registry.register(gaugeA);
- MetricSnapshots snapshots = registry.scrape();
- Assert.assertEquals(3, snapshots.size());
-
- registry.unregister(counterB);
- snapshots = registry.scrape();
- Assert.assertEquals(2, snapshots.size());
-
- registry.register(counterB);
- snapshots = registry.scrape();
- Assert.assertEquals(3, snapshots.size());
+ @Override
+ public List getPrometheusNames() {
+ return Arrays.asList(gaugeA.getPrometheusName(), counterB.getPrometheusName());
+ }
+ };
+
+ @Test
+ public void registerNoName() {
+ PrometheusRegistry registry = new PrometheusRegistry();
+ // If the collector does not have a name at registration time, there is no conflict during
+ // registration.
+ registry.register(noName);
+ registry.register(noName);
+ // However, at scrape time the collector has to provide a metric name, and then we'll get a
+ // duplicate name error.
+ try {
+ registry.scrape();
+ } catch (IllegalStateException e) {
+ Assert.assertTrue(
+ e.getMessage().contains("duplicate") && e.getMessage().contains("no_name_gauge"));
+ return;
}
+ Assert.fail("Expected duplicate name exception");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void registerDuplicateName() {
+ PrometheusRegistry registry = new PrometheusRegistry();
+ registry.register(counterA1);
+ registry.register(counterA2);
+ }
+
+ @Test
+ public void registerOk() {
+ PrometheusRegistry registry = new PrometheusRegistry();
+ registry.register(counterA1);
+ registry.register(counterB);
+ registry.register(gaugeA);
+ MetricSnapshots snapshots = registry.scrape();
+ Assert.assertEquals(3, snapshots.size());
+
+ registry.unregister(counterB);
+ snapshots = registry.scrape();
+ Assert.assertEquals(2, snapshots.size());
+
+ registry.register(counterB);
+ snapshots = registry.scrape();
+ Assert.assertEquals(3, snapshots.size());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void registerDuplicateMultiCollector() {
+ PrometheusRegistry registry = new PrometheusRegistry();
+ registry.register(multiCollector);
+ registry.register(multiCollector);
+ }
+
+ @Test
+ public void registerOkMultiCollector() {
+ PrometheusRegistry registry = new PrometheusRegistry();
+ registry.register(multiCollector);
+ MetricSnapshots snapshots = registry.scrape();
+ Assert.assertEquals(2, snapshots.size());
+
+ registry.unregister(multiCollector);
+ snapshots = registry.scrape();
+ Assert.assertEquals(0, snapshots.size());
+ }
}
diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/HistogramSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/HistogramSnapshotTest.java
index 5ff838dd7..e8e53e219 100644
--- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/HistogramSnapshotTest.java
+++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/HistogramSnapshotTest.java
@@ -1,269 +1,308 @@
package io.prometheus.metrics.model.snapshots;
import io.prometheus.metrics.model.snapshots.HistogramSnapshot.HistogramDataPointSnapshot;
-import org.junit.Assert;
-import org.junit.Test;
-
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
+import org.junit.Assert;
+import org.junit.Test;
public class HistogramSnapshotTest {
- @Test
- public void testGoodCaseComplete() {
- long createdTimestamp = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
- long scrapeTimestamp = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2);
- long exemplarTimestamp = System.currentTimeMillis();
- Exemplar exemplar1 = Exemplar.builder()
- .value(129.0)
- .traceId("abcabc")
- .spanId("defdef")
- .labels(Labels.of("status", "200"))
- .timestampMillis(exemplarTimestamp)
- .build();
- HistogramSnapshot snapshot = HistogramSnapshot.builder()
- .name("request_size_bytes")
- .help("request sizes in bytes")
- .unit(Unit.BYTES)
- .dataPoint(
- HistogramDataPointSnapshot.builder()
- .sum(27000.0)
- .nativeSchema(5)
- .nativeZeroCount(2)
- .nativeZeroThreshold(0.0000001)
- .classicHistogramBuckets(ClassicHistogramBuckets.builder()
- .bucket(Double.POSITIVE_INFINITY, 0)
- .bucket(128.0, 7)
- .bucket(1024.0, 15)
- .build())
- // The total number of observations in the native and classic histogram
- // is consistent (22 observations), but the individual bucket counts don't fit.
- // It doesn't matter for this test, but it would be good to use a more consistent
- // example in the test.
- .nativeBucketsForPositiveValues(NativeHistogramBuckets.builder()
- .bucket(1, 12)
- .bucket(2, 3)
- .bucket(4, 2)
- .build())
- .nativeBucketsForNegativeValues(NativeHistogramBuckets.builder()
- .bucket(-1, 1)
- .bucket(0, 2)
- .build())
- .labels(Labels.of("path", "/"))
- .exemplars(Exemplars.of(exemplar1))
- .createdTimestampMillis(createdTimestamp)
- .scrapeTimestampMillis(scrapeTimestamp)
- .build())
- .dataPoint(HistogramDataPointSnapshot.builder()
- .count(3) // TODO how is that not a compile error? This is a protected method!
- .sum(400.2)
- .nativeSchema(5)
- .classicHistogramBuckets(ClassicHistogramBuckets.builder()
- .bucket(128.0, 0)
- .bucket(1024.0, 4)
- .bucket(Double.POSITIVE_INFINITY, 2)
- .build())
- .nativeBucketsForPositiveValues(NativeHistogramBuckets.builder()
- .bucket(-1, 1)
- .bucket(3, 3)
- .bucket(4, 2)
- .build())
- .labels(Labels.of("path", "/api/v1"))
- .exemplars(Exemplars.of(exemplar1))
- .createdTimestampMillis(createdTimestamp)
- .scrapeTimestampMillis(scrapeTimestamp)
- .build())
- .build();
- SnapshotTestUtil.assertMetadata(snapshot, "request_size_bytes", "request sizes in bytes", "bytes");
+ @Test
+ public void testGoodCaseComplete() {
+ long createdTimestamp = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
+ long scrapeTimestamp = System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2);
+ long exemplarTimestamp = System.currentTimeMillis();
+ Exemplar exemplar1 =
+ Exemplar.builder()
+ .value(129.0)
+ .traceId("abcabc")
+ .spanId("defdef")
+ .labels(Labels.of("status", "200"))
+ .timestampMillis(exemplarTimestamp)
+ .build();
+ HistogramSnapshot snapshot =
+ HistogramSnapshot.builder()
+ .name("request_size_bytes")
+ .help("request sizes in bytes")
+ .unit(Unit.BYTES)
+ .dataPoint(
+ HistogramDataPointSnapshot.builder()
+ .sum(27000.0)
+ .nativeSchema(5)
+ .nativeZeroCount(2)
+ .nativeZeroThreshold(0.0000001)
+ .classicHistogramBuckets(
+ ClassicHistogramBuckets.builder()
+ .bucket(Double.POSITIVE_INFINITY, 0)
+ .bucket(128.0, 7)
+ .bucket(1024.0, 15)
+ .build())
+ // The total number of observations in the native and classic histogram
+ // is consistent (22 observations), but the individual bucket counts don't fit.
+ // It doesn't matter for this test, but it would be good to use a more
+ // consistent
+ // example in the test.
+ .nativeBucketsForPositiveValues(
+ NativeHistogramBuckets.builder()
+ .bucket(1, 12)
+ .bucket(2, 3)
+ .bucket(4, 2)
+ .build())
+ .nativeBucketsForNegativeValues(
+ NativeHistogramBuckets.builder().bucket(-1, 1).bucket(0, 2).build())
+ .labels(Labels.of("path", "/"))
+ .exemplars(Exemplars.of(exemplar1))
+ .createdTimestampMillis(createdTimestamp)
+ .scrapeTimestampMillis(scrapeTimestamp)
+ .build())
+ .dataPoint(
+ HistogramDataPointSnapshot.builder()
+ .count(3)
+ .sum(400.2)
+ .nativeSchema(5)
+ .classicHistogramBuckets(
+ ClassicHistogramBuckets.builder()
+ .bucket(128.0, 0)
+ .bucket(1024.0, 4)
+ .bucket(Double.POSITIVE_INFINITY, 2)
+ .build())
+ .nativeBucketsForPositiveValues(
+ NativeHistogramBuckets.builder()
+ .bucket(-1, 1)
+ .bucket(3, 3)
+ .bucket(4, 2)
+ .build())
+ .labels(Labels.of("path", "/api/v1"))
+ .exemplars(Exemplars.of(exemplar1))
+ .createdTimestampMillis(createdTimestamp)
+ .scrapeTimestampMillis(scrapeTimestamp)
+ .build())
+ .build();
+ SnapshotTestUtil.assertMetadata(
+ snapshot, "request_size_bytes", "request sizes in bytes", "bytes");
- Assert.assertEquals(2, snapshot.getDataPoints().size());
- HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0); // data is sorted by labels, so the first one should be path="/"
- Assert.assertTrue(data.hasSum());
- Assert.assertTrue(data.hasCount());
- Assert.assertTrue(data.hasCreatedTimestamp());
- Assert.assertTrue(data.hasScrapeTimestamp());
- Assert.assertEquals(22, data.getCount());
- Assert.assertEquals(27000.0, data.getSum(), 0.0);
- Assert.assertEquals(Labels.of("path", "/"), data.getLabels());
- Assert.assertEquals(exemplar1.getValue(), data.getExemplars().get(128.0, 1024.0).getValue(), 0.0);
- Assert.assertEquals(createdTimestamp, data.getCreatedTimestampMillis());
- Assert.assertEquals(scrapeTimestamp, data.getScrapeTimestampMillis());
- // classic histogram 1
- int i = 0;
- for (ClassicHistogramBucket bucket : data.getClassicBuckets()) {
- switch (i++) {
- case 0:
- Assert.assertEquals(128.0, bucket.getUpperBound(), 0.0);
- Assert.assertEquals(7, bucket.getCount());
- break;
- case 1:
- Assert.assertEquals(1024.0, bucket.getUpperBound(), 0.0);
- Assert.assertEquals(15, bucket.getCount());
- break;
- case 2:
- Assert.assertEquals(Double.POSITIVE_INFINITY, bucket.getUpperBound(), 0.0);
- Assert.assertEquals(0, bucket.getCount());
- break;
- }
- }
- Assert.assertEquals("expecting 3 classic histogram buckets", 3, i);
- // native histogram 1
- Assert.assertEquals(5, data.getNativeSchema());
- Assert.assertEquals(2, data.getNativeZeroCount());
- Assert.assertEquals(0.0000001, data.getNativeZeroThreshold(), 0.0000001);
- Assert.assertEquals(3, data.getNativeBucketsForPositiveValues().size());
- i = 0;
- for (NativeHistogramBucket bucket : data.getNativeBucketsForPositiveValues()) {
- switch (i++) {
- case 0:
- Assert.assertEquals(1, bucket.getBucketIndex());
- Assert.assertEquals(12, bucket.getCount());
- break;
- case 1:
- Assert.assertEquals(2, bucket.getBucketIndex());
- Assert.assertEquals(3, bucket.getCount());
- break;
- case 2:
- Assert.assertEquals(4, bucket.getBucketIndex());
- Assert.assertEquals(2, bucket.getCount());
- break;
- }
- }
- Assert.assertEquals("expecting 3 native buckets for positive values", 3, i);
- i = 0;
- Assert.assertEquals(2, data.getNativeBucketsForNegativeValues().size());
- for (NativeHistogramBucket bucket : data.getNativeBucketsForNegativeValues()) {
- switch (i++) {
- case 0:
- Assert.assertEquals(-1, bucket.getBucketIndex());
- Assert.assertEquals(1, bucket.getCount());
- break;
- case 1:
- Assert.assertEquals(0, bucket.getBucketIndex());
- Assert.assertEquals(2, bucket.getCount());
- break;
- }
- }
- Assert.assertEquals("expecting 2 native buckets for positive values", 2, i);
- // classic histogram 2 (it's ok that this is incomplete, because we covered it with the other tests)
- data = snapshot.getDataPoints().get(1);
- Assert.assertEquals(6, data.getCount());
- // native histogram 2 (it's ok that this is incomplete, because we covered it with the other tests)
- Assert.assertEquals(5, data.getNativeSchema());
- Assert.assertEquals(0, data.getNativeZeroCount());
- Assert.assertEquals(0, data.getNativeZeroThreshold(), 0);
+ Assert.assertEquals(2, snapshot.getDataPoints().size());
+ HistogramDataPointSnapshot data =
+ snapshot
+ .getDataPoints()
+ .get(0); // data is sorted by labels, so the first one should be path="/"
+ Assert.assertTrue(data.hasSum());
+ Assert.assertTrue(data.hasCount());
+ Assert.assertTrue(data.hasCreatedTimestamp());
+ Assert.assertTrue(data.hasScrapeTimestamp());
+ Assert.assertEquals(22, data.getCount());
+ Assert.assertEquals(27000.0, data.getSum(), 0.0);
+ Assert.assertEquals(Labels.of("path", "/"), data.getLabels());
+ Assert.assertEquals(
+ exemplar1.getValue(), data.getExemplars().get(128.0, 1024.0).getValue(), 0.0);
+ Assert.assertEquals(createdTimestamp, data.getCreatedTimestampMillis());
+ Assert.assertEquals(scrapeTimestamp, data.getScrapeTimestampMillis());
+ // classic histogram 1
+ int i = 0;
+ for (ClassicHistogramBucket bucket : data.getClassicBuckets()) {
+ switch (i++) {
+ case 0:
+ Assert.assertEquals(128.0, bucket.getUpperBound(), 0.0);
+ Assert.assertEquals(7, bucket.getCount());
+ break;
+ case 1:
+ Assert.assertEquals(1024.0, bucket.getUpperBound(), 0.0);
+ Assert.assertEquals(15, bucket.getCount());
+ break;
+ case 2:
+ Assert.assertEquals(Double.POSITIVE_INFINITY, bucket.getUpperBound(), 0.0);
+ Assert.assertEquals(0, bucket.getCount());
+ break;
+ }
}
-
- @Test
- public void testEmptyHistogram() {
- HistogramSnapshot snapshot = HistogramSnapshot.builder()
- .name("empty_histogram")
- .build();
- Assert.assertEquals(0, snapshot.getDataPoints().size());
+ Assert.assertEquals("expecting 3 classic histogram buckets", 3, i);
+ // native histogram 1
+ Assert.assertEquals(5, data.getNativeSchema());
+ Assert.assertEquals(2, data.getNativeZeroCount());
+ Assert.assertEquals(0.0000001, data.getNativeZeroThreshold(), 0.0000001);
+ Assert.assertEquals(3, data.getNativeBucketsForPositiveValues().size());
+ i = 0;
+ for (NativeHistogramBucket bucket : data.getNativeBucketsForPositiveValues()) {
+ switch (i++) {
+ case 0:
+ Assert.assertEquals(1, bucket.getBucketIndex());
+ Assert.assertEquals(12, bucket.getCount());
+ break;
+ case 1:
+ Assert.assertEquals(2, bucket.getBucketIndex());
+ Assert.assertEquals(3, bucket.getCount());
+ break;
+ case 2:
+ Assert.assertEquals(4, bucket.getBucketIndex());
+ Assert.assertEquals(2, bucket.getCount());
+ break;
+ }
}
-
- @Test
- public void testMinimalClassicHistogram() {
- HistogramSnapshot snapshot = HistogramSnapshot.builder()
- .name("minimal_histogram")
- .dataPoint(HistogramDataPointSnapshot.builder()
- .classicHistogramBuckets(ClassicHistogramBuckets.of(new double[]{Double.POSITIVE_INFINITY}, new long[]{0}))
- .build())
- .build();
- HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0);
- Assert.assertFalse(data.hasSum());
- Assert.assertEquals(1, snapshot.getDataPoints().get(0).getClassicBuckets().size());
+ Assert.assertEquals("expecting 3 native buckets for positive values", 3, i);
+ i = 0;
+ Assert.assertEquals(2, data.getNativeBucketsForNegativeValues().size());
+ for (NativeHistogramBucket bucket : data.getNativeBucketsForNegativeValues()) {
+ switch (i++) {
+ case 0:
+ Assert.assertEquals(-1, bucket.getBucketIndex());
+ Assert.assertEquals(1, bucket.getCount());
+ break;
+ case 1:
+ Assert.assertEquals(0, bucket.getBucketIndex());
+ Assert.assertEquals(2, bucket.getCount());
+ break;
+ }
}
+ Assert.assertEquals("expecting 2 native buckets for positive values", 2, i);
+ // classic histogram 2 (it's ok that this is incomplete, because we covered it with the other
+ // tests)
+ data = snapshot.getDataPoints().get(1);
+ Assert.assertEquals(6, data.getCount());
+ // native histogram 2 (it's ok that this is incomplete, because we covered it with the other
+ // tests)
+ Assert.assertEquals(5, data.getNativeSchema());
+ Assert.assertEquals(0, data.getNativeZeroCount());
+ Assert.assertEquals(0, data.getNativeZeroThreshold(), 0);
+ }
- @Test
- public void testMinimalNativeHistogram() {
- HistogramSnapshot snapshot = HistogramSnapshot.builder()
- .name("hist")
- .dataPoint(HistogramDataPointSnapshot.builder()
- .nativeSchema(5)
- .build())
- .build();
- Assert.assertEquals("hist", snapshot.getMetadata().getName());
- Assert.assertFalse(snapshot.getMetadata().hasUnit());
- Assert.assertEquals(1, snapshot.getDataPoints().size());
- HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0);
- Assert.assertFalse(data.hasCreatedTimestamp());
- Assert.assertFalse(data.hasScrapeTimestamp());
- Assert.assertTrue(data.hasCount());
- Assert.assertEquals(0, data.getCount());
- Assert.assertFalse(data.hasSum());
- Assert.assertEquals(0, data.getNativeBucketsForNegativeValues().size());
- Assert.assertEquals(0, data.getNativeBucketsForPositiveValues().size());
- }
+ @Test
+ public void testEmptyHistogram() {
+ HistogramSnapshot snapshot = HistogramSnapshot.builder().name("empty_histogram").build();
+ Assert.assertEquals(0, snapshot.getDataPoints().size());
+ }
- @Test
- public void testClassicCount() {
- HistogramSnapshot snapshot = HistogramSnapshot.builder()
- .name("test_histogram")
- .dataPoint(HistogramDataPointSnapshot.builder()
- .classicHistogramBuckets(ClassicHistogramBuckets.builder()
- .bucket(1.0, 3)
- .bucket(2.0, 2)
- .bucket(Double.POSITIVE_INFINITY, 0)
- .build())
- .build())
- .build();
- HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0);
- Assert.assertFalse(data.hasSum());
- Assert.assertTrue(data.hasCount());
- Assert.assertEquals(5, data.getCount());
- }
+ @Test
+ public void testMinimalClassicHistogram() {
+ HistogramSnapshot snapshot =
+ HistogramSnapshot.builder()
+ .name("minimal_histogram")
+ .dataPoint(
+ HistogramDataPointSnapshot.builder()
+ .classicHistogramBuckets(
+ ClassicHistogramBuckets.of(
+ new double[] {Double.POSITIVE_INFINITY}, new long[] {0}))
+ .build())
+ .build();
+ HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0);
+ Assert.assertFalse(data.hasSum());
+ Assert.assertEquals(1, snapshot.getDataPoints().get(0).getClassicBuckets().size());
+ }
- @Test(expected = IllegalArgumentException.class)
- public void testEmptyData() {
- // This will fail because one of nativeSchema and classicHistogramBuckets is required
- HistogramDataPointSnapshot.builder().build();
- }
+ @Test
+ public void testMinimalNativeHistogram() {
+ HistogramSnapshot snapshot =
+ HistogramSnapshot.builder()
+ .name("hist")
+ .dataPoint(HistogramDataPointSnapshot.builder().nativeSchema(5).build())
+ .build();
+ Assert.assertEquals("hist", snapshot.getMetadata().getName());
+ Assert.assertFalse(snapshot.getMetadata().hasUnit());
+ Assert.assertEquals(1, snapshot.getDataPoints().size());
+ HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0);
+ Assert.assertFalse(data.hasCreatedTimestamp());
+ Assert.assertFalse(data.hasScrapeTimestamp());
+ Assert.assertTrue(data.hasCount());
+ Assert.assertEquals(0, data.getCount());
+ Assert.assertFalse(data.hasSum());
+ Assert.assertEquals(0, data.getNativeBucketsForNegativeValues().size());
+ Assert.assertEquals(0, data.getNativeBucketsForPositiveValues().size());
+ }
- @Test
- public void testEmptyNativeData() {
- HistogramDataPointSnapshot data = HistogramDataPointSnapshot.builder()
- .nativeSchema(5)
- .build();
- Assert.assertEquals(0, data.getNativeBucketsForNegativeValues().size());
- Assert.assertEquals(0, data.getNativeBucketsForPositiveValues().size());
- }
+ @Test
+ public void testClassicCount() {
+ HistogramSnapshot snapshot =
+ HistogramSnapshot.builder()
+ .name("test_histogram")
+ .dataPoint(
+ HistogramDataPointSnapshot.builder()
+ .classicHistogramBuckets(
+ ClassicHistogramBuckets.builder()
+ .bucket(1.0, 3)
+ .bucket(2.0, 2)
+ .bucket(Double.POSITIVE_INFINITY, 0)
+ .build())
+ .build())
+ .build();
+ HistogramDataPointSnapshot data = snapshot.getDataPoints().get(0);
+ Assert.assertFalse(data.hasSum());
+ Assert.assertTrue(data.hasCount());
+ Assert.assertEquals(5, data.getCount());
+ }
- @Test(expected = UnsupportedOperationException.class)
- public void testDataImmutable() {
- HistogramSnapshot snapshot = HistogramSnapshot.builder()
- .name("test_histogram")
- .dataPoint(HistogramDataPointSnapshot.builder()
- .labels(Labels.of("a", "a"))
- .classicHistogramBuckets(ClassicHistogramBuckets.of(new double[]{Double.POSITIVE_INFINITY}, new long[]{0}))
- .build())
- .dataPoint(HistogramDataPointSnapshot.builder()
- .labels(Labels.of("a", "b"))
- .classicHistogramBuckets(ClassicHistogramBuckets.of(new double[]{Double.POSITIVE_INFINITY}, new long[]{2}))
- .build())
- .build();
- Iterator iterator = snapshot.getDataPoints().iterator();
- iterator.next();
- iterator.remove();
- }
+ @Test(expected = IllegalArgumentException.class)
+ public void testEmptyData() {
+ // This will fail because one of nativeSchema and classicHistogramBuckets is required
+ HistogramDataPointSnapshot.builder().build();
+ }
- @Test(expected = IllegalArgumentException.class)
- public void testEmptyClassicBuckets() {
- new HistogramDataPointSnapshot(ClassicHistogramBuckets.EMPTY, Double.NaN, Labels.EMPTY, Exemplars.EMPTY, 0L);
- }
+ @Test
+ public void testEmptyNativeData() {
+ HistogramDataPointSnapshot data = HistogramDataPointSnapshot.builder().nativeSchema(5).build();
+ Assert.assertEquals(0, data.getNativeBucketsForNegativeValues().size());
+ Assert.assertEquals(0, data.getNativeBucketsForPositiveValues().size());
+ }
- @Test
- public void testMinimalNativeData() {
- new HistogramDataPointSnapshot(ClassicHistogramBuckets.EMPTY, 0, 0, 0.0,
- NativeHistogramBuckets.EMPTY, NativeHistogramBuckets.EMPTY, Double.NaN, Labels.EMPTY, Exemplars.EMPTY, 0L);
- }
+ @Test(expected = UnsupportedOperationException.class)
+ public void testDataImmutable() {
+ HistogramSnapshot snapshot =
+ HistogramSnapshot.builder()
+ .name("test_histogram")
+ .dataPoint(
+ HistogramDataPointSnapshot.builder()
+ .labels(Labels.of("a", "a"))
+ .classicHistogramBuckets(
+ ClassicHistogramBuckets.of(
+ new double[] {Double.POSITIVE_INFINITY}, new long[] {0}))
+ .build())
+ .dataPoint(
+ HistogramDataPointSnapshot.builder()
+ .labels(Labels.of("a", "b"))
+ .classicHistogramBuckets(
+ ClassicHistogramBuckets.of(
+ new double[] {Double.POSITIVE_INFINITY}, new long[] {2}))
+ .build())
+ .build();
+ Iterator iterator = snapshot.getDataPoints().iterator();
+ iterator.next();
+ iterator.remove();
+ }
- @Test
- public void testMinimalClassicData() {
- ClassicHistogramBuckets buckets = ClassicHistogramBuckets.builder()
- .bucket(Double.POSITIVE_INFINITY, 0)
- .build();
- new HistogramDataPointSnapshot(buckets, HistogramSnapshot.CLASSIC_HISTOGRAM, 0, 0.0,
- NativeHistogramBuckets.EMPTY, NativeHistogramBuckets.EMPTY, Double.NaN, Labels.EMPTY, Exemplars.EMPTY, 0L);
- }
+ @Test(expected = IllegalArgumentException.class)
+ public void testEmptyClassicBuckets() {
+ new HistogramDataPointSnapshot(
+ ClassicHistogramBuckets.EMPTY, Double.NaN, Labels.EMPTY, Exemplars.EMPTY, 0L);
+ }
+
+ @Test
+ public void testMinimalNativeData() {
+ new HistogramDataPointSnapshot(
+ ClassicHistogramBuckets.EMPTY,
+ 0,
+ 0,
+ 0.0,
+ NativeHistogramBuckets.EMPTY,
+ NativeHistogramBuckets.EMPTY,
+ Double.NaN,
+ Labels.EMPTY,
+ Exemplars.EMPTY,
+ 0L);
+ }
+
+ @Test
+ public void testMinimalClassicData() {
+ ClassicHistogramBuckets buckets =
+ ClassicHistogramBuckets.builder().bucket(Double.POSITIVE_INFINITY, 0).build();
+ new HistogramDataPointSnapshot(
+ buckets,
+ HistogramSnapshot.CLASSIC_HISTOGRAM,
+ 0,
+ 0.0,
+ NativeHistogramBuckets.EMPTY,
+ NativeHistogramBuckets.EMPTY,
+ Double.NaN,
+ Labels.EMPTY,
+ Exemplars.EMPTY,
+ 0L);
+ }
}
diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/LabelsTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/LabelsTest.java
index d7a3e8b3e..e7ae37723 100644
--- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/LabelsTest.java
+++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/LabelsTest.java
@@ -1,131 +1,128 @@
package io.prometheus.metrics.model.snapshots;
-import io.prometheus.metrics.model.snapshots.Labels;
+import static org.junit.Assert.assertNotEquals;
+
import org.junit.Assert;
-import org.junit.Ignore;
import org.junit.Test;
-import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeLabelName;
-import static org.junit.Assert.assertNotEquals;
-
public class LabelsTest {
- private > void assertLessThan(T a, T b) {
- Assert.assertTrue(a.compareTo(b) < 0);
- }
-
- private > void assertGreaterThan(T a, T b) {
- Assert.assertTrue(a.compareTo(b) > 0);
- }
-
- @Test
- public void testCompareDifferentLabelNames() {
- Labels labels1 = Labels.of("env", "prod", "status2", "200");
- Labels labels2 = Labels.of("env", "prod", "status1", "200");
- assertGreaterThan(labels1, labels2);
- assertLessThan(labels2, labels1);
- assertNotEquals(labels1, labels2);
- assertNotEquals(labels2, labels1);
- }
-
- @Test
- public void testCompareSameLabelNames() {
- // If all label names are the same, labels should be sorted by label value.
- Labels labels1 = Labels.of("env", "prod", "status", "200");
- Labels labels2 = Labels.of("env", "prod", "status", "500");
- assertLessThan(labels1, labels2);
- assertGreaterThan(labels2, labels1);
- assertNotEquals(labels1, labels2);
- assertNotEquals(labels2, labels1);
- }
-
- @Test
- public void testCompareDifferentNumberOfLabels() {
- Labels labels1 = Labels.of("env", "prod", "status", "200");
- Labels labels2 = Labels.of("env", "prod", "status", "200", "x_code", "none");
- assertLessThan(labels1, labels2);
- assertGreaterThan(labels2, labels1);
- assertNotEquals(labels1, labels2);
- assertNotEquals(labels2, labels1);
- }
-
- @Test
- public void testComparePrometheusNames() {
- Labels labels1 = Labels.of("my_a", "val");
- Labels labels2 = Labels.of("my.b", "val");
- assertLessThan(labels1, labels2); // this is true because it compares "my_a" to "my_b".
- }
-
- @Test
- public void testEqualsHashcodeDots() {
- Labels labels1 = Labels.of("my_a", "val");
- Labels labels2 = Labels.of("my.a", "val");
- Assert.assertEquals(labels1, labels2);
- Assert.assertEquals(labels1.hashCode(), labels2.hashCode());
- }
-
- @Test
- public void testCompareEquals() {
- Labels labels1 = Labels.of("env", "prod", "status", "200");
- Labels labels2 = Labels.of("env", "prod", "status", "200");
- Assert.assertEquals(0, labels1.compareTo(labels2));
- Assert.assertEquals(0, labels2.compareTo(labels1));
- Assert.assertEquals(labels1, labels2);
- Assert.assertEquals(labels2, labels1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testIllegalLabelName() {
- Labels.of("my_service/status", "200");
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testReservedLabelName() {
- Labels.of("__name__", "requests_total");
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testDuplicateLabelName() {
- Labels.of("name1", "value1", "name2", "value2", "name1", "value3");
- }
-
- @Test
- public void testMakePrometheusNames() {
- String[] names = new String[]{};
- String[] prometheusNames = Labels.makePrometheusNames(names);
- Assert.assertSame(names, prometheusNames);
-
- names = new String[]{"no_dots", "at_all"};
- prometheusNames = Labels.makePrometheusNames(names);
- Assert.assertSame(names, prometheusNames);
-
- names = new String[]{"dots", "here.it.is"};
- prometheusNames = Labels.makePrometheusNames(names);
- Assert.assertNotSame(names, prometheusNames);
- Assert.assertSame(names[0], prometheusNames[0]);
- Assert.assertEquals("here.it.is", names[1]);
- Assert.assertEquals("here_it_is", prometheusNames[1]);
- }
-
- @Test
- public void testMerge() {
- Labels labels1 = Labels.of("key.1", "value 1", "key.3", "value 3");
- Labels labels2 = Labels.of("key_2", "value 2");
- Labels merged = labels2.merge(labels1);
- Assert.assertEquals("key.1", merged.getName(0));
- Assert.assertEquals("key_2", merged.getName(1));
- Assert.assertEquals("key.3", merged.getName(2));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testMergeDuplicateName() {
- Labels labels1 = Labels.of("key_one", "v1");
- Labels labels2 = Labels.of("key.one", "v2");
- labels2.merge(labels1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testDuplicateName() {
- Labels.of("key_one", "v1", "key.one", "v2");
- }
+ private > void assertLessThan(T a, T b) {
+ Assert.assertTrue(a.compareTo(b) < 0);
+ }
+
+ private > void assertGreaterThan(T a, T b) {
+ Assert.assertTrue(a.compareTo(b) > 0);
+ }
+
+ @Test
+ public void testCompareDifferentLabelNames() {
+ Labels labels1 = Labels.of("env", "prod", "status2", "200");
+ Labels labels2 = Labels.of("env", "prod", "status1", "200");
+ assertGreaterThan(labels1, labels2);
+ assertLessThan(labels2, labels1);
+ assertNotEquals(labels1, labels2);
+ assertNotEquals(labels2, labels1);
+ }
+
+ @Test
+ public void testCompareSameLabelNames() {
+ // If all label names are the same, labels should be sorted by label value.
+ Labels labels1 = Labels.of("env", "prod", "status", "200");
+ Labels labels2 = Labels.of("env", "prod", "status", "500");
+ assertLessThan(labels1, labels2);
+ assertGreaterThan(labels2, labels1);
+ assertNotEquals(labels1, labels2);
+ assertNotEquals(labels2, labels1);
+ }
+
+ @Test
+ public void testCompareDifferentNumberOfLabels() {
+ Labels labels1 = Labels.of("env", "prod", "status", "200");
+ Labels labels2 = Labels.of("env", "prod", "status", "200", "x_code", "none");
+ assertLessThan(labels1, labels2);
+ assertGreaterThan(labels2, labels1);
+ assertNotEquals(labels1, labels2);
+ assertNotEquals(labels2, labels1);
+ }
+
+ @Test
+ public void testComparePrometheusNames() {
+ Labels labels1 = Labels.of("my_a", "val");
+ Labels labels2 = Labels.of("my.b", "val");
+ assertLessThan(labels1, labels2); // this is true because it compares "my_a" to "my_b".
+ }
+
+ @Test
+ public void testEqualsHashcodeDots() {
+ Labels labels1 = Labels.of("my_a", "val");
+ Labels labels2 = Labels.of("my.a", "val");
+ Assert.assertEquals(labels1, labels2);
+ Assert.assertEquals(labels1.hashCode(), labels2.hashCode());
+ }
+
+ @Test
+ public void testCompareEquals() {
+ Labels labels1 = Labels.of("env", "prod", "status", "200");
+ Labels labels2 = Labels.of("env", "prod", "status", "200");
+ Assert.assertEquals(0, labels1.compareTo(labels2));
+ Assert.assertEquals(0, labels2.compareTo(labels1));
+ Assert.assertEquals(labels1, labels2);
+ Assert.assertEquals(labels2, labels1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testIllegalLabelName() {
+ Labels.of("my_service/status", "200");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testReservedLabelName() {
+ Labels.of("__name__", "requests_total");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testDuplicateLabelName() {
+ Labels.of("name1", "value1", "name2", "value2", "name1", "value3");
+ }
+
+ @Test
+ public void testMakePrometheusNames() {
+ String[] names = new String[] {};
+ String[] prometheusNames = Labels.makePrometheusNames(names);
+ Assert.assertSame(names, prometheusNames);
+
+ names = new String[] {"no_dots", "at_all"};
+ prometheusNames = Labels.makePrometheusNames(names);
+ Assert.assertSame(names, prometheusNames);
+
+ names = new String[] {"dots", "here.it.is"};
+ prometheusNames = Labels.makePrometheusNames(names);
+ Assert.assertNotSame(names, prometheusNames);
+ Assert.assertSame(names[0], prometheusNames[0]);
+ Assert.assertEquals("here.it.is", names[1]);
+ Assert.assertEquals("here_it_is", prometheusNames[1]);
+ }
+
+ @Test
+ public void testMerge() {
+ Labels labels1 = Labels.of("key.1", "value 1", "key.3", "value 3");
+ Labels labels2 = Labels.of("key_2", "value 2");
+ Labels merged = labels2.merge(labels1);
+ Assert.assertEquals("key.1", merged.getName(0));
+ Assert.assertEquals("key_2", merged.getName(1));
+ Assert.assertEquals("key.3", merged.getName(2));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMergeDuplicateName() {
+ Labels labels1 = Labels.of("key_one", "v1");
+ Labels labels2 = Labels.of("key.one", "v2");
+ labels2.merge(labels1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testDuplicateName() {
+ Labels.of("key_one", "v1", "key.one", "v2");
+ }
}
diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricMetadataTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricMetadataTest.java
index f9e9a18d6..9a3a980bc 100644
--- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricMetadataTest.java
+++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/MetricMetadataTest.java
@@ -1,72 +1,76 @@
package io.prometheus.metrics.model.snapshots;
+import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeMetricName;
+
import org.junit.Assert;
import org.junit.Test;
-import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName;
-import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeMetricName;
-
public class MetricMetadataTest {
- @Test(expected = IllegalArgumentException.class)
- public void testEmptyName() {
- new MetricMetadata("");
- }
+ @Test(expected = IllegalArgumentException.class)
+ public void testEmptyName() {
+ new MetricMetadata("");
+ }
- @Test(expected = IllegalArgumentException.class)
- public void testNullName() {
- new MetricMetadata(null);
- }
+ @Test(expected = IllegalArgumentException.class)
+ public void testNullName() {
+ new MetricMetadata(null);
+ }
- @Test(expected = IllegalArgumentException.class)
- public void testIllegalName() {
- new MetricMetadata("my_namespace/http_server_duration"); // let's see when we decide to allow slashes :)
- }
+ @Test(expected = IllegalArgumentException.class)
+ public void testIllegalName() {
+ new MetricMetadata(
+ "my_namespace/http_server_duration"); // let's see when we decide to allow slashes :)
+ }
- @Test
- public void testSanitizationIllegalCharacters() {
- MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("my_namespace/http.server.duration", Unit.SECONDS), "help string", Unit.SECONDS);
- Assert.assertEquals("my_namespace_http.server.duration_seconds", metadata.getName());
- Assert.assertEquals("my_namespace_http_server_duration_seconds", metadata.getPrometheusName());
- Assert.assertEquals("help string", metadata.getHelp());
- Assert.assertEquals("seconds", metadata.getUnit().toString());
- }
+ @Test
+ public void testSanitizationIllegalCharacters() {
+ MetricMetadata metadata =
+ new MetricMetadata(
+ sanitizeMetricName("my_namespace/http.server.duration", Unit.SECONDS),
+ "help string",
+ Unit.SECONDS);
+ Assert.assertEquals("my_namespace_http.server.duration_seconds", metadata.getName());
+ Assert.assertEquals("my_namespace_http_server_duration_seconds", metadata.getPrometheusName());
+ Assert.assertEquals("help string", metadata.getHelp());
+ Assert.assertEquals("seconds", metadata.getUnit().toString());
+ }
- @Test
- public void testSanitizationCounter() {
- MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("my_events_total"));
- Assert.assertEquals("my_events", metadata.getName());
- }
+ @Test
+ public void testSanitizationCounter() {
+ MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("my_events_total"));
+ Assert.assertEquals("my_events", metadata.getName());
+ }
- @Test
- public void testSanitizationInfo() {
- MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("target_info"));
- Assert.assertEquals("target", metadata.getName());
- }
+ @Test
+ public void testSanitizationInfo() {
+ MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("target_info"));
+ Assert.assertEquals("target", metadata.getName());
+ }
- @Test
- public void testSanitizationWeirdCornerCase() {
- MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("_total_created"));
- Assert.assertEquals("total", metadata.getName());
- }
+ @Test
+ public void testSanitizationWeirdCornerCase() {
+ MetricMetadata metadata = new MetricMetadata(sanitizeMetricName("_total_created"));
+ Assert.assertEquals("total", metadata.getName());
+ }
- @Test(expected = IllegalArgumentException.class)
- public void testSanitizeEmptyString() {
- sanitizeMetricName("");
- }
+ @Test(expected = IllegalArgumentException.class)
+ public void testSanitizeEmptyString() {
+ sanitizeMetricName("");
+ }
- @Test(expected = IllegalArgumentException.class)
- public void testUnitSuffixRequired() {
- new MetricMetadata("my_counter", "help", Unit.SECONDS);
- }
+ @Test(expected = IllegalArgumentException.class)
+ public void testUnitSuffixRequired() {
+ new MetricMetadata("my_counter", "help", Unit.SECONDS);
+ }
- @Test
- public void testUnitSuffixAdded() {
- new MetricMetadata(sanitizeMetricName("my_counter", Unit.SECONDS), "help", Unit.SECONDS);
- }
+ @Test
+ public void testUnitSuffixAdded() {
+ new MetricMetadata(sanitizeMetricName("my_counter", Unit.SECONDS), "help", Unit.SECONDS);
+ }
- @Test
- public void testUnitNotDuplicated() {
- Assert.assertEquals("my_counter_bytes", sanitizeMetricName("my_counter_bytes", Unit.BYTES));
- }
+ @Test
+ public void testUnitNotDuplicated() {
+ Assert.assertEquals("my_counter_bytes", sanitizeMetricName("my_counter_bytes", Unit.BYTES));
+ }
}
diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SnapshotTestUtil.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SnapshotTestUtil.java
index 54766debd..1a531b5fd 100644
--- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SnapshotTestUtil.java
+++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/SnapshotTestUtil.java
@@ -1,17 +1,17 @@
package io.prometheus.metrics.model.snapshots;
-import io.prometheus.metrics.model.snapshots.MetricSnapshot;
import org.junit.Assert;
public class SnapshotTestUtil {
- public static void assertMetadata(MetricSnapshot snapshot, String name, String help, String unit) {
- Assert.assertEquals(name, snapshot.getMetadata().getName());
- Assert.assertEquals(help, snapshot.getMetadata().getHelp());
- if (unit != null) {
- Assert.assertEquals(unit, snapshot.getMetadata().getUnit().toString());
- } else {
- Assert.assertNull(snapshot.getMetadata().getUnit());
- }
+ public static void assertMetadata(
+ MetricSnapshot snapshot, String name, String help, String unit) {
+ Assert.assertEquals(name, snapshot.getMetadata().getName());
+ Assert.assertEquals(help, snapshot.getMetadata().getHelp());
+ if (unit != null) {
+ Assert.assertEquals(unit, snapshot.getMetadata().getUnit().toString());
+ } else {
+ Assert.assertNull(snapshot.getMetadata().getUnit());
}
+ }
}
diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/StateSetSnapshotTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/StateSetSnapshotTest.java
index 2795ec165..ccc159b30 100644
--- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/StateSetSnapshotTest.java
+++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/StateSetSnapshotTest.java
@@ -1,145 +1,145 @@
package io.prometheus.metrics.model.snapshots;
-import org.junit.Assert;
-import org.junit.Test;
-
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
+import org.junit.Assert;
+import org.junit.Test;
public class StateSetSnapshotTest {
- @Test
- public void testCompleteGoodCase() {
- long scrapeTimestamp = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
- StateSetSnapshot snapshot = StateSetSnapshot.builder()
- .name("my_feature_flags")
- .help("Feature Flags")
- .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder()
- .labels(Labels.of("entity", "controller"))
- .scrapeTimestampMillis(scrapeTimestamp)
- .state("feature1", true)
- .state("feature2", false)
- .build()
- )
- .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder()
- .labels(Labels.of("entity", "api"))
- .state("feature1", false)
- .state("feature2", false)
- .build()
- )
- .build();
- SnapshotTestUtil.assertMetadata(snapshot, "my_feature_flags", "Feature Flags", null);
- Assert.assertEquals(2, snapshot.getDataPoints().size());
- StateSetSnapshot.StateSetDataPointSnapshot data = snapshot.getDataPoints().get(1); // data is sorted by labels, so the second one should be entity="controller"
- Assert.assertEquals(Labels.of("entity", "controller"), data.getLabels());
- Assert.assertEquals(2, data.size());
- Assert.assertEquals("feature1", data.getName(0));
- Assert.assertTrue(data.isTrue(0));
- Assert.assertEquals("feature2", data.getName(1));
- Assert.assertFalse(data.isTrue(1));
- Assert.assertTrue(data.hasScrapeTimestamp());
- Assert.assertEquals(scrapeTimestamp, data.getScrapeTimestampMillis());
- Assert.assertFalse(data.hasCreatedTimestamp());
- }
-
- @Test
- public void testStateSetDataSorted() {
- StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.builder()
- .state("b", true)
- .state("d", false)
- .state("c", true)
- .state("a", false)
- .build();
- Assert.assertEquals(4, data.size());
- Assert.assertEquals("a", data.getName(0));
- Assert.assertFalse(data.isTrue(0));
- Assert.assertEquals("b", data.getName(1));
- Assert.assertTrue(data.isTrue(1));
- Assert.assertEquals("c", data.getName(2));
- Assert.assertTrue(data.isTrue(2));
- Assert.assertEquals("d", data.getName(3));
- Assert.assertFalse(data.isTrue(3));
- }
+ @Test
+ public void testCompleteGoodCase() {
+ long scrapeTimestamp = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
+ StateSetSnapshot snapshot =
+ StateSetSnapshot.builder()
+ .name("my_feature_flags")
+ .help("Feature Flags")
+ .dataPoint(
+ StateSetSnapshot.StateSetDataPointSnapshot.builder()
+ .labels(Labels.of("entity", "controller"))
+ .scrapeTimestampMillis(scrapeTimestamp)
+ .state("feature1", true)
+ .state("feature2", false)
+ .build())
+ .dataPoint(
+ StateSetSnapshot.StateSetDataPointSnapshot.builder()
+ .labels(Labels.of("entity", "api"))
+ .state("feature1", false)
+ .state("feature2", false)
+ .build())
+ .build();
+ SnapshotTestUtil.assertMetadata(snapshot, "my_feature_flags", "Feature Flags", null);
+ Assert.assertEquals(2, snapshot.getDataPoints().size());
+ StateSetSnapshot.StateSetDataPointSnapshot data =
+ snapshot
+ .getDataPoints()
+ .get(1); // data is sorted by labels, so the second one should be entity="controller"
+ Assert.assertEquals(Labels.of("entity", "controller"), data.getLabels());
+ Assert.assertEquals(2, data.size());
+ Assert.assertEquals("feature1", data.getName(0));
+ Assert.assertTrue(data.isTrue(0));
+ Assert.assertEquals("feature2", data.getName(1));
+ Assert.assertFalse(data.isTrue(1));
+ Assert.assertTrue(data.hasScrapeTimestamp());
+ Assert.assertEquals(scrapeTimestamp, data.getScrapeTimestampMillis());
+ Assert.assertFalse(data.hasCreatedTimestamp());
+ }
- @Test(expected = IllegalArgumentException.class)
- public void testMustHaveState() {
- // Must have at least one state.
- StateSetSnapshot.StateSetDataPointSnapshot.builder().build();
- }
+ @Test
+ public void testStateSetDataSorted() {
+ StateSetSnapshot.StateSetDataPointSnapshot data =
+ StateSetSnapshot.StateSetDataPointSnapshot.builder()
+ .state("b", true)
+ .state("d", false)
+ .state("c", true)
+ .state("a", false)
+ .build();
+ Assert.assertEquals(4, data.size());
+ Assert.assertEquals("a", data.getName(0));
+ Assert.assertFalse(data.isTrue(0));
+ Assert.assertEquals("b", data.getName(1));
+ Assert.assertTrue(data.isTrue(1));
+ Assert.assertEquals("c", data.getName(2));
+ Assert.assertTrue(data.isTrue(2));
+ Assert.assertEquals("d", data.getName(3));
+ Assert.assertFalse(data.isTrue(3));
+ }
- @Test
- public void testMinimal() {
- StateSetSnapshot snapshot = StateSetSnapshot.builder()
- .name("my_flag")
- .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder()
- .state("flag", true)
- .build()
- )
- .build();
- Assert.assertEquals(1, snapshot.dataPoints.size());
- }
+ @Test(expected = IllegalArgumentException.class)
+ public void testMustHaveState() {
+ // Must have at least one state.
+ StateSetSnapshot.StateSetDataPointSnapshot.builder().build();
+ }
- @Test
- public void testEmpty() {
- StateSetSnapshot snapshot = StateSetSnapshot.builder()
- .name("my_flag")
- .build();
- Assert.assertEquals(0, snapshot.dataPoints.size());
- }
+ @Test
+ public void testMinimal() {
+ StateSetSnapshot snapshot =
+ StateSetSnapshot.builder()
+ .name("my_flag")
+ .dataPoint(
+ StateSetSnapshot.StateSetDataPointSnapshot.builder().state("flag", true).build())
+ .build();
+ Assert.assertEquals(1, snapshot.dataPoints.size());
+ }
- @Test(expected = UnsupportedOperationException.class)
- public void testDataImmutable() {
- StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.builder()
- .state("a", true)
- .state("b", true)
- .state("c", true)
- .build();
- Iterator iterator = data.iterator();
- iterator.next();
- iterator.remove();
- }
+ @Test
+ public void testEmpty() {
+ StateSetSnapshot snapshot = StateSetSnapshot.builder().name("my_flag").build();
+ Assert.assertEquals(0, snapshot.dataPoints.size());
+ }
- @Test(expected = IllegalArgumentException.class)
- public void testDuplicateState() {
- StateSetSnapshot.StateSetDataPointSnapshot data = StateSetSnapshot.StateSetDataPointSnapshot.builder()
- .state("a", true)
- .state("b", true)
- .state("a", true)
- .build();
- }
+ @Test(expected = UnsupportedOperationException.class)
+ public void testDataImmutable() {
+ StateSetSnapshot.StateSetDataPointSnapshot data =
+ StateSetSnapshot.StateSetDataPointSnapshot.builder()
+ .state("a", true)
+ .state("b", true)
+ .state("c", true)
+ .build();
+ Iterator iterator = data.iterator();
+ iterator.next();
+ iterator.remove();
+ }
- @Test(expected = UnsupportedOperationException.class)
- public void testStateSetImmutable() {
- StateSetSnapshot snapshot = StateSetSnapshot.builder()
- .name("flags")
- .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder()
- .labels(Labels.of("entity", "controller"))
- .state("feature", true)
- .build()
- )
- .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder()
- .labels(Labels.of("entity", "api"))
- .state("feature", true)
- .build()
- )
- .build();
- Iterator iterator = snapshot.getDataPoints().iterator();
- iterator.next();
- iterator.remove();
- }
+ @Test(expected = IllegalArgumentException.class)
+ public void testDuplicateState() {
+ StateSetSnapshot.StateSetDataPointSnapshot.builder()
+ .state("a", true)
+ .state("b", true)
+ .state("a", true)
+ .build();
+ }
- @Test(expected = IllegalArgumentException.class)
- public void testLabelsUnique() {
+ @Test(expected = UnsupportedOperationException.class)
+ public void testStateSetImmutable() {
+ StateSetSnapshot snapshot =
StateSetSnapshot.builder()
- .name("flags")
- .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder()
- .state("feature", true)
- .build()
- )
- .dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder()
- .state("feature", true)
- .build()
- )
- .build();
- }
+ .name("flags")
+ .dataPoint(
+ StateSetSnapshot.StateSetDataPointSnapshot.builder()
+ .labels(Labels.of("entity", "controller"))
+ .state("feature", true)
+ .build())
+ .dataPoint(
+ StateSetSnapshot.StateSetDataPointSnapshot.builder()
+ .labels(Labels.of("entity", "api"))
+ .state("feature", true)
+ .build())
+ .build();
+ Iterator iterator =
+ snapshot.getDataPoints().iterator();
+ iterator.next();
+ iterator.remove();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testLabelsUnique() {
+ StateSetSnapshot.builder()
+ .name("flags")
+ .dataPoint(
+ StateSetSnapshot.StateSetDataPointSnapshot.builder().state("feature", true).build())
+ .dataPoint(
+ StateSetSnapshot.StateSetDataPointSnapshot.builder().state("feature", true).build())
+ .build();
+ }
}
diff --git a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnitTest.java b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnitTest.java
index f88458cc3..1f70f6520 100644
--- a/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnitTest.java
+++ b/prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/UnitTest.java
@@ -3,49 +3,42 @@
import org.junit.Assert;
import org.junit.Test;
-import static org.junit.Assert.fail;
-
public class UnitTest {
- @Test
- public void testEmpty() {
- try {
- new Unit(" ");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected
- }
- }
-
- @Test
- public void testEquals1() {
- Unit unit1 = Unit.BYTES;
- Unit unit2 = new Unit("bytes");
-
- Assert.assertEquals(unit2, unit1);
- }
-
- @Test
- public void testEquals2() {
- Unit unit1 = new Unit("bytes ");
- Unit unit2 = new Unit("bytes");
-
- Assert.assertEquals(unit2, unit1);
- }
-
- @Test
- public void testEquals3() {
- Unit unit1 = new Unit(" bytes");
- Unit unit2 = new Unit("bytes");
-
- Assert.assertEquals(unit2, unit1);
- }
-
- @Test
- public void testEquals4() {
- Unit unit1 = new Unit(" bytes ");
- Unit unit2 = new Unit("bytes");
-
- Assert.assertEquals(unit2, unit1);
- }
+ @Test(expected = IllegalArgumentException.class)
+ public void testEmpty() {
+ new Unit(" ");
+ }
+
+ @Test
+ public void testEquals1() {
+ Unit unit1 = Unit.BYTES;
+ Unit unit2 = new Unit("bytes");
+
+ Assert.assertEquals(unit2, unit1);
+ }
+
+ @Test
+ public void testEquals2() {
+ Unit unit1 = new Unit("bytes ");
+ Unit unit2 = new Unit("bytes");
+
+ Assert.assertEquals(unit2, unit1);
+ }
+
+ @Test
+ public void testEquals3() {
+ Unit unit1 = new Unit(" bytes");
+ Unit unit2 = new Unit("bytes");
+
+ Assert.assertEquals(unit2, unit1);
+ }
+
+ @Test
+ public void testEquals4() {
+ Unit unit1 = new Unit(" bytes ");
+ Unit unit2 = new Unit("bytes");
+
+ Assert.assertEquals(unit2, unit1);
+ }
}